ucblogo-5.5/0040755000161300001330000000000010276423431010735 5ustar bhdoeucblogo-5.5/parse.c0100644000161300001330000004127010276045565012224 0ustar bhdoe/* * parse.c logo parser module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef WIN32 #include #endif #include "logo.h" #include "globals.h" #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif #include #ifdef ibm #ifndef _MSC_VER #include extern int getch(void); #endif /* _MSC_VER */ #endif #ifdef __RZTC__ #include #endif # ifdef HAVE_WX #define getc getFromWX_2 #define getch getFromWX #endif FILE *readstream; FILE *writestream; FILE *loadstream; FILE *dribblestream = NULL; int input_blocking = 0; NODE *deepend_proc_name = NIL; int rd_getc(FILE *strm) { int c; #ifdef WIN32 MSG msg; #endif #ifndef WIN32 /* skip this section ... */ #ifdef __RZTC__ if (strm == stdin) zflush(); c = ztc_getc(strm); #else c = getc(strm); #endif if (strm == stdin && c != EOF) update_coords(c); #ifdef ibm if (c == 17 && interactive && strm==stdin) { /* control-q */ to_pending = 0; err_logo(STOP_ERROR,NIL); if (input_blocking) { #ifdef SIG_TAKES_ARG logo_stop(0); #else logo_stop(); #endif } } if (c == 23 && interactive && strm==stdin) { /* control-w */ #ifndef __RZTC__ getc(strm); /* eat up the return */ #endif #ifdef SIG_TAKES_ARG logo_pause(0); #else logo_pause(); #endif return(rd_getc(strm)); } #endif #else /* WIN32 */ if (strm == stdin) { if (winPasteText && !line_avail) winDoPaste(); if (!line_avail) { win32_text_cursor(); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); if (line_avail) break; } } c = read_line[read_index++]; if (c == 17 && interactive && strm==stdin) { /* control-q */ to_pending = 0; err_logo(STOP_ERROR,NIL); line_avail = 0; free(read_line); if (input_blocking) logo_stop(0); return('\n'); } if (c == 23 && interactive && strm==stdin) { /* control-w */ line_avail = 0; free(read_line); logo_pause(0); return(rd_getc(strm)); } if (c == '\n') { line_avail = 0; free(read_line); } } else /* reading from a file */ c = getc(strm); #endif /* WIN32 */ #ifdef ecma return((c == EOF) ? c : ecma_clear(c)); #else return(c); #endif } void rd_print_prompt(char *str) { #ifdef ibm #if defined(__RZTC__) || defined(WIN32) if (in_graphics_mode && !in_splitscreen) #else #ifndef _MSC_VER if (in_graphics_mode && ibm_screen_top == 0) #endif /* _MSC_VER */ #endif lsplitscreen(NIL); #endif #ifdef mac extern int in_fscreen(void); if (in_fscreen()) lsplitscreen(NIL); #endif ndprintf(stdout,"%t",str); #if defined(__RZTC__) && !defined(WIN32) /* sowings */ zflush(); #endif } #if defined(__RZTC__) && !defined(WIN32) /* sowings */ void zrd_print_prompt(char *str) { newline_bugfix(); rd_print_prompt(str); } #else #define zrd_print_prompt rd_print_prompt #endif #define into_line(chr) {if (phys_line >= p_end) { \ p_len += MAX_PHYS_LINE; \ p_pos = phys_line - p_line; \ p_line = realloc(p_line, p_len); \ p_end = &p_line[p_len-1]; \ phys_line = &p_line[p_pos]; \ } \ *phys_line++ = (chr);} char *p_line = 0, *p_end; int p_len = MAX_PHYS_LINE; NODE *reader(FILE *strm, char *prompt) { int c = 0, dribbling, vbar = 0, paren = 0; int bracket = 0, brace = 0, p_pos, contin=1, insemi=0, raw=0; static char ender[] = "\nEND\n"; char *phys_line, *lookfor = ender; NODETYPES this_type = STRING; NODE *ret; if (!strcmp(prompt, "RW")) { /* called by readword */ prompt = ""; contin = 0; } if (!strcmp(prompt, "RAW")) { /* called by readrawline */ prompt = ""; contin = 0; raw = 1; } charmode_off(); #ifdef WIN32 dribbling = 0; #else dribbling = (dribblestream != NULL && strm == stdin); #endif if (p_line == 0) { p_line = malloc(MAX_PHYS_LINE); if (p_line == NULL) { err_logo(OUT_OF_MEM, NIL); return UNBOUND; } p_end = &p_line[MAX_PHYS_LINE-1]; } phys_line = p_line; if (strm == stdin && *prompt) { if (interactive) { rd_print_prompt(prompt); #ifdef WIN32 win32_update_text(); #endif } } if (strm == stdin) { input_blocking++; erract_errtype = FATAL; } #ifndef TIOCSTI if (!setjmp(iblk_buf)) { #endif c = rd_getc(strm); if ((c=='\b' || c=='\127') && strm==stdin && interactive) { silent_load(LogoLogo, logolib); c = rd_getc(strm); } #ifdef mac if (c == '\r') c = '\n'; /* seen in raw mode by keyp, never read */ #endif while (c != EOF && (vbar || paren || bracket || brace || c != '\n') && NOT_THROWING) { if (dribbling) rd_putc(c, dribblestream); if (!raw && c == '\\' && (c = rd_getc(strm)) != EOF) { if (dribbling) rd_putc(c, dribblestream); c = setparity(c); this_type = BACKSLASH_STRING; if (c == setparity('\n') && strm == stdin) { if (interactive) zrd_print_prompt("\\ "); } } if (c != EOF) into_line(c); if (raw) { c = rd_getc(strm); continue; } if (*prompt && (c&0137) == *lookfor) { lookfor++; if (*lookfor == 0) { if (deepend_proc_name != NIL) err_logo(DEEPEND, deepend_proc_name); else err_logo(DEEPEND_NONAME, NIL); break; } } else lookfor = ender; if (c == '|') { vbar = !vbar; this_type = VBAR_STRING; } else if (contin && !vbar && !insemi) { if (c == '(') paren++; else if (paren && c == ')') paren--; else if (c == '[') bracket++; else if (bracket && c == ']') bracket--; else if (c == '{') brace++; else if (brace && c == '}') brace--; else if (c == ';') insemi++; } if (this_type == STRING && strchr(special_chars, c)) this_type = VBAR_STRING; if (/* (vbar || paren ...) && */ c == '\n') { insemi = 0; if (strm == stdin) { if (interactive) zrd_print_prompt(vbar ? "| " : "~ "); } } while (!vbar && c == '~' && (c = rd_getc(strm)) != EOF) { while (c == ' ' || c == '\t') c = rd_getc(strm); if (dribbling) rd_putc(c, dribblestream); into_line(c); if (c == '\n') { insemi = 0; if (interactive && strm == stdin) zrd_print_prompt("~ "); } } if (c != EOF) c = rd_getc(strm); } #ifndef TIOCSTI } #endif *phys_line = '\0'; input_blocking = 0; #if defined(__RZTC__) && !defined(WIN32) /* sowings */ fix_cursor(); if (interactive && strm == stdin) newline_bugfix(); #endif if (dribbling) rd_putc('\n', dribblestream); if (c == EOF && strm == stdin) { if (interactive) clearerr(stdin); rd_print_prompt("\n"); } if (phys_line == p_line) return(Null_Word); /* so emptyp works */ ret = make_strnode(p_line, (struct string_block *)NULL, (int)strlen(p_line), this_type, strnzcpy); return(ret); } NODE *list_to_array(NODE *list) { NODE *np = list, *result; FIXNUM len = 0, i; for (; np; np = cdr(np)) len++; result = make_array(len); setarrorg(result,1); for (i = 0, np = list; np; np = cdr(np)) (getarrptr(result))[i++] = car(np); return(result); } #define parens(ch) (ch == '(' || ch == ')' || ch == ';') #define infixs(ch) (ch == '*' || ch == '/' || ch == '+' || ch == '-' || ch == '=' || ch == '<' || ch == '>') #define white_space(ch) (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0') NODE *parser_iterate(char **inln, char *inlimit, struct string_block *inhead, BOOLEAN semi, int endchar) { char ch, *wptr = NULL; static char terminate = '\0'; /* KLUDGE */ NODE *outline = NIL, *lastnode = NIL, *tnode = NIL; int windex = 0, vbar = 0; NODETYPES this_type = STRING; BOOLEAN broken = FALSE; do { /* get the current character and increase pointer */ ch = **inln; if (!vbar && windex == 0) wptr = *inln; if (++(*inln) >= inlimit) *inln = &terminate; /* skip through comments and line continuations */ while (!vbar && ((semi && ch == ';') || #ifdef WIN32 (ch == '~' && (**inln == 012 || **inln == 015)))) { while (ch == '~' && (**inln == 012 || **inln == 015)) { #else (ch == '~' && **inln == '\n'))) { while (ch == '~' && **inln == '\n') { #endif if (++(*inln) >= inlimit) *inln = &terminate; ch = **inln; if (windex == 0) wptr = *inln; else { if (**inln == ']' || **inln == '[' || **inln == '{' || **inln == '}') { ch = ' '; break; } else { broken = TRUE; } } if (++(*inln) >= inlimit) *inln = &terminate; } if (semi && ch == ';') { #ifdef WIN32 if (**inln != 012 && **inln != 015) #else if (**inln != '\n') #endif do { ch = **inln; if (windex == 0) wptr = *inln; else broken = TRUE; if (++(*inln) >= inlimit) *inln = &terminate; } #ifdef WIN32 while (ch != '\0' && ch != '~' && **inln != 012 && **inln != 015); #else /* !Win32 */ while (ch != '\0' && ch != '~' && **inln != '\n'); #endif if (ch != '\0' && ch != '~') ch = '\n'; } } /* flag that this word will be of BACKSLASH_STRING type */ if (getparity(ch)) this_type = BACKSLASH_STRING; if (ch == '|') { vbar = !vbar; this_type = VBAR_STRING; broken = TRUE; /* so we'll copy the chars */ } else if (vbar || (!white_space(ch) && ch != ']' && ch != '{' && ch != '}' && ch != '[')) windex++; if (vbar) continue; else if (ch == endchar) break; else if (ch == ']') err_logo(UNEXPECTED_BRACKET, NIL); else if (ch == '}') err_logo(UNEXPECTED_BRACE, NIL); /* if this is a '[', parse a new list */ else if (ch == '[') { tnode = cons(parser_iterate(inln,inlimit,inhead,semi,']'), NIL); if (**inln == '\0') ch = '\0'; } else if (ch == '{') { tnode = cons(list_to_array (parser_iterate(inln,inlimit,inhead,semi,'}')), NIL); if (**inln == '@') { int i = 0, sign = 1; (*inln)++; if (**inln == '-') { sign = -1; (*inln)++; } while ((ch = **inln) >= '0' && ch <= '9') { i = (i*10) + ch - '0'; (*inln)++; } setarrorg(car(tnode),sign*i); } if (**inln == '\0') ch = '\0'; } /* if this character or the next one will terminate string, make the word */ else if (white_space(ch) || **inln == ']' || **inln == '[' || **inln == '{' || **inln == '}') { if (windex > 0 || this_type == VBAR_STRING) { if (broken == FALSE) tnode = cons(make_strnode(wptr, inhead, windex, this_type, strnzcpy), NIL); else { tnode = cons(make_strnode(wptr, (struct string_block *)NULL, windex, this_type, (semi ? mend_strnzcpy : mend_nosemi)), NIL); broken = FALSE; } this_type = STRING; windex = 0; } } /* put the word onto the end of the return list */ if (tnode != NIL) { if (outline == NIL) outline = tnode; else setcdr(lastnode, tnode); lastnode = tnode; tnode = NIL; } } while (ch); return(outline); } NODE *parser(NODE *nd, BOOLEAN semi) { NODE *rtn; int slen; char *lnsav; rtn = cnv_node_to_strnode(nd); slen = getstrlen(rtn); lnsav = getstrptr(rtn); rtn = parser_iterate(&lnsav,lnsav + slen,getstrhead(rtn),semi,-1); return(rtn); } NODE *lparse(NODE *args) { NODE *arg, *val = UNBOUND; arg = string_arg(args); if (NOT_THROWING) { val = parser(arg, FALSE); } return(val); } NODE *runparse_node(NODE *nd, NODE **ndsptr) { NODE *outline = NIL, *tnode = NIL, *lastnode = NIL, *snd; char *wptr, *tptr; struct string_block *whead; int wlen, wcnt, tcnt, isnumb, gotdot; NODETYPES wtyp; BOOLEAN monadic_minus = FALSE; if (nd == Minus_Tight) return cons(nd, NIL); snd = cnv_node_to_strnode(nd); wptr = getstrptr(snd); wlen = getstrlen(snd); wtyp = nodetype(snd); wcnt = 0; whead = getstrhead(snd); while (wcnt < wlen) { if (*wptr == ';') { *ndsptr = NIL; break; } if (*wptr == '"') { tcnt = 0; tptr = ++wptr; wcnt++; while (wcnt < wlen && !parens(*wptr)) { if (wtyp == BACKSLASH_STRING && getparity(*wptr)) wtyp = PUNBOUND; /* flag for "\( case */ wptr++, wcnt++, tcnt++; } if (wtyp == PUNBOUND) { wtyp = BACKSLASH_STRING; tnode = cons(make_quote(intern(make_strnode(tptr, NULL, tcnt, wtyp, noparity_strnzcpy))), NIL); } else tnode = cons(make_quote(intern(make_strnode(tptr, whead, tcnt, wtyp, strnzcpy))), NIL); } else if (*wptr == ':') { tcnt = 0; tptr = ++wptr; wcnt++; while (wcnt < wlen && !parens(*wptr) && !infixs(*wptr)) wptr++, wcnt++, tcnt++; tnode = cons(make_colon(intern(make_strnode(tptr, whead, tcnt, wtyp, strnzcpy))), NIL); } else if (wcnt == 0 && *wptr == '-' && monadic_minus == FALSE && wcnt+1 < wlen && !white_space(*(wptr+1))) { /* minus sign with space before and no space after is unary */ tnode = cons(make_intnode((FIXNUM)0), NIL); monadic_minus = TRUE; } else if (parens(*wptr) || infixs(*wptr)) { if (monadic_minus) tnode = cons(Minus_Tight, NIL); else if (wcnt+1 < wlen && ((*wptr == '<' && (*(wptr+1) == '=' || *(wptr+1) == '>')) || (*wptr == '>' && *(wptr+1) == '='))) { tnode = cons(intern(make_strnode(wptr, whead, 2, STRING, strnzcpy)), NIL); wptr++, wcnt++; } else tnode = cons(intern(make_strnode(wptr, whead, 1, STRING, strnzcpy)), NIL); monadic_minus = FALSE; wptr++, wcnt++; } else { tcnt = 0; tptr = wptr; /* isnumb 4 means nothing yet; * 0 means digits so far, 1 means just saw * 'e' so minus can be next, 2 means no longer * eligible even if an 'e' comes along */ isnumb = 4; gotdot = 0; if (*wptr == '?') { isnumb = 3; /* turn ?5 to (? 5) */ wptr++, wcnt++, tcnt++; } while (wcnt < wlen && !parens(*wptr) && (!infixs(*wptr) || (isnumb == 1 && (*wptr == '-' || *wptr == '+')))) { if (isnumb == 4 && isdigit(*wptr)) isnumb = 0; if (isnumb == 0 && tcnt > 0 && (*wptr == 'e' || *wptr == 'E')) isnumb = 1; else if (!(isdigit(*wptr) || (!gotdot && *wptr == '.')) || isnumb == 1) isnumb = 2; if (*wptr == '.') gotdot++; wptr++, wcnt++, tcnt++; } if (isnumb == 3 && tcnt > 1) { /* ?5 syntax */ NODE *qmtnode; qmtnode = cons_list(0, Left_Paren, Query, cnv_node_to_numnode (make_strnode(tptr+1, whead, tcnt-1, wtyp, strnzcpy)), END_OF_LIST); if (outline == NIL) { outline = qmtnode; } else { setcdr(lastnode, qmtnode); } lastnode = cddr(qmtnode); tnode = cons(Right_Paren, NIL); } else if (isnumb < 2 && tcnt > 0) { tnode = cons(cnv_node_to_numnode(make_strnode(tptr, whead, tcnt, wtyp, strnzcpy)), NIL); } else tnode = cons(intern(make_strnode(tptr, whead, tcnt, wtyp, strnzcpy)), NIL); } if (outline == NIL) outline = tnode; else setcdr(lastnode, tnode); lastnode = tnode; } return(outline); } NODE *runparse(NODE *ndlist) { NODE *curnd = NIL, *outline = NIL, *tnode = NIL, *lastnode = NIL; char *str; if (nodetype(ndlist) == RUN_PARSE) return parsed__runparse(ndlist); if (!is_list(ndlist)) { err_logo(BAD_DATA_UNREC, ndlist); return(NIL); } if (ndlist != NIL && is_word(curnd=car(ndlist)) && getstrlen(curnd) >= 2 && (str=getstrptr(curnd)) && *str++ == '#' && *str == '!') return NIL; /* shell-script #! treated as comment line */ while (ndlist != NIL) { curnd = car(ndlist); ndlist = cdr(ndlist); if (!is_word(curnd)) tnode = cons(curnd, NIL); else { if (!numberp(curnd)) tnode = runparse_node(curnd, &ndlist); else tnode = cons(cnv_node_to_numnode(curnd), NIL); } if (tnode != NIL) { if (outline == NIL) outline = tnode; else setcdr(lastnode, tnode); lastnode = tnode; while (cdr(lastnode) != NIL) { lastnode = cdr(lastnode); if (check_throwing) break; } } if (check_throwing) break; } return(outline); } NODE *lrunparse(NODE *args) { NODE *arg; arg = car(args); while (nodetype(arg) == ARRAY && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } if (NOT_THROWING && !aggregate(arg)) arg = parser(arg, TRUE); if (NOT_THROWING) return runparse(arg); return UNBOUND; } ucblogo-5.5/graphics.c0100644000161300001330000013152410275715617012715 0ustar bhdoe/* * graphics.c logo graphics module mak * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef WIN32 #include #endif /* WIN32 */ #include "logo.h" /* #include "globals.h" has been moved further down */ #include #ifdef HAVE_WX #include "wxGraphics.h" #elif defined(mac) #include "macterm.h" #elif defined(WIN32) #include "win32trm.h" #elif defined(__RZTC__) #include #include "ztcterm.h" #elif defined(x_window) #include "xgraphics.h" #elif defined(ibm) #include "ibmterm.h" #else #include "nographics.h" #endif /* end this whole big huge tree */ #include "globals.h" #if defined(__RZTC__) && !defined(WIN32) /* sowings */ #define total_turtle_bottom_max (-(MaxY/2)) #else #define total_turtle_bottom_max turtle_bottom_max #endif /* types of graphics moves that can be recorded */ #define LINEXY 1 #define MOVEXY 2 #define LABEL 3 #define SETPENVIS 4 #define SETPENMODE 5 #define SETPENCOLOR 6 #define SETPENSIZE 7 #define SETPENPATTERN 8 #define FILLERUP 9 #define ARC 10 #define SETPENRGB 11 /* NOTE: See the files (macterm.c and macterm.h) or (ibmterm.c and ibmterm.h) for examples of the functions and macros that this file assumes exist. */ #define One (sizeof(int)) #define Two (2*One) #define Three (3*One) #define Four (4*One) #define Big (sizeof(FLONUM)) #define PENMODE_PAINT 0 #define PENMODE_ERASE 1 #define PENMODE_REVERSE 2 int internal_penmode = PENMODE_PAINT; mode_type current_mode = wrapmode; FLONUM turtle_x = 0.0, turtle_y = 0.0, turtle_heading = 0.0; FLONUM x_scale = 1.0, y_scale = 1.0; BOOLEAN turtle_shown = TRUE; FLONUM wanna_x = 0.0, wanna_y = 0.0; BOOLEAN out_of_bounds = FALSE; void setpos_bynumber(FLONUM, FLONUM); int max_palette_slot = 0; char record[GR_SIZE]; FIXNUM record_index = 0; int last_recorded = -1; pen_info orig_pen; BOOLEAN refresh_p = TRUE; /************************************************************/ double pfmod(double x, double y) { double temp = fmod(x,y); if (temp < 0) return temp+y; return temp; } FLONUM cut_error(FLONUM n) { n *= 1000000; n = (n > 0 ? floor(n) : ceil(n)); n /= 1000000; if (n == -0.0) n = 0.0; return(n); } FIXNUM g_round(FLONUM n) { n += (n < 0.0 ? -0.5 : 0.5); if ((n < 0.0 ? -n : n) > MAXLOGOINT) err_logo(TURTLE_OUT_OF_BOUNDS, NIL); if (n < 0.0) return((FIXNUM)ceil(n)); return((FIXNUM)floor(n)); } /************************************************************/ void draw_turtle_helper(void); void check_x_high(void); void check_x_low(void); void forward(FLONUM); void draw_turtle(void) { unsigned int r=0, g=0, b=0; int old_color=pen_color; int save_vis; if (!turtle_shown) return; turtle_shown = 0; get_palette(pen_color, &r, &g, &b); if (r==0 && g==0 && b==0) { set_pen_color(7); } save_vis=pen_vis; pen_vis = -1; forward(-1); draw_turtle_helper(); /* all that follows is for "turtle wrap" effect */ if ((turtle_y > turtle_top_max - turtle_height) && (current_mode == wrapmode)) { turtle_y -= (screen_height + 1); draw_turtle_helper(); check_x_high(); check_x_low(); turtle_y += (screen_height + 1); } if ((turtle_y < turtle_bottom_max + turtle_height) && (current_mode == wrapmode)) { turtle_y += (screen_height + 1); draw_turtle_helper(); check_x_high(); check_x_low(); turtle_y -= (screen_height + 1); } check_x_high(); check_x_low(); turtle_shown = 0; set_pen_color(old_color); forward(1); set_pen_vis(save_vis); turtle_shown = 1; } void check_x_high(void) { if ((turtle_x > turtle_right_max - turtle_height) && (current_mode == wrapmode)) { turtle_x -= (screen_width + 1); draw_turtle_helper(); turtle_x += (screen_width + 1); } } void check_x_low(void) { if ((turtle_x < turtle_left_max + turtle_height) && (current_mode == wrapmode)) { turtle_x += (screen_width + 1); draw_turtle_helper(); turtle_x -= (screen_width + 1); } } void draw_turtle_helper(void) { pen_info saved_pen; FLONUM real_heading; int left_x, left_y, right_x, right_y, top_x, top_y; #if 1 /* Evan Marshall Manning */ double cos_real_heading, sin_real_heading; FLONUM delta_x, delta_y; #endif prepare_to_draw; prepare_to_draw_turtle; save_pen(&saved_pen); plain_xor_pen(); pen_vis = 0; set_pen_width(1); set_pen_height(1); real_heading = -turtle_heading + 90.0; #if 0 left_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)((real_heading + 90.0)*degrad))*turtle_half_bottom)); left_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)((real_heading + 90.0)*degrad))*turtle_half_bottom)); right_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)((real_heading - 90.0)*degrad))*turtle_half_bottom)); right_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)((real_heading - 90.0)*degrad))*turtle_half_bottom)); top_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)(real_heading*degrad))*turtle_side)); top_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)(real_heading*degrad))*turtle_side)); #else cos_real_heading = cos((FLONUM)(real_heading*degrad)); sin_real_heading = sin((FLONUM)(real_heading*degrad)); delta_x = x_scale*(FLONUM)(sin_real_heading*turtle_half_bottom); delta_y = y_scale*(FLONUM)(cos_real_heading*turtle_half_bottom); left_x = g_round(turtle_x - delta_x); left_y = g_round(turtle_y + delta_y); right_x = g_round(turtle_x + delta_x); right_y = g_round(turtle_y - delta_y); top_x = g_round(turtle_x + x_scale*(FLONUM)(cos_real_heading*turtle_side)); top_y = g_round(turtle_y + y_scale*(FLONUM)(sin_real_heading*turtle_side)); #endif #if 0 /* move to left, draw to top; move to right, draw to top; move to left draw to right */ move_to(screen_x_center + left_x, screen_y_center - left_y); line_to(screen_x_center + top_x, screen_y_center - top_y); move_to(screen_x_center + right_x, screen_y_center - right_y); line_to(screen_x_center + top_x, screen_y_center - top_y); move_to(screen_x_center + left_x, screen_y_center - left_y); line_to(screen_x_center + right_x, screen_y_center - right_y); #else /* move to right, draw to left, draw to top, draw to right */ move_to(screen_x_center + right_x, screen_y_center - right_y); line_to(screen_x_center + left_x, screen_y_center - left_y); line_to(screen_x_center + top_x, screen_y_center - top_y); line_to(screen_x_center + right_x, screen_y_center - right_y); #endif restore_pen(&saved_pen); done_drawing_turtle; done_drawing; } /************************************************************/ void forward_helper(FLONUM); BOOLEAN safe_to_save(void); void save_line(void), save_move(void), save_vis(void), save_mode(void); void save_color(void), save_size(void), save_pattern(void); void save_string(char *, int); void save_arc(FLONUM, FLONUM, FLONUM, FLONUM, FLONUM, FLONUM, FLONUM, FLONUM); void right(FLONUM a) { prepare_to_draw; draw_turtle(); turtle_heading += a; turtle_heading = pfmod(turtle_heading,360.0); draw_turtle(); done_drawing; } NODE *numeric_arg(NODE *args) { NODE *arg = car(args), *val; val = cnv_node_to_numnode(arg); while (val == UNBOUND && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); val = cnv_node_to_numnode(arg); } setcar(args,val); return(val); } NODE *lright(NODE *arg) { NODE *val; FLONUM a; val = numeric_arg(arg); if (NOT_THROWING) { if (nodetype(val) == INT) a = (FLONUM)getint(val); else a = getfloat(val); right(a); } return(UNBOUND); } NODE *lleft(NODE *arg) { NODE *val; FLONUM a; val = numeric_arg(arg); if (NOT_THROWING) { if (nodetype(val) == INT) a = (FLONUM)getint(val); else a = getfloat(val); right(-a); } return(UNBOUND); } FLONUM wrap_right(FLONUM, FLONUM, FLONUM, FLONUM, FLONUM); FLONUM wrap_left(FLONUM, FLONUM, FLONUM, FLONUM, FLONUM); FLONUM wrap_up(FLONUM, FLONUM, FLONUM, FLONUM, FLONUM); FLONUM wrap_down(FLONUM, FLONUM, FLONUM, FLONUM, FLONUM); void forward(FLONUM d) { prepare_to_draw; draw_turtle(); forward_helper(d); draw_turtle(); done_drawing; wanna_x = turtle_x; wanna_y = turtle_y; out_of_bounds = FALSE; } void forward_helper(FLONUM d) { FLONUM real_heading, dx, dy, x1, y1, x2, y2, newd = 0.0; FIXNUM rx2, ry2; wraploop: if (newd != 0.0) d = newd; real_heading = -turtle_heading + 90.0; x1 = screen_x_coord; y1 = screen_y_coord; dx = (FLONUM)(cos((FLONUM)(real_heading*degrad))*d*x_scale); dy = (FLONUM)(sin((FLONUM)(real_heading*degrad))*d*y_scale); if ((dx < 0 && dx > -0.000001) || (dx > 0 && dx < 0.000001)) dx = 0; if ((dy < 0 && dy > -0.000001) || (dy > 0 && dy < 0.000001)) dy = 0; x2 = x1 + dx; y2 = y1 - dy; move_to(g_round(x1), g_round(y1)); save_move(); if (check_throwing) return; if (internal_penmode == PENMODE_REVERSE && pen_vis == 0 && d > 0.0) { line_to(g_round(x1), g_round(y1)); /* flip the corner */ save_line(); } rx2 = g_round(x2); ry2 = g_round(y2); if (check_throwing) return; if (current_mode == windowmode || (rx2 >= screen_left && rx2 <= screen_right && ry2 >= screen_top && ry2 <= screen_bottom)) { turtle_x = turtle_x + dx; turtle_y = turtle_y + dy; line_to(rx2, ry2); save_line(); } else { if (rx2 > screen_right && g_round(x1) == screen_right) { move_to(screen_left, g_round(y1)); turtle_x = turtle_left_max; goto wraploop; } if (ry2 < screen_top && g_round(y1) == screen_top) { move_to(g_round(x1), screen_bottom); turtle_y = turtle_bottom_max; goto wraploop; } if (rx2 < screen_left && g_round(x1) == screen_left) { move_to(screen_right, g_round(y1)); turtle_x = turtle_right_max; goto wraploop; } if (ry2 > screen_bottom && g_round(y1) == screen_bottom) { move_to(g_round(x1), screen_top); turtle_y = turtle_top_max; goto wraploop; } if ((newd = wrap_right(d, x1, y1, x2, y2)) != 0.0) goto wraploop; if ((newd = wrap_left(d, x1, y1, x2, y2)) != 0.0) goto wraploop; if ((newd = wrap_up(d, x1, y1, x2, y2)) != 0.0) goto wraploop; if ((newd = wrap_down(d, x1, y1, x2, y2)) != 0.0) goto wraploop; } if (internal_penmode == PENMODE_REVERSE && pen_vis == 0 && d < 0.0) { line_to(g_round(screen_x_coord), g_round(screen_y_coord)); save_line(); } } FLONUM wrap_right(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) { FLONUM yi, newd; FIXNUM ryi; if (x2 > screen_right) { yi = ((y2 - y1)/(x2 - x1)) * (screen_right + 1 - x1) + y1; ryi = g_round(yi); if (ryi >= screen_top && ryi <= screen_bottom) { line_to(screen_right, ryi); save_line(); turtle_x = turtle_left_max; turtle_y = screen_y_center - yi; if (current_mode == wrapmode) { newd = d * ((x2 - screen_right - 1)/(x2 - x1)); if (newd*d > 0) return(newd); } else { turtle_x = turtle_right_max; err_logo(TURTLE_OUT_OF_BOUNDS, NIL); } } } return(0.0); } FLONUM wrap_left(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) { FLONUM yi, newd; FIXNUM ryi; if (x2 < screen_left) { yi = ((y1 - y2)/(x2 - x1)) * (x1 + 1 - screen_left) + y1; ryi = g_round(yi); if (ryi >= screen_top && ryi <= screen_bottom) { line_to(screen_left, ryi); save_line(); turtle_x = turtle_right_max; turtle_y = screen_y_center - yi; if (current_mode == wrapmode) { newd = d * ((x2 + 1 - screen_left)/(x2 - x1)); if (newd*d > 0) return(newd); } else { turtle_x = turtle_left_max; err_logo(TURTLE_OUT_OF_BOUNDS, NIL); } } } return(0.0); } FLONUM wrap_up(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) { FLONUM xi, newd; FIXNUM rxi; if (y2 < screen_top) { xi = ((x2 - x1)/(y1 - y2)) * (y1 + 1 - screen_top) + x1; rxi = g_round(xi); if (rxi >= screen_left && rxi <= screen_right) { line_to(rxi, screen_top); save_line(); turtle_x = xi - screen_x_center; turtle_y = turtle_bottom_max; if (current_mode == wrapmode) { newd = d * ((y2 + 1 - screen_top)/(y2 - y1)); if (newd*d > 0) return(newd); } else { turtle_y = turtle_top_max; err_logo(TURTLE_OUT_OF_BOUNDS, NIL); } } else if (rxi >= (screen_left-1) && rxi <= (screen_right+1)) { rxi = (rxi > screen_right ? screen_right : screen_left); line_to(rxi, screen_top); save_line(); turtle_x = xi - screen_x_center; turtle_y = turtle_bottom_max; if (current_mode == wrapmode) { newd = d * ((y2 + 1 - screen_top)/(y2 - y1)); if (newd*d > 0) return(newd); } else { turtle_y = turtle_top_max; err_logo(TURTLE_OUT_OF_BOUNDS, NIL); } } } return(0.0); } FLONUM wrap_down(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) { FLONUM xi, newd; FIXNUM rxi; if (y2 > screen_bottom) { xi = ((x2 - x1)/(y2 - y1)) * (screen_bottom + 1 - y1) + x1; rxi = g_round(xi); if (rxi >= screen_left && rxi <= screen_right) { line_to(rxi, screen_bottom); save_line(); turtle_x = xi - screen_x_center; turtle_y = turtle_top_max; if (current_mode == wrapmode) { newd = d * ((y2 - screen_bottom - 1)/(y2 - y1)); if (newd*d > 0) return(newd); } else { turtle_y = turtle_bottom_max; err_logo(TURTLE_OUT_OF_BOUNDS, NIL); } } else if (rxi >= (screen_left-1) && rxi <= (screen_right+1)) { rxi = (rxi > screen_right ? screen_right : screen_left); line_to(rxi, screen_bottom); save_line(); turtle_x = xi - screen_x_center; turtle_y = turtle_top_max; if (current_mode == wrapmode) { newd = d * ((y2 - screen_bottom - 1)/(y2 - y1)); if (newd*d > 0) return(newd); } else { turtle_y = turtle_bottom_max; err_logo(TURTLE_OUT_OF_BOUNDS, NIL); } } } return(0.0); } NODE *lforward(NODE *arg) { NODE *val; FLONUM d; val = numeric_arg(arg); if (NOT_THROWING) { if (nodetype(val) == INT) d = (FLONUM)getint(val); else d = getfloat(val); forward(d); } return(UNBOUND); } NODE *lback(NODE *arg) { NODE *val; FLONUM d; val = numeric_arg(arg); if (NOT_THROWING) { if (nodetype(val) == INT) d = (FLONUM)getint(val); else d = getfloat(val); forward(-d); } return(UNBOUND); } NODE *lshowturtle(NODE *args) { prepare_to_draw; if (!turtle_shown) { turtle_shown = TRUE; draw_turtle(); } done_drawing; return(UNBOUND); } NODE *lhideturtle(NODE *args) { prepare_to_draw; if (turtle_shown) { draw_turtle(); turtle_shown = FALSE; } done_drawing; return(UNBOUND); } NODE *lshownp(NODE *args) { return(turtle_shown ? TrueName() : FalseName()); } NODE *lsetheading(NODE *arg) { NODE *val; val = numeric_arg(arg); if (NOT_THROWING) { prepare_to_draw; draw_turtle(); if (nodetype(val) == INT) turtle_heading = (FLONUM)getint(val); else turtle_heading = getfloat(val); turtle_heading = pfmod(turtle_heading,360.0); draw_turtle(); done_drawing; } return(UNBOUND); } NODE *lheading(NODE *args) { return(make_floatnode(turtle_heading)); } NODE *vec_arg_helper(NODE *args, BOOLEAN floatok, BOOLEAN three) { NODE *arg = car(args), *val1, *val2, *val3 = NIL; while (NOT_THROWING) { if (arg != NIL && is_list(arg) && cdr(arg) != NIL && (three ? (cddr(arg) != NIL && cdr(cddr(arg)) == NIL) : cddr(arg) == NIL)) { val1 = cnv_node_to_numnode(car(arg)); val2 = cnv_node_to_numnode(cadr(arg)); if (three) val3 = cnv_node_to_numnode(car(cddr(arg))); if (val1 != UNBOUND && val2 != UNBOUND && (floatok || (nodetype(val1) == INT && getint(val1) >= 0 && nodetype(val2) == INT && getint(val2) >= 0 && (!three || (nodetype(val3) == INT && getint(val3) >= 0))))) { setcar(arg, val1); setcar(cdr(arg), val2); if (three) setcar (cddr(arg), val3); return(arg); } } setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } return(UNBOUND); } NODE *vector_arg(NODE *args) { return vec_arg_helper(args,TRUE,FALSE); } NODE *pos_int_vector_arg(NODE *args) { return vec_arg_helper(args,FALSE,FALSE); } NODE *rgb_arg(NODE *args) { return vec_arg_helper(args,FALSE,TRUE); } FLONUM towards_helper(FLONUM x, FLONUM y, FLONUM from_x, FLONUM from_y) { FLONUM m, a, tx, ty; tx = from_x/x_scale; ty = from_y/y_scale; if (x != tx || y != ty) { if (x == tx) a = (y < ty) ? -90 : 90; else { m = (y - ty)/(x - tx); a = atan(m)/degrad; if (x < tx) a = fmod(a + 180.0,360.0); } a = -(a - 90.0); return (a < 0 ? 360.0+a : a); } return 0.0; } NODE *ltowards(NODE *args) { NODE *xnode, *ynode = UNBOUND, *arg; FLONUM x, y; arg = vector_arg(args); if (NOT_THROWING) { xnode = car(arg); ynode = cadr(arg); x = ((nodetype(xnode) == FLOATT) ? getfloat(xnode) : (FLONUM)getint(xnode)); y = ((nodetype(ynode) == FLOATT) ? getfloat(ynode) : (FLONUM)getint(ynode)); return make_floatnode(towards_helper(x, y, turtle_x, turtle_y)); } return(UNBOUND); } NODE *lpos(NODE *args) { return(cons(make_floatnode(cut_error(turtle_x/x_scale)), cons(make_floatnode(cut_error(turtle_y/y_scale)), NIL))); } NODE *lscrunch(NODE *args) { return(cons(make_floatnode(x_scale), cons(make_floatnode(y_scale), NIL))); } NODE *lhome(NODE *args) { prepare_to_draw; out_of_bounds = FALSE; setpos_bynumber((FLONUM)0.0, (FLONUM)0.0); draw_turtle(); turtle_heading = 0.0; draw_turtle(); done_drawing; return(UNBOUND); } void cs_helper(int centerp) { #ifdef x_window clearing_screen++; #endif prepare_to_draw; clear_screen; #ifdef x_window clearing_screen==0; #endif if (centerp) { wanna_x = wanna_y = turtle_x = turtle_y = turtle_heading = 0.0; out_of_bounds = FALSE; move_to(screen_x_coord, screen_y_coord); } draw_turtle(); save_pen(&orig_pen); p_info_x(orig_pen) = g_round(screen_x_coord); p_info_y(orig_pen) = g_round(screen_y_coord); record_index = 0; last_recorded = -1; if (turtle_x != 0.0 || turtle_y != 0.0) save_move(); if (pen_vis != 0) save_vis(); if (internal_penmode != PENMODE_PAINT) save_mode(); if (pen_color != 7) save_color(); if (pen_width != 1 || pen_height != 1) save_size(); done_drawing; } NODE *lclearscreen(NODE *args) { cs_helper(TRUE); return(UNBOUND); } NODE *lclean(NODE *args) { cs_helper(FALSE); return(UNBOUND); } void setpos_commonpart(FLONUM target_x, FLONUM target_y) { FLONUM scaled_x, scaled_y, tx, ty, save_heading; BOOLEAN wrapping = FALSE; if (NOT_THROWING) { scaled_x = target_x * x_scale; scaled_y = target_y * y_scale; wrapping = scaled_x > turtle_right_max || scaled_x < turtle_left_max || scaled_y > turtle_top_max || scaled_y < turtle_bottom_max; if (current_mode == fencemode && wrapping) err_logo(TURTLE_OUT_OF_BOUNDS, NIL); else if (current_mode == wrapmode && (wrapping || out_of_bounds)) { save_heading = turtle_heading; turtle_heading = towards_helper(target_x, target_y, wanna_x, wanna_y); tx = wanna_x/x_scale; ty = wanna_y/y_scale; #define sq(z) ((z)*(z)) forward_helper(sqrt(sq(target_x - tx) + sq(target_y - ty))); turtle_heading = save_heading; wanna_x = scaled_x; wanna_y = scaled_y; out_of_bounds = wrapping; } else { out_of_bounds = FALSE; wanna_x = turtle_x = scaled_x; wanna_y = turtle_y = scaled_y; line_to(g_round(screen_x_coord), g_round(screen_y_coord)); save_line(); } draw_turtle(); done_drawing; } } void setpos_bynumber(FLONUM target_x, FLONUM target_y) { if (NOT_THROWING) { prepare_to_draw; draw_turtle(); move_to(g_round(screen_x_coord), g_round(screen_y_coord)); setpos_commonpart(target_x, target_y); done_drawing; } } void setpos_helper(NODE *xnode, NODE *ynode) { FLONUM target_x, target_y; if (NOT_THROWING) { prepare_to_draw; draw_turtle(); move_to(g_round(screen_x_coord), g_round(screen_y_coord)); target_x = ((xnode == NIL) ? turtle_x : ((nodetype(xnode) == FLOATT) ? getfloat(xnode) : (FLONUM)getint(xnode))); target_y = ((ynode == NIL) ? turtle_y : ((nodetype(ynode) == FLOATT) ? getfloat(ynode) : (FLONUM)getint(ynode))); setpos_commonpart(target_x, target_y); done_drawing; } } NODE *lsetpos(NODE *args) { NODE *arg = vector_arg(args); if (NOT_THROWING) { setpos_helper(car(arg), cadr(arg)); } return(UNBOUND); } NODE *lsetxy(NODE *args) { NODE *xnode, *ynode; xnode = numeric_arg(args); ynode = numeric_arg(cdr(args)); if (NOT_THROWING) { setpos_helper(xnode, ynode); } return(UNBOUND); } NODE *lsetx(NODE *args) { NODE *xnode; xnode = numeric_arg(args); if (NOT_THROWING) { setpos_helper(xnode, NIL); } return(UNBOUND); } NODE *lsety(NODE *args) { NODE *ynode; ynode = numeric_arg(args); if (NOT_THROWING) { setpos_helper(NIL, ynode); } return(UNBOUND); } NODE *lwrap(NODE *args) { prepare_to_draw; draw_turtle(); current_mode = wrapmode; while (turtle_x > turtle_right_max) { turtle_x -= screen_width; } while (turtle_x < turtle_left_max) { turtle_x += screen_width; } while (turtle_y > turtle_top_max) { turtle_y -= screen_height; } while (turtle_y < turtle_bottom_max) { turtle_y += screen_height; } move_to(screen_x_coord, screen_y_coord); draw_turtle(); done_drawing; return(UNBOUND); } NODE *lfence(NODE *args) { (void)lwrap(args); /* get turtle inside the fence */ prepare_to_draw; draw_turtle(); current_mode = fencemode; draw_turtle(); done_drawing; return(UNBOUND); } NODE *lwindow(NODE *args) { prepare_to_draw; draw_turtle(); current_mode = windowmode; draw_turtle(); done_drawing; return(UNBOUND); } NODE *lturtlemode(NODE *args) { switch (current_mode) { case wrapmode: return(theName(Name_wrap)); case fencemode: return(theName(Name_fence)); case windowmode: return(theName(Name_window)); } return(UNBOUND); /* Can't get here, but makes compiler happy */ } NODE *lfill(NODE *args) { prepare_to_draw; draw_turtle(); logofill(); draw_turtle(); if (safe_to_save()) { last_recorded = record[record_index] = FILLERUP; record_index += One; } done_drawing; return(UNBOUND); } NODE *llabel(NODE *arg) { char textbuf[300]; short theLength; print_stringptr = textbuf; print_stringlen = 300; ndprintf((FILE *)NULL,"%p",car(arg)); *print_stringptr = '\0'; if (NOT_THROWING) { prepare_to_draw; draw_turtle(); theLength = strlen(textbuf); #ifdef mac c_to_pascal_string(textbuf, theLength); #endif label(textbuf); save_string(textbuf,theLength); draw_turtle(); done_drawing; } return(UNBOUND); } enum {SCREEN_TEXT, SCREEN_SPLIT, SCREEN_FULL} screen_mode = SCREEN_TEXT; NODE *ltextscreen(NODE *args) { text_screen; screen_mode = SCREEN_TEXT; return(UNBOUND); } NODE *lsplitscreen(NODE *args) { split_screen; screen_mode = SCREEN_SPLIT; return(UNBOUND); } NODE *lfullscreen(NODE *args) { full_screen; screen_mode = SCREEN_FULL; return(UNBOUND); } NODE *lscreenmode(NODE *args) { switch (screen_mode) { case SCREEN_TEXT: return(theName(Name_textscreen)); case SCREEN_SPLIT: return(theName(Name_splitscreen)); case SCREEN_FULL: return(theName(Name_fullscreen)); } return(UNBOUND); /* Can't get here, but makes compiler happy */ } NODE *lpendownp(NODE *args) { return(pen_vis == 0 ? TrueName() : FalseName()); } NODE *lpencolor(NODE *args) { if (pen_color == -1) return lpalette(cons(make_intnode(-1),NIL)); return(make_intnode((FIXNUM)pen_color)); } NODE *lbackground(NODE *args) { if (back_ground == -2) return lpalette(cons(make_intnode(-2),NIL)); return(make_intnode((FIXNUM)back_ground)); } NODE *lpensize(NODE *args) { return(cons(make_intnode((FIXNUM)pen_width), cons(make_intnode((FIXNUM)pen_height), NIL))); } NODE *lpenpattern(NODE *args) { return(get_node_pen_pattern); } NODE *lpendown(NODE *args) { pen_vis = 0; save_vis(); return(UNBOUND); } NODE *lpenup(NODE *args) { if (pen_vis == 0) pen_vis--; save_vis(); return(UNBOUND); } NODE *lpenpaint(NODE *args) { internal_penmode = PENMODE_PAINT; pen_down; save_mode(); return(lpendown(NIL)); } NODE *lpenerase(NODE *args) { internal_penmode = PENMODE_ERASE; pen_erase; save_mode(); return(lpendown(NIL)); } NODE *lpenreverse(NODE *args) { internal_penmode = PENMODE_REVERSE; pen_reverse; save_mode(); return(lpendown(NIL)); } NODE *lpenmode(NODE *args) { switch(internal_penmode) { case PENMODE_PAINT: return theName(Name_paint); case PENMODE_ERASE: return theName(Name_erase); case PENMODE_REVERSE: return theName(Name_reverse); } return(UNBOUND); /* Can't get here, but makes compiler happy */ } NODE *lsetpencolor(NODE *arg) { NODE *val; if (NOT_THROWING) { prepare_to_draw; if (is_list(car(arg))) { val = make_intnode(-1); lsetpalette(cons(val,arg)); } else val = pos_int_arg(arg); set_pen_color(getint(val)); save_color(); done_drawing; } return(UNBOUND); } NODE *lsetbackground(NODE *arg) { NODE *val; if (NOT_THROWING) { prepare_to_draw; if (is_list(car(arg))) { val = make_intnode(-2); lsetpalette(cons(val,arg)); } else val = pos_int_arg(arg); set_back_ground(getint(val)); done_drawing; } return(UNBOUND); } NODE *lsetpalette(NODE *args) { NODE *slot = integer_arg(args); NODE *arg = rgb_arg(cdr(args)); int slotnum = (int)getint(slot); if (slotnum < -2) { err_logo(BAD_DATA_UNREC, slot); } else if (NOT_THROWING && ((slotnum > 7) || (slotnum < 0))) { prepare_to_draw; set_palette(slotnum, (unsigned int)getint(car(arg)), (unsigned int)getint(cadr(arg)), (unsigned int)getint(car(cddr(arg)))); if (pen_color == slotnum) { set_pen_color(slotnum); } done_drawing; if (slotnum > max_palette_slot) max_palette_slot = slotnum; } return(UNBOUND); } NODE *lpalette(NODE *args) { NODE *arg = integer_arg(args); unsigned int r=0, g=0, b=0; if (getint(arg) < -2) err_logo(BAD_DATA_UNREC, arg); if (NOT_THROWING) { get_palette((int)getint(arg), &r, &g, &b); return cons(make_intnode((FIXNUM)r), cons(make_intnode((FIXNUM)g), cons(make_intnode((FIXNUM)b), NIL))); } return UNBOUND; } void save_palette(FILE *fp) { unsigned int colors[3]; int i; fwrite(&max_palette_slot, sizeof(int), 1, fp); for (i=8; i <= max_palette_slot; i++) { get_palette(i, &colors[0], &colors[1], &colors[2]); fwrite(colors, sizeof(int), 3, fp); } } void restore_palette(FILE *fp) { unsigned int colors[3]; int i, nslots; fread(&nslots, sizeof(int), 1, fp); if (nslots > max_palette_slot) max_palette_slot = nslots; for (i=8; i <= nslots; i++) { fread(colors, sizeof(int), 3, fp); set_palette(i, colors[0], colors[1], colors[2]); } } NODE *lsetpensize(NODE *args) { NODE *arg; if (NOT_THROWING) { prepare_to_draw; if (is_list(car(args))) { arg = pos_int_vector_arg(args); set_pen_width((int)getint(car(arg))); set_pen_height((int)getint(cadr(arg))); } else { /* 5.5 accept single number for [n n] */ arg = pos_int_arg(args); set_pen_width((int)getint(arg)); set_pen_height((int)getint(arg)); } save_size(); done_drawing; } return(UNBOUND); } NODE *lsetpenpattern(NODE *args) { NODE *arg; arg = car(args); while ((!is_list(arg)) && NOT_THROWING) arg = err_logo(BAD_DATA, arg); if (NOT_THROWING) { prepare_to_draw; set_list_pen_pattern(arg); save_pattern(); done_drawing; } return(UNBOUND); } NODE *lsetscrunch(NODE *args) { NODE *xnode, *ynode; xnode = numeric_arg(args); ynode = numeric_arg(cdr(args)); if (NOT_THROWING) { prepare_to_draw; draw_turtle(); x_scale = (nodetype(xnode) == FLOATT) ? getfloat(xnode) : (FLONUM)getint(xnode); y_scale = (nodetype(ynode) == FLOATT) ? getfloat(ynode) : (FLONUM)getint(ynode); draw_turtle(); done_drawing; #ifdef __RZTC__ { FILE *fp = fopen("scrunch.dat","r"); if (fp != NULL) { fclose(fp); fp = fopen("scrunch.dat","w"); if (fp != NULL) { fwrite(&x_scale, sizeof(FLONUM), 1, fp); fwrite(&y_scale, sizeof(FLONUM), 1, fp); fclose(fp); } } } #endif } return(UNBOUND); } NODE *lmousepos(NODE *args) { return(cons(make_intnode(mouse_x), cons(make_intnode(mouse_y), NIL))); } NODE *lbuttonp(NODE *args) { if (button) return(TrueName()); return(FalseName()); } NODE *lbutton(NODE *args) { return(make_intnode(button)); } NODE *ltone(NODE *args) { NODE *p, *d; FIXNUM pitch, duration; p = numeric_arg(args); d = numeric_arg(cdr(args)); if (NOT_THROWING) { pitch = (nodetype(p) == FLOATT) ? (FIXNUM)getfloat(p) : getint(p); duration = (nodetype(d) == FLOATT) ? (FIXNUM)getfloat(d) : getint(d); if (pitch > 0) tone(pitch, duration); } return(UNBOUND); } void do_arc(FLONUM count, FLONUM ang, FLONUM radius, FLONUM delta, FLONUM tx, FLONUM ty, FLONUM angle, FLONUM thead, BOOLEAN save) { FLONUM x; FLONUM y; FLONUM i; BOOLEAN save_refresh = refresh_p; FLONUM save_x = turtle_x; FLONUM save_y = turtle_y; int pen_state; refresh_p = 0; if (save) { x = sin(ang*3.141592654/180.0)*radius; y = cos(ang*3.141592654/180.0)*radius; turtle_x = tx+x; turtle_y = ty+y; } /* draw each line segment of arc (will do wrap) */ for (i=1.0;i<=count;i=i+1.0) { /* calc x y */ x = sin(ang*3.141592654/180.0)*radius; y = cos(ang*3.141592654/180.0)*radius; setpos_bynumber(tx+x, ty+y); ang = ang + delta; } /* assure we draw something and end in the exact right place */ x = sin((thead+angle)*3.141592654/180.0)*radius; y = cos((thead+angle)*3.141592654/180.0)*radius; setpos_bynumber(tx+x, ty+y); if (save) { pen_state = pen_vis; pen_vis = -1; setpos_bynumber(tx, ty); pen_vis = pen_state; turtle_x = save_x; turtle_y = save_y; } refresh_p = save_refresh; } NODE *larc(NODE *arg) { NODE *val1; NODE *val2; FLONUM angle; FLONUM radius; FLONUM ang; FLONUM tx; FLONUM ty; FLONUM count; FLONUM delta; FLONUM x; FLONUM y; int turtle_state; int pen_state; /* get args */ val1 = numeric_arg(arg); val2 = numeric_arg(cdr(arg)); if (NOT_THROWING) { if (nodetype(val1) == INT) angle = (FLONUM)getint(val1); else angle = getfloat(val1); if (nodetype(val2) == INT) radius = (FLONUM)getint(val2); else radius = getfloat(val2); prepare_to_draw; draw_turtle(); /* save and force turtle state */ turtle_state = turtle_shown; turtle_shown = 0; /* grab things before they change and use for restore */ ang = turtle_heading; tx = turtle_x; ty = turtle_y; /* calculate resolution parameters */ if (angle > 360.0) angle = 360.0+fmod(angle, 360.0); if (angle < -360.0) angle = -(360.0+fmod(-angle, 360.0)); count = fabs(angle*radius/200.0); /* 4.5 */ if (count == 0.0) count = 1.0; delta = angle/count; /* jump to begin of first line segment without drawing */ x = sin(ang*3.141592654/180.0)*radius; y = cos(ang*3.141592654/180.0)*radius; pen_state = pen_vis; pen_vis = -1; save_vis(); setpos_bynumber(tx+x, ty+y); pen_vis = pen_state; save_vis(); ang = ang + delta; save_arc(count, ang, radius, delta, tx, ty, angle, turtle_heading); do_arc(count, ang, radius, delta, tx, ty, angle, turtle_heading, 0); /* restore state */ pen_state = pen_vis; pen_vis = -1; save_vis(); setpos_bynumber(tx, ty); pen_vis = pen_state; save_vis(); turtle_shown = turtle_state; draw_turtle(); wanna_x = turtle_x; wanna_y = turtle_y; out_of_bounds = FALSE; pen_state = pen_vis; pen_vis = -1; save_vis(); forward_helper((FLONUM)0.0); /* Lets fill work -- dunno why */ pen_vis = pen_state; save_vis(); done_drawing; } return(UNBOUND); } /************************************************************/ /* The rest of this file implements the recording of moves in the graphics window and the playing back of those moves. It's needed on machines like the Macintosh where the contents of the graphics window can get erased and need to be redrawn. On machines where no graphics redrawing is necessary, set the size of the recording buffer to 1 in logo.h. */ BOOLEAN safe_to_save(void) { return(refresh_p && record_index < (GR_SIZE - 300)); } void save_lm_helper (void) { *(int *)(record + record_index + One) = g_round(turtle_x); *(int *)(record + record_index + Two) = g_round(turtle_y); record_index += Three; } void save_line(void) { if (safe_to_save()) { last_recorded = record[record_index] = LINEXY; save_lm_helper(); } } void save_move(void) { if (safe_to_save()) { if (record_index >= Three && last_recorded == MOVEXY) record_index -= Three; last_recorded = record[record_index] = MOVEXY; save_lm_helper(); } } void save_vis(void) { if (safe_to_save()) { last_recorded = record[record_index] = SETPENVIS; record[record_index + 1] = pen_vis; record_index += One; } } void save_mode(void) { if (safe_to_save()) { last_recorded = record[record_index] = SETPENMODE; #if defined(x_window) && !HAVE_WX *(GC *)(record + record_index + One) = pen_mode; #else *(int *)(record + record_index + One) = pen_mode; #endif *(int *)(record + record_index + Two) = internal_penmode; record_index += Three; save_color(); } } void save_color(void) { int r,g,b; if (safe_to_save()) { if (pen_color == -1) { get_palette(pen_color, &r, &g, &b); last_recorded = record[record_index] = SETPENRGB; *(int *)(record + record_index + One) = r; *(int *)(record + record_index + Two) = g; *(int *)(record + record_index + Three) = b; record_index += Four; } else { last_recorded = record[record_index] = SETPENCOLOR; *(int *)(record + record_index + One) = pen_color; record_index += Two; } } } void save_size(void) { if (safe_to_save()) { last_recorded = record[record_index] = SETPENSIZE; *(int *)(record + record_index + One) = pen_width; *(int *)(record + record_index + Two) = pen_height; record_index += Three; } } void save_pattern(void) { if (safe_to_save()) { last_recorded = record[record_index] = SETPENPATTERN; get_pen_pattern(&record[record_index + One]); record_index += One+8; } } void save_string(char *s, int len) { int count; if (safe_to_save()) { last_recorded = record[record_index] = LABEL; record[record_index + One] = (unsigned char)len; for (count = 0; count <= len; count++) record[record_index + One+1 + count] = s[count]; record[record_index + One+2 + len] = '\0'; record_index += (One+2 + len + (One-1)) & ~(One-1); } } void save_arc(FLONUM count, FLONUM ang, FLONUM radius, FLONUM delta, FLONUM tx, FLONUM ty, FLONUM angle, FLONUM thead) { if (safe_to_save()) { last_recorded = record[record_index] = ARC; *(FLONUM *)(record + record_index + Big) = count; *(FLONUM *)(record + record_index + 2 * Big) = ang; *(FLONUM *)(record + record_index + 3 * Big) = radius; *(FLONUM *)(record + record_index + 4 * Big) = delta; *(FLONUM *)(record + record_index + 5 * Big) = tx; *(FLONUM *)(record + record_index + 6 * Big) = ty; *(FLONUM *)(record + record_index + 7 * Big) = angle; *(FLONUM *)(record + record_index + 8 * Big) = thead; record_index += 9*Big; } } NODE *lrefresh(NODE *args) { refresh_p = TRUE; return(UNBOUND); } NODE *lnorefresh(NODE *args) { refresh_p = FALSE; return(UNBOUND); } void redraw_graphics(void) { FLONUM save_tx, save_ty, save_th; FIXNUM r_index = 0; int lastx, lasty; pen_info saved_pen; BOOLEAN saved_shown; #if defined(__RZTC__) && !defined(WIN32) BOOLEAN save_splitscreen = in_splitscreen; #endif if (!refresh_p) { /* clear_screen; draw_turtle(); */ return; } prepare_to_draw; save_tx = turtle_x; save_ty = turtle_y; save_th = turtle_heading; saved_shown = turtle_shown; turtle_shown = FALSE; save_pen(&saved_pen); restore_pen(&orig_pen); #if defined(__RZTC__) && !defined(WIN32) full_screen; #endif erase_screen(); wanna_x = wanna_y = turtle_x = turtle_y = turtle_heading = 0.0; out_of_bounds = FALSE; move_to(screen_x_coord, screen_y_coord); internal_penmode = PENMODE_PAINT; pen_down; set_pen_color((FIXNUM)7); set_pen_width(1); set_pen_height(1); #ifdef __TURBOC__ moveto(p_info_x(orig_pen),p_info_y(orig_pen)); #endif lastx = lasty = 0; while (r_index < record_index) { turtle_x = (FLONUM)(lastx); turtle_y = (FLONUM)(lasty); switch (record[r_index]) { case (LINEXY) : lastx = *(int *)(record + r_index + One); lasty = *(int *)(record + r_index + Two); line_to(screen_x_center+lastx, screen_y_center-lasty); r_index += Three; break; case (MOVEXY) : lastx = *(int *)(record + r_index + One); lasty = *(int *)(record + r_index + Two); move_to(screen_x_center+lastx, screen_y_center-lasty); r_index += Three; break; case (LABEL) : draw_string((unsigned char *)(record + r_index + One+1)); move_to(screen_x_center+lastx, screen_y_center-lasty); r_index += (One+2 + record[r_index + One] + (One-1)) & ~(One-1); break; case (SETPENVIS) : set_pen_vis(record[r_index + 1]); r_index += One; break; case (SETPENMODE) : #if defined(x_window) && !HAVE_WX set_pen_mode(*(GC *)(record + r_index + One)); #else set_pen_mode(*(int *)(record + r_index + One)); #endif internal_penmode = *(int *)(record + r_index + Two); r_index += Three; break; case (SETPENCOLOR) : set_pen_color((FIXNUM)(*(int *)(record + r_index + One))); r_index += Two; break; case (SETPENRGB) : set_palette(-1, (*(int *)(record + r_index + One)), (*(int *)(record + r_index + Two)), (*(int *)(record + r_index + Three))); set_pen_color((FIXNUM)(-1)); r_index += Four; break; case (SETPENSIZE) : set_pen_width(*(int *)(record + r_index + One)); set_pen_height(*(int *)(record + r_index + Two)); r_index += Three; break; case (SETPENPATTERN) : set_pen_pattern(&record[r_index + One]); r_index += One+8; break; case (FILLERUP) : logofill(); r_index += One; break; case (ARC) : do_arc(*(FLONUM *)(record + r_index + Big), *(FLONUM *)(record + r_index + 2 * Big), *(FLONUM *)(record + r_index + 3 * Big), *(FLONUM *)(record + r_index + 4 * Big), *(FLONUM *)(record + r_index + 5 * Big), *(FLONUM *)(record + r_index + 6 * Big), *(FLONUM *)(record + r_index + 7 * Big), *(FLONUM *)(record + r_index + 8 * Big), 1); r_index += 9*Big; break; } } restore_pen(&saved_pen); turtle_shown = saved_shown; #if defined(__RZTC__) && !defined(WIN32) if (save_splitscreen) {split_screen;} #endif turtle_x = save_tx; turtle_y = save_ty; turtle_heading = save_th; draw_turtle(); done_drawing; } NODE *lsavepict(NODE *args) { FILE *fp; static int bg; FIXNUM want, cnt; char *p; #if defined(WIN32)||defined(ibm) extern NODE *lopen(NODE *, char *); lopen(args,"wb"); #else lopenwrite(args); #endif if (NOT_THROWING) { fp = (FILE *)file_list->n_obj; save_palette(fp); fwrite(&record_index, sizeof(FIXNUM), 1, fp); want = record_index; p = record; while (want > 0) { cnt = fwrite(p, 1, want, fp); if (ferror(fp) || cnt <= 0) { err_logo(FILE_ERROR, make_static_strnode("File too big")); lclose(args); return UNBOUND; } want -= cnt; p += cnt; } bg = (int)back_ground; fwrite(&bg, sizeof(int), 1, fp); lclose(args); } return UNBOUND; } NODE *lloadpict(NODE *args) { FILE *fp; static int bg; FIXNUM want, cnt; char *p; #if defined(WIN32)||defined(ibm) extern NODE *lopen(NODE *, char *); lopen(args,"rb"); #else lopenread(args); #endif if (NOT_THROWING) { prepare_to_draw; fp = (FILE *)file_list->n_obj; restore_palette(fp); fread(&record_index, sizeof(FIXNUM), 1, fp); if (record_index < 0 || record_index >= GR_SIZE) { err_logo(FILE_ERROR, make_static_strnode("File bad format")); record_index = 0; last_recorded = -1; lclose(args); return UNBOUND; } want = record_index; p = record; while (want > 0) { cnt = fread(p, 1, want, fp); if (ferror(fp) || cnt <= 0) { record_index = 0; last_recorded = -1; done_drawing; err_logo(FILE_ERROR, make_static_strnode("File bad format")); lclose(args); return UNBOUND; } want -= cnt; p += cnt; } fread(&bg, sizeof(int), 1, fp); lclose(args); set_back_ground((FIXNUM)bg); done_drawing; } return UNBOUND; } void ps_string(FILE *fp, char *p) { int ch; while ((ch = *p++)) { if (ch=='(' || ch==')' || ch=='\\') fprintf(fp, "\\"); fprintf(fp, "%c", ch); } } void rgbprint(FILE *fp, int cnum) { unsigned int r=0, g=0, b=0; get_palette(cnum, &r, &g, &b); fprintf(fp, "%6.4f %6.4f %6.4f", ((double)r)/65535, ((double)g)/65535, ((double)b)/65535); } #ifdef mac extern void fixMacType(NODE *args); #endif NODE *lepspict(NODE *args) { FILE *fp; int r_index = 0, act=0, lastx = 0, lasty = 0, vis = 0; #ifdef mac fixMacType(args); lopenappend(args); #else lopenwrite(args); #endif if (NOT_THROWING) { fp = (FILE *)file_list->n_obj; fprintf(fp, "%%!PS-Adobe-3.0 EPSF-3.0\n"); ndprintf(fp, "%%Title: %p\n", car(args)); fprintf(fp, "%%%%Creator: Logo2PS 1.1; Copyright 1997, Vladimir Batagelj\n"); fprintf(fp, "%%%%BoundingBox: %d %d %d %d\n", screen_left, screen_top, screen_right, screen_bottom); fprintf(fp, "%%%%EndComments\n"); ndprintf(fp, "%%Page: %p\n", car(args)); fprintf(fp, "1 setlinecap 1 setlinejoin\n"); fprintf(fp, "/Courier 9 selectfont\n"); fprintf(fp, "gsave\n"); rgbprint(fp, back_ground); fprintf(fp, " setrgbcolor\n"); fprintf(fp, "%d %d moveto %d %d lineto %d %d lineto %d %d lineto\n", screen_left, screen_top, screen_right, screen_top, screen_right, screen_bottom, screen_left, screen_bottom); fprintf(fp, " closepath fill grestore\n"); fprintf(fp, "%d %d moveto\n", screen_x_center, screen_y_center); while (r_index < record_index) switch (record[r_index]) { case (LINEXY) : if (!vis) { lastx = screen_x_center + *(int *)(record + r_index + One); lasty = screen_y_center + *(int *)(record + r_index + Two); fprintf(fp, "%d %d lineto\n", lastx, lasty); r_index += Three; act++; break; /* else fall through */ } case (MOVEXY) : lastx = screen_x_center + *(int *)(record + r_index + One); lasty = screen_y_center + *(int *)(record + r_index + Two); fprintf(fp, "%d %d moveto\n", lastx, lasty); r_index += Three; break; case (LABEL) : fprintf(fp, "gsave -5 1 rmoveto ("); ps_string(fp, record + r_index + One+1); fprintf(fp, ") show grestore\n"); fprintf(fp, "%d %d moveto\n", lastx, lasty); r_index += (One+2 + record[r_index + One] + (One-1)) & ~(One-1); break; case (SETPENVIS) : vis = record[r_index + 1]; r_index += One; break; case (SETPENMODE) : r_index += Three; break; case (SETPENCOLOR) : if (act) { fprintf(fp, "stroke %d %d moveto\n", lastx, lasty); act = 0; } rgbprint(fp, (*(int *)(record + r_index + One))); fprintf(fp, " setrgbcolor\n"); r_index += Two; break; case (SETPENRGB) : if (act) { fprintf(fp, "stroke %d %d moveto\n", lastx, lasty); act = 0; } set_palette(-1, (*(int *)(record + r_index + One)), (*(int *)(record + r_index + Two)), (*(int *)(record + r_index + Three))); rgbprint(fp, -1); fprintf(fp, " setrgbcolor\n"); r_index += Four; break; case (SETPENSIZE) : if (act) { fprintf(fp, "stroke %d %d moveto\n", lastx, lasty); act = 0; } fprintf(fp, "%d setlinewidth\n", (*(int *)(record + r_index + One))); r_index += Three; break; case (SETPENPATTERN) : r_index += One+8; break; case (FILLERUP) : r_index += One; break; case (ARC) : r_index += 9*Big; break; } fprintf(fp, "stroke\nshowpage\n%%%%EOF\n"); lclose(args); } return UNBOUND; } ucblogo-5.5/makehelp.c0100644000161300001330000000646310276046366012705 0ustar bhdoe#include #include char line[100], line2[100], line3[100]; char name[30] = "helpfiles/"; char name2[30] = "helpfiles/"; char tocname[20], tocname2[20]; main() { FILE *in=fopen("usermanual", "r"); FILE *fp, *fp2; FILE *toc=fopen("helpfiles/HELPCONTENTS", "w"); FILE *tmp=fopen("helptemp", "w"); FILE *all=fopen("helpfiles/ALL_NAMES", "w"); char ch, *cp, *np, *tp; int intab, three, col=5; if (toc == NULL) { fprintf(stderr, "Can't open HELPCONTENTS.\n"); exit(1); } fputs("Help is available on the following:\n\n", toc); fgets(line, 100, in); while (line[0] != '-') fgets(line, 100, in); while (!feof(in)) { for (cp = line, np = &name[10], tp = tocname; (ch = *cp) == '.' || (ch >= 'A' && ch <= 'Z') || ch == '`' || ch == '0' || ch == '1'; cp++) { *tp++ = tolower(ch); if (ch == '.') ch='d'; *np++ = tolower(ch); } if (cp == line || (ch != ' ' && ch != '\t' && ch != '\n')) { fgets(line, 100, in); continue; } *tp = *np = '\0'; if (name[11] == '\0' && name[10] != '`') { fgets(line, 100, in); continue; } line2[1] = 'x'; fgets(line2, 100, in); if ((ch = line2[1]) == '-' || ch == '=') { fgets(line, 100, in); continue; } fp = fopen(name, "w"); if (fp == NULL) { fprintf(stderr, "Can't open %s\n", name); exit(1); } fprintf(tmp, "%s\n", tocname); fprintf(all, "%s\n", tocname); three = 0; ch = line2[0]; if (ch == '.' || (ch >= 'A' && ch <= 'Z')) { for (cp = line2, np = &name2[10], tp = tocname2; (ch = *cp) == '.' || (ch >= 'A' && ch <= 'Z') || ch == '?'; cp++) { *tp++ = tolower(ch); if (ch == '.') ch='d'; if (ch == '?') three++; *np++ = tolower(ch); } *tp = *np = '\0'; if (tp != tocname2 && strcmp(tocname, tocname2)) fprintf(all, "%s\n", tocname2); if (three) { fp2 = NULL; fgets(line3, 100, in); tp = tocname2; if ((ch = line3[0]) == '.' || (ch >= 'A' && ch <= 'Z')) { for (cp = line3, np = &name2[10]; (ch = *cp) == '.' || (ch >= 'A' && ch <= 'Z') || ch == '?'; cp++) { *tp++ = tolower(ch); if (ch == '.') ch='d'; *np++ = tolower(ch); } *tp = *np = '\0'; } else name2[10] = '\0'; if (tp != tocname2) fprintf(all, "%s\n", tocname); } if (name2[10] != '\0') { fp2 = fopen(name2, "w"); if (fp2 == NULL) { fprintf(stderr, "Can't open %s\n", name2); exit(1); } } else fp2 = NULL; } else fp2 = NULL; fputs(line, fp); fputs(line2, fp); if (three) fputs(line3, fp); if (fp2) { fputs(line, fp2); fputs(line2, fp2); if (three) fputs(line3, fp); } intab = 0; fgets(line, 100, in); while (!feof(in)) { if (intab && line[0] != '\t' && line[0] != '\n') break; if (!intab && line[0] == '\t') intab++; fputs(line, fp); if (fp2) fputs(line, fp2); fgets(line, 100, in); } fclose(fp); if (fp2) fclose(fp2); } fprintf(tmp, ".defmacro\n"); /* looks like abbrev for .macro */ fprintf(tmp, "+\n-\n*\n/\n=\n<\n>\n"); /* infix operators */ fprintf(tmp, "<=\n>=\n<>\n"); /* two-char infix */ fclose(tmp); fprintf(all, "+\n-\n*\n/\n=\n<\n>\n"); /* infix operators */ fprintf(all, "<=\n>=\n<>\n"); /* two-char infix */ fclose(all); fclose(toc); exit(0); } ucblogo-5.5/coms.c0100644000161300001330000002562610271734206012052 0ustar bhdoe/* * coms.c program execution control module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" #include #ifdef HAVE_UNISTD_H #include #endif #ifdef ibm #include "process.h" #endif #ifdef mac #include #include #endif #ifdef __RZTC__ #include #include #include #include #endif #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif NODE *make_cont(enum labels cont, NODE *val) { #ifdef __RZTC__ union { enum labels lll; NODE *ppp;} cast; #endif NODE *retval = cons(NIL, val); #ifdef __RZTC__ cast.lll = cont; retval->n_car = cast.ppp; #else retval->n_car = (NODE *)cont; #endif settype(retval, CONT); return retval; } NODE *loutput(NODE *arg) { if (NOT_THROWING) { if (ufun == NIL) { err_logo(AT_TOPLEVEL, fun); } else if (val_status & OUTPUT_TAIL /* This happens if OP seen when val_status & STOP_OK */ || !(val_status & OUTPUT_OK)) { /* This happens on OP OP 3 */ if (didnt_output_name == NIL) didnt_output_name = fun; if (didnt_get_output == UNBOUND) { didnt_get_output = cons_list(0,theName(Name_output), ufun,this_line,END_OF_LIST); /* Not quite right; could be .maybeoutput */ didnt_output_name = fun; } err_logo(DIDNT_OUTPUT, NIL); } else { stopping_flag = OUTPUT; output_unode = current_unode; output_node = car(arg); } } return(UNBOUND); } NODE *lstop(NODE *args) { if (NOT_THROWING) if (ufun == NIL) err_logo(AT_TOPLEVEL, theName(Name_stop)); else if (val_status & OUTPUT_TAIL || !(val_status & STOP_OK)) { didnt_output_name = fun; err_logo(DIDNT_OUTPUT, NIL); } else { stopping_flag = STOP; output_unode = current_unode; } return(UNBOUND); } NODE *lthrow(NODE *arg) { if (NOT_THROWING) { if (isName(car(arg), Name_error)) { if (cdr(arg) != NIL) err_logo(USER_ERR_MESSAGE, cadr(arg)); else err_logo(USER_ERR, UNBOUND); } else { stopping_flag = THROWING; throw_node = car(arg); if (cdr(arg) != NIL) output_node = cadr(arg); else output_node = UNBOUND; } } return(UNBOUND); } NODE *lcatch(NODE *args) { return make_cont(catch_continuation, cons(car(args), lrun(cdr(args)))); } extern NODE *evaluator(NODE *list, enum labels where); int torf_arg(NODE *args) { NODE *arg = car(args); while (NOT_THROWING) { if (is_list(arg)) { /* accept a list and run it */ val_status = VALUE_OK; arg = evaluator(arg, begin_seq); } if (isName(arg, Name_true)) return TRUE; if (isName(arg, Name_false)) return FALSE; if (NOT_THROWING) arg = err_logo(BAD_DATA, arg); } return -1; } NODE *lgoto(NODE *args) { return make_cont(goto_continuation, car(args)); } NODE *ltag(NODE *args) { return UNBOUND; } NODE *lnot(NODE *args) { int arg = torf_arg(args); if (NOT_THROWING) { if (arg) return(FalseName()); else return(TrueName()); } return(UNBOUND); } NODE *land(NODE *args) { int arg; if (args == NIL) return(TrueName()); while (NOT_THROWING) { arg = torf_arg(args); if (arg == FALSE) return(FalseName()); args = cdr(args); if (args == NIL) break; } if (NOT_THROWING) return(TrueName()); else return(UNBOUND); } NODE *lor(NODE *args) { int arg; if (args == NIL) return(FalseName()); while (NOT_THROWING) { arg = torf_arg(args); if (arg == TRUE) return(TrueName()); args = cdr(args); if (args == NIL) break; } if (NOT_THROWING) return(FalseName()); else return(UNBOUND); } NODE *runnable_arg(NODE *args) { NODE *arg = car(args); if (!aggregate(arg)) { setcar(args, parser(arg, TRUE)); arg = car(args); } while (!is_list(arg) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } return(arg); } NODE *lif(NODE *args) { /* macroized */ NODE *yes; int pred; if (cddr(args) != NIL) return(lifelse(args)); pred = torf_arg(args); yes = runnable_arg(cdr(args)); if (NOT_THROWING) { if (pred) return(yes); return(NIL); } return(UNBOUND); } NODE *lifelse(NODE *args) { /* macroized */ NODE *yes, *no; int pred; pred = torf_arg(args); yes = runnable_arg(cdr(args)); no = runnable_arg(cddr(args)); if (NOT_THROWING) { if (pred) return(yes); return(no); } return(UNBOUND); } NODE *lrun(NODE *args) { /* macroized */ NODE *arg = runnable_arg(args); if (NOT_THROWING) return(arg); return(UNBOUND); } NODE *lrunresult(NODE *args) { return make_cont(runresult_continuation, lrun(args)); } NODE *pos_int_arg(NODE *args) { NODE *arg = car(args), *val; FIXNUM i; FLONUM f; val = cnv_node_to_numnode(arg); while ((nodetype(val) != INT || getint(val) < 0) && NOT_THROWING) { if (nodetype(val) == FLOATT && fmod((f = getfloat(val)), 1.0) == 0.0 && f >= 0.0 && f < (FLONUM)MAXLOGOINT) { #if HAVE_IRINT i = irint(f); #else i = (FIXNUM)f; #endif val = make_intnode(i); break; } setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); val = cnv_node_to_numnode(arg); } setcar(args,val); if (nodetype(val) == INT) return(val); return UNBOUND; } NODE *lrepeat(NODE *args) { NODE *cnt, *torpt, *retval = NIL; cnt = pos_int_arg(args); torpt = lrun(cdr(args)); if (NOT_THROWING) { retval = make_cont(repeat_continuation, cons(cnt,torpt)); } return(retval); } NODE *lrepcount(NODE *args) { return make_intnode(user_repcount); } NODE *lforever(NODE *args) { NODE *torpt = lrun(args); if (NOT_THROWING) return make_cont(repeat_continuation, cons(make_intnode(-1), torpt)); return NIL; } NODE *ltest(NODE *args) { int arg = torf_arg(args); if (tailcall != 0) return UNBOUND; if (NOT_THROWING) { dont_fix_ift = arg+1; } return(UNBOUND); } NODE *liftrue(NODE *args) { if (ift_iff_flag < 0) return(err_logo(NO_TEST,NIL)); else if (ift_iff_flag > 0) return(lrun(args)); else return(NIL); } NODE *liffalse(NODE *args) { if (ift_iff_flag < 0) return(err_logo(NO_TEST,NIL)); else if (ift_iff_flag == 0) return(lrun(args)); else return(NIL); } void prepare_to_exit(BOOLEAN okay) { #ifdef mac if (okay) { console_options.pause_atexit = 0; exit(0); } #endif #ifndef WIN32 /* sowings */ #ifdef ibm ltextscreen(NIL); ibm_plain_mode(); #ifdef __RZTC__ msm_term(); zflush(); controlc_close(); #endif #endif #endif /* !WIN32 */ #ifdef unix #ifndef HAVE_UNISTD_H extern int getpid(); #endif char ef[30]; charmode_off(); sprintf(ef, "/tmp/logo%d", (int)getpid()); unlink(ef); #endif } NODE *lbye(NODE *args) { prepare_to_exit(TRUE); if (ufun != NIL || loadstream != stdin) exit(0); #ifndef WIN32 if (isatty(0) && isatty(1)) #endif lcleartext(NIL); ndprintf(stdout, "%t\n", message_texts[THANK_YOU]); ndprintf(stdout, "%t\n", message_texts[NICE_DAY]); #ifdef __RZTC__ printf("\n"); #endif exit(0); return UNBOUND; /* not reached, but makes compiler happy */ } NODE *lwait(NODE *args) { NODE *num; unsigned int n; #ifdef mac long target; extern void ProcessEvent(void); #endif num = pos_int_arg(args); if (NOT_THROWING) { #ifdef WIN32 win32_update_text(); #else fflush(stdout); /* csls v. 1 p. 7 */ #endif #if defined(__RZTC__) zflush(); #endif if (getint(num) > 0) { #ifdef unix #ifdef HAVE_USLEEP n = (unsigned int)getint(num) * 16667; usleep(n); #else n = (unsigned int)getint(num) / 60; sleep(n); #endif #elif defined(__RZTC__) usleep(getint(num) * 16667L); #elif defined(mac) target = getint(num)+TickCount(); while (TickCount() < target) { if (check_throwing) break; ProcessEvent(); } #elif defined(_MSC_VER) n = (unsigned int)getint(num); while (n > 60) { _sleep(1000); n -= 60; if (check_throwing) n = 0; } if (n > 0) _sleep(n*1000/60); #else /* unreachable, I think */ if (!setjmp(iblk_buf)) { input_blocking++; n = ((unsigned int)getint(num)+30) / 60; if (n > 0) sleep(n); } input_blocking = 0; #endif } } return(UNBOUND); } NODE *lshell(NODE *args) { #ifdef mac printf("%s\n", message_texts[NOSHELL_MAC]); return(UNBOUND); #else #ifdef ibm NODE *arg; char doscmd[200]; /* union REGS r; */ arg = car(args); while (!is_list(arg) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } if (arg == NIL) { ndprintf(stdout, "%t\n", message_texts[TYPE_EXIT]); if (spawnlp(P_WAIT, "command", "command", NULL)) err_logo(FILE_ERROR, make_static_strnode ("Could not open shell (probably due to low memory)")); } else { print_stringlen = 199; print_stringptr = doscmd; ndprintf((FILE *)NULL,"%p",arg); *print_stringptr = '\0'; if (system(doscmd) < 0) err_logo(FILE_ERROR, make_static_strnode ("Could not open shell (probably due to low memory)")); } /* r.h.ah = 0x3; r.h.al = 0; r.h.dh = 0; r.h.dl = 0; int86(0x21, &r, &r); x_coord = x_margin; y_coord = r.h.dh; */ #ifndef WIN32 x_coord = x_margin; y_coord = y_max; ibm_gotoxy(x_coord, y_coord); #else win32_repaint_screen(); #endif return(UNBOUND); #else extern FILE *popen(); char cmdbuf[300]; FILE *strm; NODE *head = NIL, *tail = NIL, *this; BOOLEAN wordmode = FALSE; int len; if (cdr(args) != NIL) wordmode = TRUE; print_stringptr = cmdbuf; print_stringlen = 300; ndprintf((FILE *)NULL,"%p\n",car(args)); *print_stringptr = '\0'; strm = popen(cmdbuf,"r"); fgets(cmdbuf,300,strm); while (!feof(strm)) { len = (int)strlen(cmdbuf); if (cmdbuf[len-1] == '\n') cmdbuf[--len] = '\0'; if (wordmode) this = make_strnode(cmdbuf, (struct string_block *)NULL, len, STRING, strnzcpy); else this = parser(make_static_strnode(cmdbuf), FALSE); if (head == NIL) { tail = head = cons(this,NIL); } else { setcdr(tail, cons(this,NIL)); tail = cdr(tail); } fgets(cmdbuf,300,strm); } pclose(strm); return(head); #endif #endif } ucblogo-5.5/error.c0100644000161300001330000002007710274572346012245 0ustar bhdoe/* * error.c logo error module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef mac #include #endif NODE *throw_node = NIL; NODE *err_mesg = NIL; ERR_TYPES erract_errtype; char *message_texts[MAX_MESSAGE+NUM_WORDS]; void err_print(char *buffer) { int save_flag = stopping_flag; int errtype; NODE *errargs, *oldfullp; FILE *fp; if (err_mesg == NIL) return; if (buffer == NULL) { fp = stdout; } else { if (writestream == NULL) lsetwrite(the_generation); /* setwrite [] */ print_stringptr = buffer; print_stringlen = 200; fp = NULL; } stopping_flag = RUN; oldfullp = valnode__caseobj(Fullprintp); setvalnode__caseobj(Fullprintp, TrueName()); errtype = getint(car(err_mesg)); errargs = cadr(err_mesg); force_printdepth = 5; force_printwidth = 80; if (errargs == NIL) ndprintf(fp, message_texts[errtype]); else if (cdr(errargs) == NIL) ndprintf(fp, message_texts[errtype], car(errargs)); else ndprintf(fp, message_texts[errtype], car(errargs), cadr(errargs)); if (car(cddr(err_mesg)) != NIL && buffer == NULL) { ndprintf(fp, message_texts[ERROR_IN], car(cddr(err_mesg)), cadr(cddr(err_mesg))); } err_mesg = NIL; if (buffer == NULL) new_line(fp); else *print_stringptr = '\0'; setvalnode__caseobj(Fullprintp, oldfullp); stopping_flag = save_flag; } NODE *err_logo(ERR_TYPES error_type, NODE *error_desc) { BOOLEAN recoverable = FALSE, warning = FALSE, uplevel = FALSE; NODE *err_act, *val = UNBOUND; switch(error_type) { case FATAL: prepare_to_exit(FALSE); ndprintf(stdout,"%t\n",message_texts[FATAL]); exit(1); case OUT_OF_MEM_UNREC: prepare_to_exit(FALSE); ndprintf(stdout,"%t\n",message_texts[OUT_OF_MEM_UNREC]); exit(1); case OUT_OF_MEM: use_reserve_tank(); break; case DIDNT_OUTPUT: if (didnt_output_name != NIL) { last_call = didnt_output_name; } if (error_desc == NIL) { error_desc = car(didnt_get_output); ufun = cadr(didnt_get_output); this_line = cadr(cdr(didnt_get_output)); } err_mesg = cons_list(0, last_call, error_desc, END_OF_LIST); recoverable = TRUE; break; case NOT_ENOUGH: if (error_desc == NIL) err_mesg = cons_list(0, fun, END_OF_LIST); else err_mesg = cons_list(0, error_desc, END_OF_LIST); break; case BAD_DATA: recoverable = TRUE; case BAD_DATA_UNREC: err_mesg = cons_list(0, fun, error_desc, END_OF_LIST); break; case DK_WHAT_UP: uplevel = TRUE; case DK_WHAT: err_mesg = cons_list(0, error_desc, END_OF_LIST); break; case DK_HOW: case APPLY_BAD_DATA: case NO_VALUE: recoverable = TRUE; case DK_HOW_UNREC: case NO_CATCH_TAG: case ALREADY_DEFINED: case FILE_ERROR: case IS_PRIM: case AT_TOPLEVEL: case ERR_MACRO: case DEEPEND: case BAD_DEFAULT: case TOO_MUCH: case CANT_OPEN_ERROR: case ALREADY_OPEN_ERROR: case NOT_OPEN_ERROR: err_mesg = cons_list(0, error_desc, END_OF_LIST); break; case SHADOW_WARN: err_mesg = cons_list(0, error_desc, END_OF_LIST); case IF_WARNING: warning = TRUE; break; case MISSING_SPACE: warning = TRUE; err_mesg = error_desc; break; case USER_ERR_MESSAGE: uplevel = TRUE; err_mesg = cons_list(0, error_desc, END_OF_LIST); break; case NO_TEST: err_mesg = cons_list(0, fun, END_OF_LIST); break; default: err_mesg = NIL; } didnt_output_name = NIL; if (uplevel && ufun != NIL) { ufun = last_ufun; this_line = last_line; } if (ufun != NIL) err_mesg = cons_list(0, err_mesg, ufun, this_line, END_OF_LIST); else err_mesg = cons_list(0, err_mesg, NIL, NIL, END_OF_LIST); err_mesg = cons(make_intnode((FIXNUM)error_type), err_mesg); if (warning) { err_print(NULL); return(UNBOUND); } err_act = valnode__caseobj(Erract); if (err_act != NIL && err_act != UNDEFINED) { if (error_type != erract_errtype) { erract_errtype = error_type; setvalnode__caseobj(Erract, NIL); val = err_eval_driver(err_act, recoverable); setvalnode__caseobj(Erract, err_act); if (recoverable == TRUE && val != UNBOUND) { return(val); } else if (recoverable == FALSE && val != UNBOUND) { ndprintf(stdout, message_texts[DK_WHAT], val); ndprintf(stdout, "\n"); val = UNBOUND; throw_node = theName(Name_toplevel); } else { /* if (err_mesg != NIL) */ { /* is this ever wrong? */ throw_node = theName(Name_error); stopping_flag = THROWING; output_node = UNBOUND; } return(UNBOUND); } } else { ndprintf(stdout,"%t\n", message_texts[ERRACT_LOOP]); throw_node = theName(Name_toplevel); } } else { /* no erract */ throw_node = theName(Name_error); } stopping_flag = THROWING; output_node = UNBOUND; return(val); } NODE *lerror(NODE *args) { NODE *val, *save_err = err_mesg; char buffer[200]; if (err_mesg == NIL) return NIL; err_print(buffer); err_mesg = save_err; setcar(cdr(err_mesg), make_strnode(buffer, (struct string_block *)NULL, strlen(buffer), STRING, strnzcpy)); val = err_mesg; err_mesg = NIL; return(val); } #ifndef HAVE_MEMCPY void memcpy(char *to, char *from, size_t len) { while (--len >= 0) *to++ = *from++; } #endif NODE *lpause(NODE *args) { NODE *elist = NIL, *val = UNBOUND, *uname = NIL; int sav_input_blocking; #ifndef TIOCSTI jmp_buf sav_iblk; #endif if (err_mesg != NIL) err_print(NULL); /* if (ufun != NIL) */ { uname = ufun; ndprintf(stdout, "%t\n", message_texts[PAUS_ING]); #ifndef TIOCSTI memcpy((char *)(&sav_iblk), (char *)(&iblk_buf), sizeof(jmp_buf)); #endif sav_input_blocking = input_blocking; input_blocking = 0; #ifdef mac csetmode(C_ECHO, stdin); fflush(stdin); #endif while (RUNNING) { if (uname != NIL) print_node(stdout, uname); elist = reader(stdin, "? "); if (NOT_THROWING) elist = parser(elist, TRUE); else elist = NIL; #ifndef WIN32 if (feof(stdin) && !isatty(0)) lbye(NIL); #endif #ifdef __RZTC__ if (feof(stdin)) rewind(stdin); #endif if (elist != NIL) eval_driver(elist); if (stopping_flag == THROWING) { if (compare_node(throw_node, Pause, TRUE) == 0) { val = output_node; output_node = UNBOUND; stopping_flag = RUN; #ifndef TIOCSTI memcpy((char *)(&iblk_buf), (char *)(&sav_iblk), sizeof(jmp_buf)); #endif input_blocking = sav_input_blocking; if (uname != NIL) { ufun = uname; } return(val); } else if (isName(throw_node, Name_error)) { err_print(NULL); stopping_flag = RUN; } } } #ifndef TIOCSTI memcpy((char *)(&iblk_buf), (char *)(&sav_iblk), sizeof(jmp_buf)); #endif input_blocking = sav_input_blocking; unblock_input(); if (uname != NIL) { ufun = uname; } /* } else { stopping_flag = THROWING; throw_node = theName(Name_toplevel); */ } return(val); } NODE *lcontinue(NODE *args) { stopping_flag = THROWING; throw_node = Pause; if (args != NIL) output_node = car(args); else output_node = UNBOUND; return(UNBOUND); } ucblogo-5.5/obj.c0100644000161300001330000003443007741104670011660 0ustar bhdoe/* * obj.c logo object functions module scc * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "logo.h" #include "globals.h" #ifdef OBJECTS NODE *logo_object, *current_object; NODE *name_arg(NODE *args); NODE *assoc(NODE *name, NODE *alist); FIXNUM gensymnum = 1; /* Creates new license plate for object */ NODE *newplate(void) { char buffer[20]; sprintf(buffer,"G%d", gensymnum++); return make_strnode(buffer, NULL, strlen(buffer), STRING, strnzcpy); return UNBOUND; } /* Creates a new object */ NODE *newobj(void) { NODE *result = newnode(OBJECT); NODE *binding = newnode(CONS); setcar(binding, theName(Name_licenseplate)); setobject(binding, newplate()); setvars(result, binding); return result; } /* Initializes Object Logo */ void obj_init(void) { logo_object = newobj(); current_object = logo_object; setvars(logo_object, cons(theName(Name_name), getvars(logo_object))); setobject(getvars(logo_object), make_static_strnode("Logo")); /* [[initlist] [exist output self]] */ askexist = cons(cons(theName(Name_initlist), NIL), cons(cons(theName(Name_exist), cons(theName(Name_output), cons(theName(Name_self), NIL))), NIL)); } /* Outputs the Logo object, ancestor of all other objects. * @params - none */ NODE *llogo(NODE *args) { return(logo_object); } /* Creates and outputs an object whose parent is the Logo object. * @params - none */ NODE *lsomething(NODE *args) { NODE *val; val = newobj(); setparents(val, cons(logo_object, NIL)); return val; } /* Creates and outputs an object, whose parent is Object, or whose parents * are Object1, Object2, etc., or the elements of ObjectList. * @params - Object or ObjectList or (Object1 Object2 etc.) */ NODE *lkindof(NODE *args) { NODE *argcopy = args; NODE *val = UNBOUND; if (is_list(car(args))) { if (cdr(args) != NIL) { err_logo(TOO_MUCH, NIL); /* too many inputs */ } args = car(args); } /* now args is always a list of objects */ /* make sure they're all really objects */ for (argcopy = args; (argcopy != NIL && NOT_THROWING); argcopy = cdr(argcopy)) { while (!is_object(car(argcopy)) && NOT_THROWING) { setcar(argcopy, err_logo(BAD_DATA, car(argcopy))); } } if (NOT_THROWING) { val = newobj(); setparents(val, args); } return val; } /* Creates an object whose parent is Object or whose parents are the elements * of ObjectList, Asks the new object to Exist, and then outputs the object. * Any remaining inputs after the first are collected into a list and made * the value of the public variable InitList, used to initialize the newly * created object. * @params - Object or ObjectList or (Object Input1 Input2 etc.) or * (ObjectList Input1 Input2 etc.) */ NODE *loneof(NODE *args) { NODE *val = UNBOUND, *argcopy; if (!is_list(car(args))) { setcar(args, cons(car(args), NIL)); } /* now the first arg is always a list of objects */ /* make sure they're really objects */ argcopy = car(args); while (argcopy != NIL && NOT_THROWING) { while (!is_object(car(argcopy)) && NOT_THROWING) { setcar(argcopy, err_logo(BAD_DATA, car(argcopy))); } argcopy = cdr(argcopy); } if (NOT_THROWING) { val = newobj(); setparents(val, car(args)); /* apply [[InitList] [Exist Output Self]] cdr(args) */ return make_cont(withobject_continuation, cons(val, make_cont(begin_apply, cons(askexist, cons(cons(cdr(args), NIL), NIL))))); } return val; } /* Each object will be given an Exist method by the user. * The global Exist does nothing at all. */ NODE *lexist(NODE *args) { return UNBOUND; } /* Creates the object variable named Symbol, or the object variables named , * SymbolList within the current object. * @params - Symbol or SymbolList */ NODE *lhave(NODE *args) { if (is_list(car(args))) { if (cdr(args) != NIL) { err_logo(TOO_MUCH, NIL); /* too many inputs */ } args = car(args); } /* now args is always a list of symbols. args should not equal to NIL because that is checked for before. */ while (args != NIL && NOT_THROWING) { NODE *sym = intern(car(args)); NODE *binding = assoc(sym, getvars(current_object)); if (binding == NIL) { setvars(current_object, cons(sym, getvars(current_object))); setobject(getvars(current_object), UNBOUND); } args = cdr(args); } return UNBOUND; } /* USUAL.FOO has to be recognized in paren.c as a reference to the FOO method in the parent(s), provided we are in the body of FOO, so that we know how many inputs it takes. Then in eval.c we have to look for the parent(s)' FOO method So there is no lusual() -- it's not a Logo primitive */ /* Changes to Object the object in which subsequent top level instruction will * be run until the next time TalkTo is run * @params - Object */ NODE *ltalkto(NODE *args) { while (!is_object(car(args)) && NOT_THROWING) setcar(args, err_logo(BAD_DATA, car(args))); if (NOT_THROWING) current_object = car(args); return UNBOUND; } /* Runs RunList, with Object as the current object for the duration of the * Ask. After RunList finishes, the current object reverts to what it was * before the Ask. * @params - Object RunList */ NODE *lask(NODE *args) { while (!is_object(car(args)) && NOT_THROWING) setcar(args, err_logo(BAD_DATA, car(args))); if (NOT_THROWING) { return make_cont(withobject_continuation, cons(car(args), make_cont(begin_seq, cadr(args)))); } return UNBOUND; } /* Outputs the current object (the object itself, not its name) * @params - none */ NODE *lself(NODE *args) { return current_object; } /* Outputs a list containing the parent(s) of the current Object. The Logo * Object has no parents. * @params - none */ NODE *lparents(NODE *args) { return getparents(current_object); } /* Outputs a list of the names of the object variables owned by (not * inherited by) the current object. * @params - none */ NODE *lmynames(NODE *args) { return getvars(current_object); } /* Outputs TRUE if Symbol is the name of an object variable owned by the * current object, FALSE otherwise. * @params - Symbol */ NODE *lmynamep(NODE *args) { NODE *arg; arg = name_arg(args); if (NOT_THROWING) { arg = intern(arg); if (current_object == logo_object) { return torf(flag__caseobj(arg, HAS_GLOBAL_VALUE)); } else return torf(assoc(arg, getvars(current_object)) != NIL); } return UNBOUND; } /* Outputs a list of the names of the procedures owned by (not inherited * by) the current object. * @params - none */ NODE *lmyprocs(NODE *args) { return getprocs(current_object); } /* Outputs TRUE if Symbol is the name of a procedure owned by the current * object, FALSE otherwise. * @params - Symbol */ NODE *lmyprocp(NODE *args) { NODE *arg; if (current_object == logo_object) return lprocedurep(args); /* return lprocp or just call it? */ else { arg = name_arg(args); if (NOT_THROWING) return torf(assoc(arg, getprocs(current_object)) != NIL); } return UNBOUND; } /* Outputs the object that owns the accessible variable named Symbol. If there * is no such accessible variable, or if it is not an object or global * variable, an error is signalled. * @params - Symbol */ /* to whosename :name if mynamep :name [output self] if equalp self Logo [(throw "error se [No accessible variable] :name)] output usual.whosename :name end */ /* Outputs the object that owns the accessible procedure named Symbol. If * there is no such accessible procedure, an error is signalled. * @params - Symbol */ /* to whoseproc :name if myprocp :name [output self] if equalp self Logo [(throw "error [No procedure named] :name)] output usual.whoseproc :name end */ /* Helper function */ NODE *assoc(NODE *name, NODE *alist) { while (alist != NIL) { if (compare_node(name, car(alist), TRUE) == 0) return alist; alist = cdr(alist); } return(NIL); } /* Looks up value in dynamic bindings and then in Object Hierarchy. If the * value is found in one place but not the other, then the value is * returned. Otherwise, an error is signalled. * @params - name */ NODE *varValue(NODE *name) { NODE *val; name = intern(name); val = valnode__caseobj(name); if ((val != UNBOUND) && flag__caseobj(name, IS_LOCAL_VALUE)) { if (varInObjectHierarchy(name, FALSE) != (NODE *)(-1)) { err_logo(LOCAL_AND_OBJ, name); return UNBOUND; } else { return val; /* local binding */ } } val = varInObjectHierarchy(name, TRUE); return((val == (NODE *)(-1)) ? UNBOUND : val); } /* Returns the value associated with name, depends on if the logo_object is * included in the hierarchy or not. */ NODE *varInObjectHierarchy(NODE *name, BOOLEAN includeLogo) { NODE *result, *parentList; result = assoc(name, getvars(current_object)); if (result != NIL) { return getobject(result); } for (parentList = parent_list(current_object); parentList != NIL; parentList = cdr(parentList)) { result = assoc(name, getvars(car(parentList))); if (result != NIL) { return getobject(result); } } if (!includeLogo) { return (NODE *)(-1); } result = intern(name); if (flag__caseobj(result, IS_LOCAL_VALUE)) { return (NODE *)(-1); } return valnode__caseobj(result); } /* Returns the object which contains the name, depends on if the * logo_object is included in the hierarchy or not. */ NODE *varInThisObject(NODE *name, BOOLEAN includeLogo) { NODE *object, *result, *parentList; result = assoc(name, getvars(current_object)); if (result != NIL) return current_object; for (parentList = parent_list(current_object); parentList != NIL && result == NIL; parentList = cdr(parentList)) { result = assoc(name, getvars(car(parentList))); object = car(parentList); if (result != NIL) return object; } if (!includeLogo) return NIL; result = intern(name); if (flag__caseobj(result, IS_LOCAL_VALUE)) return NIL; return logo_object; } /* Returns the procedure associated with name. */ NODE *procValue(NODE *name) { NODE *result, *parentList; result = assoc(name, getprocs(current_object)); if (result != NIL) return getobject(result); for (parentList = parent_list(current_object); parentList != NIL && result == NIL; parentList = cdr(parentList)) { result = assoc(name, getprocs(car(parentList))); } if (result != NIL) return getobject(result); result = intern(name); return procnode__caseobj(result); } /* (define (parent-list obj) (define (help obj) (let ((p (parents obj))) (if (null? p) (list obj) (cons obj (flatten (map parent-list p)))))) (remdup (cdr (help obj)))) */ extern NODE* remdup(NODE *seq); NODE *parent_list_help(NODE *obj) { NODE *p, *out, *tail; out = tail = cons(obj, NIL); for (p = getparents(obj); p != NIL; p = cdr(p)) { setcdr(tail, parent_list_help(car(p))); while (cdr(tail) != NIL) tail = cdr(tail); } return out; } NODE *parent_list(NODE *obj) { return remdup(cdr(parent_list_help(obj))); } /* (define (remdup seq) (cond ((null? seq) '()) ((memq (car seq) (cdr seq)) (remdup (cdr seq))) (else (cons (car seq) (remdup (cdr seq)))))) */ NODE* remdup(NODE *seq) { NODE* okay; if (seq == NIL) return seq; /* finds the first element of new seq list */ while (memq(car(seq), cdr(seq))) { seq = cdr(seq); } for (okay = seq; cdr(okay) != NIL; okay = cdr(okay)) { while (memq(cadr(okay), cddr(okay))) { setcdr(okay, cddr(okay)); } } return seq; } /* returns true if item is a member of list, returns false otherwise */ BOOLEAN memq(NODE *item, NODE *list) { while (list != NIL) { if (item == car(list)) return TRUE; list = cdr(list); } return FALSE; } /* representation of an object */ NODE *lrepresentation(NODE *args) { NODE *license, *binding, *classbind; char buffer[200]; print_stringlen = 200; print_stringptr = buffer; license = assoc(theName(Name_licenseplate), getvars(current_object)); ndprintf(NULL, "${Object %p", getobject(license)); binding = assoc(theName(Name_name), getvars(current_object)); if (binding != NIL && getobject(binding) != UNBOUND) { ndprintf(NULL, ": %p", getobject(binding)); } classbind = assoc(theName(Name_class), getvars(current_object)); if (classbind != NIL) { if (binding == NIL || getobject(binding) == UNBOUND) { ndprintf(NULL, ":"); }else { ndprintf(NULL, ","); } ndprintf(NULL, " the class %p", getobject(classbind)); } else { classbind = varInObjectHierarchy(theName(Name_class), FALSE); if (classbind != UNBOUND && classbind != (NODE *)(-1)) { if (binding == NIL) { ndprintf(NULL, ":"); } else { ndprintf(NULL, ","); } ndprintf(NULL, " a %p", classbind); } } ndprintf(NULL, "}"); return make_strnode(buffer, NULL, strlen(buffer), STRING, strnzcpy); } #endif ucblogo-5.5/files.c0100644000161300001330000004035310274573162012212 0ustar bhdoe/* * files.c logo file management module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef WIN32 #include #endif /* WIN32 */ #include "logo.h" #include "globals.h" #ifdef HAVE_WX #define getc getFromWX_2 #endif #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef mac #include #endif #ifdef ibm #ifndef _MSC_VER #include #ifndef __RZTC__ #include #endif /* ZTC */ #endif /* MSC_VER */ extern int getch(), kbhit(); #ifdef __RZTC__ #include #endif #endif NODE *file_list = NULL; NODE *reader_name = NIL, *writer_name = NIL, *file_prefix = NIL; char *asciiz(NODE *arg) { char *out = (char *)malloc(getstrlen(arg)+1); return noparity_strnzcpy(out, getstrptr(arg), getstrlen(arg)); } NODE *lseteditor(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else { editor = asciiz(arg); editorname = strrchr(editor, (int)'/'); if (editorname == NULL) editorname = strrchr(editor, (int)'\\'); if (editorname == NULL) editorname = strrchr(editor, (int)':'); editorname = (editorname ? editorname+1 : editor); } return UNBOUND; } NODE *lsetlibloc(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else logolib = asciiz(arg); return UNBOUND; } NODE *lsethelploc(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else helpfiles = asciiz(arg); return UNBOUND; } NODE *lsetcslsloc(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else csls = asciiz(arg); return UNBOUND; } NODE *lsettemploc(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else tempdir = asciiz(arg); return UNBOUND; } NODE *lsetprefix(NODE *args) { NODE *arg; if (car(args) == NIL) file_prefix = NIL; else { arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else file_prefix = arg; } return UNBOUND; } NODE *lprefix(NODE *args) { return file_prefix; } FILE *open_file(NODE *arg, char *access) { char *fnstr; FILE *tstrm; if (is_list(arg)) { /* print to string */ if (*access != 'w') { err_logo(BAD_DATA_UNREC, arg); return NULL; } else { FIXNUM i = int_arg(cdr(arg)); if (NOT_THROWING && i > 0 && cddr(arg) == NIL) { char *tmp = (char *)malloc(i); *tmp = '\0'; return (FILE *)tmp; } err_logo(BAD_DATA_UNREC, car(arg)); return NULL; } } arg = cnv_node_to_strnode(arg); if (arg == UNBOUND) return(NULL); if (file_prefix != NIL) { print_stringlen = getstrlen(file_prefix) + getstrlen(arg) + 2; fnstr = (char *)malloc((size_t)print_stringlen + 1); } else fnstr = (char *) malloc((size_t)getstrlen(arg) + 1); if (fnstr == NULL) { err_logo(FILE_ERROR, make_static_strnode(message_texts[MEM_LOW])); return NULL; } if (file_prefix != NIL) { print_stringptr = fnstr; ndprintf((FILE *)NULL, "%p%t%p", file_prefix, separator, arg); *print_stringptr = '\0'; } else noparity_strnzcpy(fnstr, getstrptr(arg), getstrlen(arg)); tstrm = fopen(fnstr, access); free(fnstr); return(tstrm); } NODE *ldribble(NODE *arg) { if (dribblestream != NULL) err_logo(ALREADY_DRIBBLING, NIL); else { dribblestream = open_file(car(arg), "w+"); if (dribblestream == NULL) err_logo(CANT_OPEN_ERROR, car(arg)); } return(UNBOUND); } NODE *lnodribble(NODE *args) { if (dribblestream != NULL) { fclose(dribblestream); dribblestream = NULL; } return(UNBOUND); } FILE *find_file(NODE *arg, BOOLEAN remove) { NODE *t, *prev = NIL; FILE *fp = NULL; t = file_list; while (t != NIL) { if ((is_list(arg) && arg == car(t)) || (!is_list(arg) && (compare_node(arg, car(t), FALSE) == 0))) { fp = (FILE *)t->n_obj; if (remove) { t->n_obj = NIL; if (prev == NIL) file_list = cdr(t); else setcdr(prev, cdr(t)); } break; } prev = t; t = cdr(t); } return fp; } NODE *lopen(NODE *arg, char *mode) { FILE *tmp; arg = car(arg); if (find_file(arg, FALSE) != NULL) err_logo(ALREADY_OPEN_ERROR, arg); else if ((tmp = open_file(arg, mode)) != NULL) { push(arg, file_list); file_list->n_obj = (NODE *)tmp; } else err_logo(CANT_OPEN_ERROR, arg); return(UNBOUND); } NODE *lopenread(NODE *arg) { return(lopen(arg,"r")); } NODE *lopenwrite(NODE *arg) { return(lopen(arg,"w")); } NODE *lopenappend(NODE *arg) { return(lopen(arg,"a")); } NODE *lopenupdate(NODE *arg) { return(lopen(arg,"a+")); } NODE *lallopen(NODE *args) { return(file_list); } NODE *lclose(NODE *arg) { FILE *tmp; NODE *margs; if ((tmp = find_file(car(arg), TRUE)) == NULL) err_logo(NOT_OPEN_ERROR, car(arg)); else if (is_list (car(arg))) { margs = cons(caar(arg), cons(make_strnode((char *)tmp, NULL, strlen((char *)tmp), STRING, strnzcpy), NIL)); lmake(margs); free((char *)tmp); } else fclose(tmp); if ((is_list(car(arg)) && car(arg) == writer_name) || (!is_list(car(arg)) && (compare_node(car(arg), writer_name, FALSE) == 0))) { writer_name = NIL; writestream = stdout; } if ((is_list(car(arg)) && car(arg) == reader_name) || (!is_list(car(arg)) && (compare_node(car(arg), reader_name, FALSE) == 0))) { reader_name = NIL; readstream = stdin; } return(UNBOUND); } char *write_buf = 0; NODE *lsetwrite(NODE *arg) { FILE *tmp; NODE *margs; if (writestream == NULL) { /* Any setwrite finishes earlier write to string */ *print_stringptr = '\0'; writestream = stdout; if (find_file(writer_name, FALSE) == NULL) { /* pre-5.4 compatibility mode, implicitly close string */ margs = cons(car(writer_name), cons(make_strnode(write_buf, NULL, strlen(write_buf), STRING, strnzcpy), NIL)); lmake(margs); free(write_buf); } writer_name = NIL; } if (car(arg) == NIL) { writestream = stdout; writer_name = NIL; } else if (is_list(car(arg))) { /* print to string */ FIXNUM i = int_arg(cdar(arg)); if ((tmp = find_file(car(arg), FALSE)) != NULL) { writestream = NULL; writer_name = car(arg); print_stringptr = (char *)tmp + strlen((char *)tmp); print_stringlen = i - strlen((char *)tmp); } else if (NOT_THROWING && i > 0 && cddr(car(arg)) == NIL) { writestream = NULL; writer_name = copy_list(car(arg)); print_stringptr = write_buf = (char *)malloc(i); print_stringlen = i; } else err_logo(BAD_DATA_UNREC, car(arg)); } else if ((tmp = find_file(car(arg), FALSE)) != NULL) { writestream = tmp; writer_name = car(arg); } else err_logo(NOT_OPEN_ERROR, car(arg)); return(UNBOUND); } NODE *lsetread(NODE *arg) { FILE *tmp; if (car(arg) == NIL) { readstream = stdin; reader_name = NIL; } else if ((tmp = find_file(car(arg), FALSE)) != NULL) { readstream = tmp; reader_name = car(arg); } else err_logo(NOT_OPEN_ERROR, car(arg)); return(UNBOUND); } NODE *lreader(NODE *args) { return(reader_name); } NODE *lwriter(NODE *args) { return(writer_name); } NODE *lerasefile(NODE *arg) { char *fnstr; arg = cnv_node_to_strnode(car(arg)); if (arg == UNBOUND) return(UNBOUND); fnstr = malloc((size_t)getstrlen(arg) + 1); if (fnstr == NULL) { err_logo(FILE_ERROR, make_static_strnode(message_texts[MEM_LOW])); return UNBOUND; } strnzcpy(fnstr, getstrptr(arg), getstrlen(arg)); unlink(fnstr); free(fnstr); return(UNBOUND); } NODE *lsave(NODE *arg) { FILE *tmp; tmp = writestream; writestream = open_file(car(arg), "w+"); if (writestream != NULL) { setcar(arg, cons(lcontents(NIL), NIL)); lpo(car(arg)); fclose(writestream); } else err_logo(CANT_OPEN_ERROR, car(arg)); writestream = tmp; return(UNBOUND); } void runstartup(NODE *oldst) { NODE *st; st = valnode__caseobj(Startup); if (st != oldst && st != NIL && is_list(st)) { eval_driver(st); } } void silent_load(NODE *arg, char *prefix) { FILE *tmp_stream; NODE *tmp_line, *exec_list; char load_path[200]; NODE *st = valnode__caseobj(Startup); /* This procedure is called three ways: * silent_load(NIL,*argv) loads *argv * silent_load(proc,logolib) loads logolib/proc * silent_load(proc,NULL) loads proc.lg * The "/" or ".lg" is supplied by this procedure as needed. */ /* [This is no longer true! But for Windows we change FOO? to FOOQ.] * In the case that this procedure is called to load a procedure from the * logo library, it must first truncate the name of the procedure to * eight characters, to find the filename (so as to be compatible with * MS-DOS) */ if (prefix == NULL && arg == NIL) return; strcpy(load_path, (prefix == NULL ? "" : (arg == NIL ? prefix : addsep(prefix)))); if (arg != NIL) { arg = cnv_node_to_strnode(arg); if (arg == UNBOUND) return; if (!strncmp(getstrptr(arg), ".", getstrlen(arg))) return; noparitylow_strnzcpy(load_path + (int)strlen(load_path), getstrptr(arg), getstrlen(arg)); if (prefix == NULL) strcat(load_path, ".lg"); #ifdef WIN32 else if (arg != NIL) { char *cp; for (cp = load_path; *cp != '\0'; cp++) if (*cp == '?') *cp = 'Q'; } /* strcpy(load_path, eight_dot_three(load_path)); */ #endif } tmp_stream = loadstream; tmp_line = current_line; loadstream = fopen(load_path, "r"); if (loadstream != NULL) { while (!(feof(loadstream)) && NOT_THROWING) { current_line = reader(loadstream, ""); exec_list =parser(current_line, TRUE); if (exec_list != NIL) eval_driver(exec_list); } fclose(loadstream); runstartup(st); } else if (arg == NIL || prefix == csls) err_logo(CANT_OPEN_ERROR, make_strnode(load_path, NULL, strlen(load_path), STRING, strnzcpy)); loadstream = tmp_stream; current_line = tmp_line; } NODE *lcslsload(NODE *arg) { NODE *save_prefix = file_prefix; file_prefix = NIL; silent_load(car(arg),csls); file_prefix = save_prefix; return UNBOUND; } NODE *lload(NODE *arg) { FILE *tmp; NODE *tmp_line, *exec_list; NODE *st = valnode__caseobj(Startup); tmp = loadstream; tmp_line = current_line; loadstream = open_file(car(arg), "r"); if (loadstream != NULL) { while (!(feof(loadstream)) && NOT_THROWING) { current_line = reader(loadstream, ""); exec_list = parser(current_line, TRUE); if (exec_list != NIL) eval_driver(exec_list); } fclose(loadstream); runstartup(st); } else err_logo(CANT_OPEN_ERROR, car(arg)); loadstream = tmp; current_line = tmp_line; return(UNBOUND); } NODE *lreadlist(NODE *args) { NODE *val; val = parser(reader(readstream, ""), FALSE); if (feof(readstream)) { return(Null_Word); } return(val); } NODE *lreadword(NODE *args) { NODE *val; val = reader(readstream, "RW"); /* fake prompt flags no auto-continue */ if (feof(readstream)) { return(NIL); } return(val); } NODE *lreadrawline(NODE *args) { NODE *val; val = reader(readstream, "RAW"); /* fake prompt flags no specials */ if (feof(readstream)) { return(NIL); } return(val); } NODE *lreadchar(NODE *args) { #ifdef WIN32 MSG msg; #endif /* WIN32 */ char c; charmode_on(); input_blocking++; #ifndef TIOCSTI if (!setjmp(iblk_buf)) #endif { #ifdef mac csetmode(C_RAW, stdin); while ((c = (char)getc(readstream)) == EOF && readstream == stdin); csetmode(C_ECHO, stdin); #else /* !mac */ #ifdef ibm if (interactive && readstream==stdin) #ifndef WIN32 c = (char)getch(); #else /* WIN32 */ { win32_update_text(); if (!char_avail) while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); if (char_avail) break; } c = buffered_char; char_avail = 0; } #endif /* WIN32 */ else c = (char)getc(readstream); if (c == 17) { /* control-q */ to_pending = 0; err_logo(STOP_ERROR,NIL); } if (c == 23) { /* control-w */ #ifdef SIG_TAKES_ARG logo_pause(0); #else logo_pause(); #endif return(lreadchar(NIL)); } #else /* !ibm */ c = (char)getc(readstream); #endif /* ibm */ #endif /* mac */ } input_blocking = 0; if (feof(readstream)) { return(NIL); } return(make_strnode((char *)&c, (struct string_block *)NULL, 1, (getparity(c) ? BACKSLASH_STRING : STRING), strnzcpy)); } NODE *lreadchars(NODE *args) { unsigned int c, i; struct string_block *strhead = NULL; char *strptr= NULL; NODETYPES type = STRING; c = (unsigned int)getint(pos_int_arg(args)); if (stopping_flag == THROWING) return UNBOUND; charmode_on(); input_blocking++; #ifndef TIOCSTI if (!setjmp(iblk_buf)) #endif { strhead = malloc((size_t)(c + sizeof(FIXNUM) + 1)); if (strhead == NULL) { err_logo(FILE_ERROR, make_static_strnode(message_texts[MEM_LOW])); return UNBOUND; } strptr = strhead->str_str; c = (unsigned int)fread(strptr, 1, (size_t)c, readstream); setstrrefcnt(strhead, 0); } input_blocking = 0; #ifndef TIOCSTI if (stopping_flag == THROWING) return(UNBOUND); #endif if (c <= 0) { free(strhead); return(NIL); } for (i = 0; i < c; i++) if (getparity(strptr[i])) type = BACKSLASH_STRING; return(make_strnode(strptr, strhead, (int)c, type, strnzcpy)); } NODE *leofp(NODE *args) { int c; c = getc(readstream); if (c == EOF) return(TrueName()); ungetc(c,readstream); return(FalseName()); } NODE *lkeyp(NODE *args) { #ifdef unix long nc; #endif int c; #ifdef WIN32 MSG msg; int old_mode; #endif if (readstream == stdin && interactive) { charmode_on(); fflush(stdout); #if defined(__RZTC__) && !defined(WIN32) /* sowings */ zflush(); #endif #ifdef WIN32 win32_update_text(); #endif #if defined(mac) csetmode(C_RAW, stdin); c = ungetc(getc(readstream), readstream); csetmode(C_ECHO, stdin); return(c == EOF ? FalseName() : TrueName()); #elif defined(ibm) #ifdef WIN32 old_mode = char_mode; char_mode = 1; while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if (char_avail/* ||cur_index */ ) break; } char_mode = old_mode; return ((char_avail /* ||cur_index */ ) ? TrueName() : FalseName()); #else return(kbhit() ? TrueName() : FalseName()); #endif #else #ifdef FIONREAD ioctl(0,FIONREAD,(char *)(&nc)); #else ndprintf(stdout, "%t\n", message_texts[NO_FIONREAD]); nc = 1; /* pretend there's a char so we don't loop */ #endif if (nc > 0) return(TrueName()); else return(FalseName()); #endif } c = getc(readstream); if (feof(readstream)) return(FalseName()); else { ungetc(c, readstream); return(TrueName()); } } NODE *lreadpos(NODE *args) { return(make_intnode(ftell(readstream))); } NODE *lsetreadpos(NODE *arg) { NODE *val = pos_int_arg(arg); if (NOT_THROWING) { fseek(readstream,getint(val),0); } return(UNBOUND); } NODE *lwritepos(NODE *args) { return(make_intnode(ftell(writestream))); } NODE *lsetwritepos(NODE *arg) { NODE *val = pos_int_arg(arg); if (NOT_THROWING) { fseek(writestream,getint(val),0); } return(UNBOUND); } ucblogo-5.5/init.c0100644000161300001330000007167710275756203012070 0ustar bhdoe/* * init.c logo init module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef WIN32 #include #endif #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" #include #include typedef struct priminfo { char *name; short minargs; short defargs; short maxargs; short priority; NODE *(*prim) (); } PRIMTYPE; NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit, *Printwidthlimit, *Pause, *LoadNoisily, *AllowGetSet, *UnburyOnEdit, *Fullprintp, *Make, *Listvalue, *Dotsvalue, *Unbound, *Not_Enough_Node, *Buttonact, *LogoVersion, *LogoPlatform, *LogoLogo, #ifdef OBJECTS *askexist, #endif *Minus_Sign, *Minus_Tight, *Startup, *Query, *UseAlternateNames; NODE *Null_Word = NIL; PRIMTYPE prims[] = { {"*", 1, 1, 1, PREFIX_PRIORITY + 3, lmul}, {"+", 1, 1, 1, PREFIX_PRIORITY + 2, ladd}, {"-", 1, 1, 1, PREFIX_PRIORITY + 2, lsub}, {"--", 1, 1, 1, PREFIX_PRIORITY + 4, lsub}, {".defmacro", 2, 2, 2, PREFIX_PRIORITY, ldefmacro}, {".eq", 2, 2, 2, PREFIX_PRIORITY, l_eq}, {".macro", -1, -1, -1, PREFIX_PRIORITY, lmacro}, {".maybeoutput", 1, 1, 1, MAYBE_PRIORITY, loutput}, {".setbf", 2, 2, 2, PREFIX_PRIORITY, l_setbf}, {".setfirst", 2, 2, 2, PREFIX_PRIORITY, l_setfirst}, {".setitem", 3, 3, 3, PREFIX_PRIORITY, l_setitem}, {".setsegmentsize", 1, 1, 1, PREFIX_PRIORITY, lsetsegsz}, {"/", 1, 1, 1, PREFIX_PRIORITY + 3, ldivide}, {"<", 2, 2, 2, PREFIX_PRIORITY + 1, llessp}, {"=", 2, 2, 2, PREFIX_PRIORITY + 1, lequalp}, {">", 2, 2, 2, PREFIX_PRIORITY + 1, lgreaterp}, {"<=", 2, 2, 2, PREFIX_PRIORITY + 1, llessequalp}, {"<>", 2, 2, 2, PREFIX_PRIORITY + 1, lnotequalp}, {">=", 2, 2, 2, PREFIX_PRIORITY + 1, lgreaterequalp}, {"?", 0, 0, 1, PREFIX_PRIORITY, lqm}, {"allopen", 0, 0, 0, PREFIX_PRIORITY, lallopen}, {"and", 0, 2, -1, PREFIX_PRIORITY, land}, {"apply", 2, 2, 2, MACRO_PRIORITY, lapply}, {"arc", 2, 2, 2, PREFIX_PRIORITY, larc}, {"arctan", 1, 1, 2, PREFIX_PRIORITY, latan}, {"arity", 1, 1, 1, PREFIX_PRIORITY, larity}, {"array", 1, 1, 2, PREFIX_PRIORITY, larray}, {"arrayp", 1, 1, 1, PREFIX_PRIORITY, larrayp}, {"arraytolist", 1, 1, 1, PREFIX_PRIORITY, larraytolist}, {"array?", 1, 1, 1, PREFIX_PRIORITY, larrayp}, {"ascii", 1, 1, 1, PREFIX_PRIORITY, lascii}, {"ashift", 2, 2, 2, PREFIX_PRIORITY, lashift}, #ifdef OBJECTS {"ask", 2, 2, 2, MACRO_PRIORITY, lask}, #endif {"back", 1, 1, 1, PREFIX_PRIORITY, lback}, {"background", 0, 0, 0, PREFIX_PRIORITY, lbackground}, {"backslashedp", 1, 1, 1, PREFIX_PRIORITY, lbackslashedp}, {"backslashed?", 1, 1, 1, PREFIX_PRIORITY, lbackslashedp}, {"beforep", 2, 2, 2, PREFIX_PRIORITY, lbeforep}, {"before?", 2, 2, 2, PREFIX_PRIORITY, lbeforep}, {"bf", 1, 1, 1, PREFIX_PRIORITY, lbutfirst}, {"bfs", 1, 1, 1, PREFIX_PRIORITY, lbfs}, {"bg", 0, 0, 0, PREFIX_PRIORITY, lbackground}, {"bitand", 0, 2, -1, PREFIX_PRIORITY, lbitand}, {"bitnot", 1, 1, 1, PREFIX_PRIORITY, lbitnot}, {"bitor", 0, 2, -1, PREFIX_PRIORITY, lbitor}, {"bitxor", 0, 2, -1, PREFIX_PRIORITY, lbitxor}, {"bk", 1, 1, 1, PREFIX_PRIORITY, lback}, {"bl", 1, 1, 1, PREFIX_PRIORITY, lbutlast}, {"buried", 0, 0, 0, PREFIX_PRIORITY, lburied}, {"buriedp", 1, 1, 1, PREFIX_PRIORITY, lburiedp}, {"buried?", 1, 1, 1, PREFIX_PRIORITY, lburiedp}, {"bury", 1, 1, 1, PREFIX_PRIORITY, lbury}, {"butfirst", 1, 1, 1, PREFIX_PRIORITY, lbutfirst}, {"butfirsts", 1, 1, 1, PREFIX_PRIORITY, lbfs}, {"butlast", 1, 1, 1, PREFIX_PRIORITY, lbutlast}, {"button", 0, 0, 0, PREFIX_PRIORITY, lbutton}, {"buttonp", 0, 0, 0, PREFIX_PRIORITY, lbuttonp}, {"button?", 0, 0, 0, PREFIX_PRIORITY, lbuttonp}, {"bye", 0, 0, 0, PREFIX_PRIORITY, lbye}, {"catch", 2, 2, 2, MACRO_PRIORITY, lcatch}, {"char", 1, 1, 1, PREFIX_PRIORITY, lchar}, {"clean", 0, 0, 0, PREFIX_PRIORITY, lclean}, {"clearscreen", 0, 0, 0, PREFIX_PRIORITY, lclearscreen}, {"cleartext", 0, 0, 0, PREFIX_PRIORITY, lcleartext}, {"close", 1, 1, 1, PREFIX_PRIORITY, lclose}, {"co", OK_NO_ARG, 1, 1, PREFIX_PRIORITY, lcontinue}, {"contents", 0, 0, 0, PREFIX_PRIORITY, lcontents}, {"continue", OK_NO_ARG, 1, 1, PREFIX_PRIORITY, lcontinue}, {"copydef", 2, 2, 2, PREFIX_PRIORITY, lcopydef}, {"cos", 1, 1, 1, PREFIX_PRIORITY, lcos}, {"count", 1, 1, 1, PREFIX_PRIORITY, lcount}, {"cs", 0, 0, 0, PREFIX_PRIORITY, lclearscreen}, {"cslsload", 1, 1, 1, PREFIX_PRIORITY, lcslsload}, {"ct", 0, 0, 0, PREFIX_PRIORITY, lcleartext}, {"cursor", 0, 0, 0, PREFIX_PRIORITY, lcursor}, {"define", 2, 2, 2, PREFIX_PRIORITY, ldefine}, {"definedp", 1, 1, 1, PREFIX_PRIORITY, ldefinedp}, {"defined?", 1, 1, 1, PREFIX_PRIORITY, ldefinedp}, {"difference", 2, 2, 2, PREFIX_PRIORITY, lsub}, {"dribble", 1, 1, 1, PREFIX_PRIORITY, ldribble}, {"ed", OK_NO_ARG, 1, 1, PREFIX_PRIORITY, ledit}, {"edit", OK_NO_ARG, 1, 1, PREFIX_PRIORITY, ledit}, {"editfile", 1, 1, 1, PREFIX_PRIORITY, leditfile}, {"emptyp", 1, 1, 1, PREFIX_PRIORITY, lemptyp}, {"empty?", 1, 1, 1, PREFIX_PRIORITY, lemptyp}, {"eofp", 0, 0, 0, PREFIX_PRIORITY, leofp}, {"eof?", 0, 0, 0, PREFIX_PRIORITY, leofp}, {"epspict", 1, 1, 1, PREFIX_PRIORITY, lepspict}, {"equalp", 2, 2, 2, PREFIX_PRIORITY, lequalp}, {"equal?", 2, 2, 2, PREFIX_PRIORITY, lequalp}, {"er", 1, 1, 1, PREFIX_PRIORITY, lerase}, {"erall", 0, 0, 0, PREFIX_PRIORITY, lerall}, {"erase", 1, 1, 1, PREFIX_PRIORITY, lerase}, {"erasefile", 1, 1, 1, PREFIX_PRIORITY, lerasefile}, {"erf", 1, 1, 1, PREFIX_PRIORITY, lerasefile}, {"erns", 0, 0, 0, PREFIX_PRIORITY, lerns}, {"erpls", 0, 0, 0, PREFIX_PRIORITY, lerpls}, {"erps", 0, 0, 0, PREFIX_PRIORITY, lerps}, {"error", 0, 0, 0, PREFIX_PRIORITY, lerror}, #ifdef OBJECTS {"lexist", 0, 0, 0, PREFIX_PRIORITY, lexist}, #endif {"exp", 1, 1, 1, PREFIX_PRIORITY, lexp}, {"fd", 1, 1, 1, PREFIX_PRIORITY, lforward}, {"fence", 0, 0, 0, PREFIX_PRIORITY, lfence}, {"fill", 0, 0, 0, PREFIX_PRIORITY, lfill}, {"first", 1, 1, 1, PREFIX_PRIORITY, lfirst}, {"firsts", 1, 1, 1, PREFIX_PRIORITY, lfirsts}, {"forever", 1, 1, 1, MACRO_PRIORITY, lforever}, {"form", 3, 3, 3, PREFIX_PRIORITY, lform}, {"forward", 1, 1, 1, PREFIX_PRIORITY, lforward}, {"fput", 2, 2, 2, PREFIX_PRIORITY, lfput}, {"fs", 0, 0, 0, PREFIX_PRIORITY, lfullscreen}, {"fullscreen", 0, 0, 0, PREFIX_PRIORITY, lfullscreen}, {"fulltext", 1, 1, 1, PREFIX_PRIORITY, lfulltext}, {"gc", 0, 0, 1, PREFIX_PRIORITY, lgc}, {"global", 1, 1, -1, PREFIX_PRIORITY, lglobal}, {"goto", 1, 1, 1, MACRO_PRIORITY, lgoto}, {"gprop", 2, 2, 2, PREFIX_PRIORITY, lgprop}, {"greaterp", 2, 2, 2, PREFIX_PRIORITY, lgreaterp}, {"greater?", 2, 2, 2, PREFIX_PRIORITY, lgreaterp}, {"greaterequalp", 2, 2, 2, PREFIX_PRIORITY, lgreaterequalp}, {"greaterequal?", 2, 2, 2, PREFIX_PRIORITY, lgreaterequalp}, #ifdef OBJECTS {"have", 1, 1, 1, PREFIX_PRIORITY, lhave}, #endif {"heading", 0, 0, 0, PREFIX_PRIORITY, lheading}, {"help", OK_NO_ARG, 1, 1, PREFIX_PRIORITY, lhelp}, {"hideturtle", 0, 0, 0, PREFIX_PRIORITY, lhideturtle}, {"home", 0, 0, 0, PREFIX_PRIORITY, lhome}, {"ht", 0, 0, 0, PREFIX_PRIORITY, lhideturtle}, {"if", 2, 2, 3, MACRO_PRIORITY, lif}, {"ifelse", 3, 3, 3, MACRO_PRIORITY, lifelse}, {"iff", 1, 1, 1, MACRO_PRIORITY, liffalse}, {"iffalse", 1, 1, 1, MACRO_PRIORITY, liffalse}, {"ift", 1, 1, 1, MACRO_PRIORITY, liftrue}, {"iftrue", 1, 1, 1, MACRO_PRIORITY, liftrue}, {"int", 1, 1, 1, PREFIX_PRIORITY, linteg}, {"item", 2, 2, 2, PREFIX_PRIORITY, litem}, {"keyp", 0, 0, 0, PREFIX_PRIORITY, lkeyp}, {"key?", 0, 0, 0, PREFIX_PRIORITY, lkeyp}, #ifdef OBJECTS {"kindof", 1, 1, -1, PREFIX_PRIORITY, lkindof}, #endif {"label", 1, 1, 1, PREFIX_PRIORITY, llabel}, {"last", 1, 1, 1, PREFIX_PRIORITY, llast}, {"left", 1, 1, 1, PREFIX_PRIORITY, lleft}, {"lessp", 2, 2, 2, PREFIX_PRIORITY, llessp}, {"less?", 2, 2, 2, PREFIX_PRIORITY, llessp}, {"lessequalp", 2, 2, 2, PREFIX_PRIORITY, llessequalp}, {"lessequal?", 2, 2, 2, PREFIX_PRIORITY, llessequalp}, {"list", 0, 2, -1, PREFIX_PRIORITY, llist}, {"listp", 1, 1, 1, PREFIX_PRIORITY, llistp}, {"listtoarray", 1, 1, 2, PREFIX_PRIORITY, llisttoarray}, {"list?", 1, 1, 1, PREFIX_PRIORITY, llistp}, {"ln", 1, 1, 1, PREFIX_PRIORITY, lln}, {"load", 1, 1, 1, PREFIX_PRIORITY, lload}, {"loadpict", 1, 1, 1, PREFIX_PRIORITY, lloadpict}, {"local", 1, 1, -1, PREFIX_PRIORITY, llocal}, {"log10", 1, 1, 1, PREFIX_PRIORITY, llog10}, #ifdef OBJECTS {"logo", 0, 0, 0, PREFIX_PRIORITY, llogo}, #endif {"lowercase", 1, 1, 1, PREFIX_PRIORITY, llowercase}, {"lput", 2, 2, 2, PREFIX_PRIORITY, llput}, {"lshift", 2, 2, 2, PREFIX_PRIORITY, llshift}, {"lt", 1, 1, 1, PREFIX_PRIORITY, lleft}, {"macrop", 1, 1, 1, PREFIX_PRIORITY, lmacrop}, {"macro?", 1, 1, 1, PREFIX_PRIORITY, lmacrop}, {"make", 2, 2, 2, PREFIX_PRIORITY, lmake}, #if defined(WIN32) {"maximize.window", 1, 1, 1, PREFIX_PRIORITY, maximize}, #endif {"member", 2, 2, 2, PREFIX_PRIORITY, lmember}, {"memberp", 2, 2, 2, PREFIX_PRIORITY, lmemberp}, {"member?", 2, 2, 2, PREFIX_PRIORITY, lmemberp}, {"minus", 1, 1, 1, PREFIX_PRIORITY, lsub}, {"modulo", 2, 2, 2, PREFIX_PRIORITY, lmodulo}, {"mousepos", 0, 0, 0, PREFIX_PRIORITY, lmousepos}, #ifdef OBJECTS {"mynamep", 1, 1, 1, PREFIX_PRIORITY, lmynamep}, {"mynames", 0, 0, 0, PREFIX_PRIORITY, lmynames}, {"myprocp", 1, 1, 1, PREFIX_PRIORITY, lmyprocp}, {"myprocs", 0, 0, 0, PREFIX_PRIORITY, lmyprocs}, #endif {"namep", 1, 1, 1, PREFIX_PRIORITY, lnamep}, {"name?", 1, 1, 1, PREFIX_PRIORITY, lnamep}, {"names", 0, 0, 0, PREFIX_PRIORITY, lnames}, {"nodes", 0, 0, 0, PREFIX_PRIORITY, lnodes}, {"nodribble", 0, 0, 0, PREFIX_PRIORITY, lnodribble}, {"norefresh", 0, 0, 0, PREFIX_PRIORITY, lnorefresh}, {"not", 1, 1, 1, PREFIX_PRIORITY, lnot}, {"notequalp", 2, 2, 2, PREFIX_PRIORITY, lnotequalp}, {"notequal?", 2, 2, 2, PREFIX_PRIORITY, lnotequalp}, {"numberp", 1, 1, 1, PREFIX_PRIORITY, lnumberp}, {"number?", 1, 1, 1, PREFIX_PRIORITY, lnumberp}, #ifdef OBJECTS {"oneof", 1, 1, -1, MACRO_PRIORITY, loneof}, #endif {"op", 1, 1, 1, OUTPUT_PRIORITY, loutput}, {"openappend", 1, 1, 1, PREFIX_PRIORITY, lopenappend}, {"openread", 1, 1, 1, PREFIX_PRIORITY, lopenread}, {"openupdate", 1, 1, 1, PREFIX_PRIORITY, lopenupdate}, {"openwrite", 1, 1, 1, PREFIX_PRIORITY, lopenwrite}, {"or", 0, 2, -1, PREFIX_PRIORITY, lor}, {"output", 1, 1, 1, OUTPUT_PRIORITY, loutput}, {"palette", 1, 1, 1, PREFIX_PRIORITY, lpalette}, #ifdef OBJECTS {"parents", 0, 0, 0, PREFIX_PRIORITY, lparents}, #endif {"parse", 1, 1, 1, PREFIX_PRIORITY, lparse}, {"pause", 0, 0, 0, PREFIX_PRIORITY, lpause}, {"pc", 0, 0, 0, PREFIX_PRIORITY, lpencolor}, {"pd", 0, 0, 0, PREFIX_PRIORITY, lpendown}, {"pe", 0, 0, 0, PREFIX_PRIORITY, lpenerase}, {"pencolor", 0, 0, 0, PREFIX_PRIORITY, lpencolor}, {"pendown", 0, 0, 0, PREFIX_PRIORITY, lpendown}, {"pendownp", 0, 0, 0, PREFIX_PRIORITY, lpendownp}, {"pendown?", 0, 0, 0, PREFIX_PRIORITY, lpendownp}, {"penerase", 0, 0, 0, PREFIX_PRIORITY, lpenerase}, {"penmode", 0, 0, 0, PREFIX_PRIORITY, lpenmode}, {"penpaint", 0, 0, 0, PREFIX_PRIORITY, lpenpaint}, {"penpattern", 0, 0, 0, PREFIX_PRIORITY, lpenpattern}, {"penreverse", 0, 0, 0, PREFIX_PRIORITY, lpenreverse}, {"pensize", 0, 0, 0, PREFIX_PRIORITY, lpensize}, {"penup", 0, 0, 0, PREFIX_PRIORITY, lpenup}, {"plist", 1, 1, 1, PREFIX_PRIORITY, lplist}, {"plistp", 1, 1, 1, PREFIX_PRIORITY, lplistp}, {"plist?", 1, 1, 1, PREFIX_PRIORITY, lplistp}, {"plists", 0, 0, 0, PREFIX_PRIORITY, lplists}, {"po", 1, 1, 1, PREFIX_PRIORITY, lpo}, {"pos", 0, 0, 0, PREFIX_PRIORITY, lpos}, {"pot", 1, 1, 1, PREFIX_PRIORITY, lpot}, {"power", 2, 2, 2, PREFIX_PRIORITY, lpower}, {"pprop", 3, 3, 3, PREFIX_PRIORITY, lpprop}, {"ppt", 0, 0, 0, PREFIX_PRIORITY, lpenpaint}, {"pr", 0, 1, -1, PREFIX_PRIORITY, lprint}, {"prefix", 0, 0, 0, PREFIX_PRIORITY, lprefix}, {"primitivep", 1, 1, 1, PREFIX_PRIORITY, lprimitivep}, {"primitive?", 1, 1, 1, PREFIX_PRIORITY, lprimitivep}, {"primitives", 0, 0, 0, PREFIX_PRIORITY, lprimitives}, {"print", 0, 1, -1, PREFIX_PRIORITY, lprint}, {"printout", 1, 1, 1, PREFIX_PRIORITY, lpo}, {"procedurep", 1, 1, 1, PREFIX_PRIORITY, lprocedurep}, {"procedure?", 1, 1, 1, PREFIX_PRIORITY, lprocedurep}, {"procedures", 0, 0, 0, PREFIX_PRIORITY, lprocedures}, {"product", 0, 2, -1, PREFIX_PRIORITY, lmul}, {"pu", 0, 0, 0, PREFIX_PRIORITY, lpenup}, {"px", 0, 0, 0, PREFIX_PRIORITY, lpenreverse}, {"quotient", 1, 2, 2, PREFIX_PRIORITY, ldivide}, {"radarctan", 1, 1, 2, PREFIX_PRIORITY, lradatan}, {"radcos", 1, 1, 1, PREFIX_PRIORITY, lradcos}, {"radsin", 1, 1, 1, PREFIX_PRIORITY, lradsin}, {"random", 1, 1, 2, PREFIX_PRIORITY, lrandom}, {"rawascii", 1, 1, 1, PREFIX_PRIORITY, lrawascii}, {"rc", 0, 0, 0, PREFIX_PRIORITY, lreadchar}, {"rcs", 1, 1, 1, PREFIX_PRIORITY, lreadchars}, {"readchar", 0, 0, 0, PREFIX_PRIORITY, lreadchar}, {"readchars", 1, 1, 1, PREFIX_PRIORITY, lreadchars}, {"reader", 0, 0, 0, PREFIX_PRIORITY, lreader}, {"readlist", 0, 0, 0, PREFIX_PRIORITY, lreadlist}, {"readpos", 0, 0, 0, PREFIX_PRIORITY, lreadpos}, {"readrawline", 0, 0, 0, PREFIX_PRIORITY, lreadrawline}, {"readword", 0, 0, 0, PREFIX_PRIORITY, lreadword}, {"refresh", 0, 0, 0, PREFIX_PRIORITY, lrefresh}, {"remainder", 2, 2, 2, PREFIX_PRIORITY, lremainder}, {"remprop", 2, 2, 2, PREFIX_PRIORITY, lremprop}, {"repcount", 0, 0, 0, PREFIX_PRIORITY, lrepcount}, {"repeat", 2, 2, 2, MACRO_PRIORITY, lrepeat}, #ifdef OBJECTS {"representation", 0, 0, 0, PREFIX_PRIORITY, lrepresentation}, #endif {"rerandom", 0, 0, 1, PREFIX_PRIORITY, lrerandom}, {"right", 1, 1, 1, PREFIX_PRIORITY, lright}, {"rl", 0, 0, 0, PREFIX_PRIORITY, lreadlist}, {"round", 1, 1, 1, PREFIX_PRIORITY, lroundx}, {"rt", 1, 1, 1, PREFIX_PRIORITY, lright}, {"run", 1, 1, 1, MACRO_PRIORITY, lrun}, {"runparse", 1, 1, 1, PREFIX_PRIORITY, lrunparse}, {"runresult", 1, 1, 1, MACRO_PRIORITY, lrunresult}, {"rw", 0, 0, 0, PREFIX_PRIORITY, lreadword}, {"save", 1, 1, 1, PREFIX_PRIORITY, lsave}, {"savepict", 1, 1, 1, PREFIX_PRIORITY, lsavepict}, {"screenmode", 0, 0, 0, PREFIX_PRIORITY, lscreenmode}, {"scrunch", 0, 0, 0, PREFIX_PRIORITY, lscrunch}, {"se", 0, 2, -1, PREFIX_PRIORITY, lsentence}, #ifdef OBJECTS {"self", 0, 0, 0, PREFIX_PRIORITY, lself}, #endif {"sentence", 0, 2, -1, PREFIX_PRIORITY, lsentence}, {"setbg", 1, 1, 1, PREFIX_PRIORITY, lsetbackground}, {"setbackground", 1, 1, 1, PREFIX_PRIORITY, lsetbackground}, {"setcursor", 1, 1, 1, PREFIX_PRIORITY, lsetcursor}, {"setcslsloc", 1, 1, 1, PREFIX_PRIORITY, lsetcslsloc}, {"seteditor", 1, 1, 1, PREFIX_PRIORITY, lseteditor}, {"seth", 1, 1, 1, PREFIX_PRIORITY, lsetheading}, {"setheading", 1, 1, 1, PREFIX_PRIORITY, lsetheading}, {"sethelploc", 1, 1, 1, PREFIX_PRIORITY, lsethelploc}, {"setitem", 3, 3, 3, PREFIX_PRIORITY, lsetitem}, {"setlibloc", 1, 1, 1, PREFIX_PRIORITY, lsetlibloc}, {"setmargins", 1, 1, 1, PREFIX_PRIORITY, lsetmargins}, {"setpalette", 2, 2, 2, PREFIX_PRIORITY, lsetpalette}, {"setpc", 1, 1, 1, PREFIX_PRIORITY, lsetpencolor}, {"setpencolor", 1, 1, 1, PREFIX_PRIORITY, lsetpencolor}, {"setpenpattern", 1, 1, 1, PREFIX_PRIORITY, lsetpenpattern}, {"setpensize", 1, 1, 1, PREFIX_PRIORITY, lsetpensize}, {"setpos", 1, 1, 1, PREFIX_PRIORITY, lsetpos}, {"setprefix", 1, 1, 1, PREFIX_PRIORITY, lsetprefix}, {"setread", 1, 1, 1, PREFIX_PRIORITY, lsetread}, {"setreadpos", 1, 1, 1, PREFIX_PRIORITY, lsetreadpos}, {"setscrunch", 2, 2, 2, PREFIX_PRIORITY, lsetscrunch}, #if defined(WIN32)|defined(ibm) {"settc", 2, 2, 2, PREFIX_PRIORITY, set_text_color}, {"settextcolor", 2, 2, 2, PREFIX_PRIORITY, set_text_color}, #endif {"settemploc", 1, 1, 1, PREFIX_PRIORITY, lsettemploc}, {"setwrite", 1, 1, 1, PREFIX_PRIORITY, lsetwrite}, {"setwritepos", 1, 1, 1, PREFIX_PRIORITY, lsetwritepos}, {"setx", 1, 1, 1, PREFIX_PRIORITY, lsetx}, {"setxy", 2, 2, 2, PREFIX_PRIORITY, lsetxy}, {"sety", 1, 1, 1, PREFIX_PRIORITY, lsety}, {"shell", 1, 1, 2, PREFIX_PRIORITY, lshell}, {"show", 0, 1, -1, PREFIX_PRIORITY, lshow}, {"shownp", 0, 0, 0, PREFIX_PRIORITY, lshownp}, {"shown?", 0, 0, 0, PREFIX_PRIORITY, lshownp}, {"showturtle", 0, 0, 0, PREFIX_PRIORITY, lshowturtle}, {"sin", 1, 1, 1, PREFIX_PRIORITY, lsin}, #ifdef OBJECTS {"something", 0, 0, 0, PREFIX_PRIORITY, lsomething}, #endif {"splitscreen", 0, 0, 0, PREFIX_PRIORITY, lsplitscreen}, {"sqrt", 1, 1, 1, PREFIX_PRIORITY, lsqrt}, {"ss", 0, 0, 0, PREFIX_PRIORITY, lsplitscreen}, {"st", 0, 0, 0, PREFIX_PRIORITY, lshowturtle}, {"standout", 1, 1, 1, PREFIX_PRIORITY, lstandout}, {"step", 1, 1, 1, PREFIX_PRIORITY, lstep}, {"stepped", 0, 0, 0, PREFIX_PRIORITY, lstepped}, {"steppedp", 1, 1, 1, PREFIX_PRIORITY, lsteppedp}, {"stepped?", 1, 1, 1, PREFIX_PRIORITY, lsteppedp}, {"stop", 0, 0, 0, STOP_PRIORITY, lstop}, {"substringp", 2, 2, 2, PREFIX_PRIORITY, lsubstringp}, {"substring?", 2, 2, 2, PREFIX_PRIORITY, lsubstringp}, {"sum", 0, 2, -1, PREFIX_PRIORITY, ladd}, {"tag", 1, 1, 1, PREFIX_PRIORITY, ltag}, #ifdef OBJECTS {"talkto", 1, 1, 1, PREFIX_PRIORITY, ltalkto}, #endif {"test", 1, 1, 1, PREFIX_PRIORITY, ltest}, {"text", 1, 1, 1, PREFIX_PRIORITY, ltext}, {"textscreen", 0, 0, 0, PREFIX_PRIORITY, ltextscreen}, {"thing", 1, 1, 1, PREFIX_PRIORITY, lthing}, {"throw", 1, 1, 2, PREFIX_PRIORITY, lthrow}, {"to", -1, -1, -1, PREFIX_PRIORITY, lto}, {"tone", 2, 2, 2, PREFIX_PRIORITY, ltone}, {"towards", 1, 1, 1, PREFIX_PRIORITY, ltowards}, {"trace", 1, 1, 1, PREFIX_PRIORITY, ltrace}, {"traced", 0, 0, 0, PREFIX_PRIORITY, ltraced}, {"tracedp", 1, 1, 1, PREFIX_PRIORITY, ltracedp}, {"traced?", 1, 1, 1, PREFIX_PRIORITY, ltracedp}, {"ts", 0, 0, 0, PREFIX_PRIORITY, ltextscreen}, {"turtlemode", 0, 0, 0, PREFIX_PRIORITY, lturtlemode}, {"type", 0, 1, -1, PREFIX_PRIORITY, ltype}, {"unbury", 1, 1, 1, PREFIX_PRIORITY, lunbury}, {"unstep", 1, 1, 1, PREFIX_PRIORITY, lunstep}, {"untrace", 1, 1, 1, PREFIX_PRIORITY, luntrace}, {"uppercase", 1, 1, 1, PREFIX_PRIORITY, luppercase}, {"wait", 1, 1, 1, PREFIX_PRIORITY, lwait}, {"window", 0, 0, 0, PREFIX_PRIORITY, lwindow}, {"word", 0, 2, -1, PREFIX_PRIORITY, lword}, {"wordp", 1, 1, 1, PREFIX_PRIORITY, lwordp}, {"word?", 1, 1, 1, PREFIX_PRIORITY, lwordp}, {"wrap", 0, 0, 0, PREFIX_PRIORITY, lwrap}, {"writepos", 0, 0, 0, PREFIX_PRIORITY, lwritepos}, {"writer", 0, 0, 0, PREFIX_PRIORITY, lwriter}, #ifdef mac {"setwindowtitle", 1, 1, 1, PREFIX_PRIORITY, lsetwindowtitle}, {"settextfont", 1, 1, 1, PREFIX_PRIORITY, lsettextfont}, {"settextsize", 1, 1, 1, PREFIX_PRIORITY, lsettextsize}, {"settextstyle", 1, 1, 1, PREFIX_PRIORITY, lsettextstyle}, {"setwindowsize", 1, 1, 1, PREFIX_PRIORITY, lsetwindowsize}, {"setwindowxy", 1, 1, 1, PREFIX_PRIORITY, lsetwindowxy}, {"newconsole", 0, 0, 0, PREFIX_PRIORITY, lnewconsole}, {"graphtext", 0, 0, 0, PREFIX_PRIORITY, lgraphtext}, {"regulartext", 0, 0, 0, PREFIX_PRIORITY, lregulartext}, {"caninverse", 1, 1, 1, PREFIX_PRIORITY, lcaninverse}, #endif {0, 0, 0, 0, 0, 0} }; struct wdtrans translations[NUM_WORDS]; NODE *intern_p(NODE *caseobj) { NODE *result = intern(caseobj); setflag__caseobj(result, PERMANENT); return result; } void init(void) { int i = 0; NODE *iproc = NIL, *pname = NIL, *cnd = NIL; FILE *fp; char linebuf[100]; #ifdef WIN32 HKEY regKey1, regKey2, regKey3; int got_hklm = 0; char buf[200]; unsigned long int bufsiz; char *envp; #endif readstream = stdin; writestream = stdout; loadstream = stdin; fill_reserve_tank(); oldyoungs = Unbound = newnode(PUNBOUND); #ifdef HAVE_SRANDOM srandom((int)time((time_t *)NULL)); #else srand((int)time((time_t *)NULL)); #endif #ifdef ecma for (i=0; i<128; i++) ecma_array[i] = i; for (i=0; in_car = (NODE *)®s; #ifdef OBJECTS obj_init(); #endif /* Uncomment these to print debugging messages right away! */ /* setvalnode__caseobj(Redefp, True); setflag__caseobj(Redefp, VAL_BURIED); */ } ucblogo-5.5/config.h.in0100644000161300001330000000372010216146744012762 0ustar bhdoe/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if you need to in order for stat and other things to work. */ #undef _POSIX_SOURCE /* Define as the return instruction for signal handlers. */ #undef SIGRET /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define if signal handlers take an argument. */ #undef SIG_TAKES_ARG /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you have the matherr function. */ #undef HAVE_MATHERR /* Define if you have the sigsetmask function. */ #undef HAVE_SIGSETMASK /* Define if you have the sigvec function. */ #undef HAVE_SIGVEC /* Define if you have the srandom function. */ #undef HAVE_SRANDOM /* Define if you have the usleep function. */ #undef HAVE_USLEEP /* Define if you have the memcpy function. */ #undef HAVE_MEMCPY /* Define if you have the header file. */ #undef HAVE_SGTTY_H /* Define if you have the header file. */ #undef HAVE_TERMIO_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the header file. */ #undef HAVE_STRING_H /* Define if you have the header file. */ #undef HAVE_TERMCAP_H /* Define if you have the header file. */ #undef HAVE_TERMLIB_H /* Define if you have the header file. */ #undef HAVE_CURSES_H /* Define if you have the BSD library (-lBSD). */ #undef HAVE_LIBBSD /* Define if you have the curses library (-lcurses). */ #undef HAVE_LIBCURSES /* Define if you have the m library (-lm). */ #undef HAVE_LIBM /* Define if you have the termcap library (-ltermcap). */ #undef HAVE_LIBTERMCAP /* Define if you have the termlib library (-ltermlib). */ #undef HAVE_LIBTERMLIB /* Define if you have X11. */ #undef HAVE_X11 /* Define if you have the wx library. */ #undef HAVE_WX ucblogo-5.5/globals.h0100644000161300001330000004457010275756222012546 0ustar bhdoe/* * globals.h logo global references module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* main.c */ #ifdef HAVE_WX extern int start(int, char **); #endif extern NODE **bottom_stack; /*GC*/ extern NODE *current_line, *exec_list; extern int main(int, char *[]); extern void unblock_input(void); extern NODE **bottom_stack; extern void delayed_int(void); #if defined(SIG_TAKES_ARG) RETSIGTYPE logo_stop(int); RETSIGTYPE logo_pause(int); RETSIGTYPE mouse_down(int); #define mouse_click mouse_down(0) #else RETSIGTYPE logo_stop(void); RETSIGTYPE logo_pause(void); RETSIGTYPE mouse_down(void); #define mouse_click mouse_down() #endif #ifndef TIOCSTI #include extern jmp_buf iblk_buf; #endif /* logodata.c */ extern char *strnzcpy(char *, char *, int); extern char *word_strnzcpy(char *, NODE *, int); extern char *noparity_strnzcpy(char *, char *, int); extern char *mend_strnzcpy(char *, char *, int); extern char *mend_nosemi(char *, char *, int); extern char *low_strnzcpy(char *, char *, int); extern char *cap_strnzcpy(char *, char *, int); extern char *noparitylow_strnzcpy(char *, char *, int); extern int low_strncmp(char *, char *, int); extern int noparity_strncmp(char *, char *, int); extern int noparitylow_strncmp(char *, char *, int); extern NODE *make_strnode(char *, struct string_block *, int, NODETYPES, char *(*)()); extern void make_runparse(NODE *); extern NODE *make_quote(NODE *); extern NODE *maybe_quote(NODE *); extern NODE *make_caseobj(NODE *, NODE *); extern NODE *make_colon(NODE *); extern NODE *make_intnode(FIXNUM); extern NODE *make_floatnode(FLONUM); extern NODE *cnv_node_to_numnode(NODE *); extern NODE *cnv_node_to_strnode(NODE *); extern NODE *make_static_strnode(char *); extern NODE *cons_list(int, ...); extern NODE *make_array(FIXNUM); extern NODE *llowercase(NODE *); extern NODE *luppercase(NODE *); extern NODE *lgprop(NODE *); extern NODE *lpprop(NODE *); extern NODE *lremprop(NODE *); extern NODE *copy_list(NODE *); extern NODE *lplist(NODE *); extern int isName(NODE *, enum words); extern int varTrue(NODE *); extern NODE *theName(enum words); extern NODE *TrueName(void); extern NODE *FalseName(void); #ifdef ecma extern char ecma_array[], special_chars[]; extern char ecma_set(int); extern char ecma_clear(int); extern int ecma_size; extern int ecma_get(int); #endif /* mem.c */ extern NODE *free_list; extern struct segment *segment_list; extern NODE *oldyoungs; extern BOOLEAN inside_gc, int_during_gc; extern BOOLEAN addseg(void); extern NODETYPES nodetype(NODE *); extern void check_valid_oldyoung(NODE *old, NODE *new); extern void setobject(NODE *, NODE *); extern void setcar(NODE *, NODE *); extern void setcdr(NODE *, NODE *); extern NODE *newnode(NODETYPES); extern NODE *cons(NODE *, NODE *); extern void mark(NODE *); extern void gc(BOOLEAN); extern NODE *lgc(NODE *); extern NODE *lnodes(NODE *); extern NODE *lsetsegsz(NODE *); extern void fill_reserve_tank(void); extern void use_reserve_tank(void); extern void check_reserve_tank(void); /* parse.c */ extern FILE *loadstream, *writestream, *readstream, *dribblestream; extern int input_blocking; extern NODE *current_line, *deepend_proc_name; extern NODE *reader(FILE *, char *); extern NODE *parser(NODE *, BOOLEAN); extern NODE *lparse(NODE *); extern NODE *runparse(NODE *); extern NODE *lrunparse(NODE *); /* math.c */ extern int numberp(NODE *); extern NODE *lrandom(NODE *); extern NODE *lrerandom(NODE *); extern void math_init(void); extern FLONUM degrad; extern NODE *ladd(NODE *); extern NODE *lsub(NODE *); extern NODE *lmul(NODE *); extern NODE *ldivide(NODE *); extern NODE *lremainder(NODE *); extern NODE *lmodulo(NODE *); extern NODE *lbitand(NODE *); extern NODE *lbitor(NODE *); extern NODE *lbitxor(NODE *); extern NODE *lashift(NODE *); extern NODE *llshift(NODE *); extern NODE *lbitnot(NODE *); extern NODE *lsin(NODE *); extern NODE *lcos(NODE *); extern NODE *latan(NODE *); extern NODE *lradsin(NODE *); extern NODE *lradcos(NODE *); extern NODE *lradatan(NODE *); extern NODE *lsqrt(NODE *); extern NODE *linteg(NODE *); extern NODE *lroundx(NODE *); extern NODE *lexp(NODE *); extern NODE *llog10(NODE *); extern NODE *lln(NODE *); extern NODE *lpower(NODE *); extern NODE *torf(BOOLEAN); extern NODE *llessp(NODE *); extern NODE *lgreaterp(NODE *); extern NODE *llessequalp(NODE *); extern NODE *lgreaterequalp(NODE *); extern int compare_node(NODE *, NODE *, BOOLEAN); extern BOOLEAN equalp_help(NODE *, NODE *, BOOLEAN); extern NODE *lequalp(NODE *); extern NODE *lnotequalp(NODE *); extern NODE *l_eq(NODE *); extern NODE *lbeforep(NODE *); /* intern.c */ extern NODE *hash_table[HASH_LEN]; void map_oblist(void (*)()); extern NODE *make_instance(NODE *, NODE *); extern NODE *intern(NODE *); /* print.c */ extern int print_stringlen; extern char *print_stringptr; extern int force_printwidth, force_printdepth; extern int x_margin, y_margin; extern NODE *Fullprintp; extern void update_coords(char); extern void print_char(FILE *, char); extern void print_space(FILE *); extern void ndprintf(FILE *, char *, ...); extern void real_print_help(FILE *, NODE *, int, int); extern void print_help(FILE *, NODE *); extern void print_node(FILE *, NODE *); extern void print_nobrak(FILE *, NODE *); extern void new_line(FILE *); extern NODE *lshow(NODE *); extern NODE *ltype(NODE *); extern NODE *lprint(NODE *); /* init.c */ extern NODE *Left_Paren, *Right_Paren; extern NODE *Redefp, *Caseignoredp, *Erract, *Printdepthlimit; extern NODE *Printwidthlimit, *Pause, *LoadNoisily, *AllowGetSet; extern NODE *UnburyOnEdit, *Make, *Listvalue, *Dotsvalue; extern NODE *Unbound, *Not_Enough_Node, *Buttonact, *LogoVersion; extern NODE *Minus_Sign, *Minus_Tight, *Startup, *Query; extern NODE *UseAlternateNames, *LogoLogo, *LogoPlatform; extern NODE *Null_Word; extern void init(void); extern struct wdtrans translations[]; extern char *LogoPlatformName; /* wrksp.c */ extern char *editor, *editorname, *tempdir; extern int to_pending; extern NODE *ltext(NODE *); extern NODE *lfulltext(NODE *); extern NODE *ldefine(NODE *); extern NODE *ldefmacro(NODE *); extern NODE *anonymous_function(NODE *); extern NODE *lmacro(NODE *); extern NODE *lto(NODE *); extern NODE *lmake(NODE *); extern NODE *llocal(NODE *); extern NODE *lglobal(NODE *); extern NODE *cnt_list, *cnt_last; extern NODE *lcontents(NODE *); extern NODE *lburied(NODE *); extern NODE *ltraced(NODE *); extern NODE *lstepped(NODE *); extern NODE *lprocedures(NODE *); extern NODE *lprimitives(NODE *); extern NODE *lnames(NODE *); extern NODE *lplists(NODE *); extern NODE *lpo(NODE *); extern NODE *lpot(NODE *); extern NODE *lerase(NODE *); extern NODE *lerall(NODE *); extern NODE *lerps(NODE *); extern NODE *lerns(NODE *); extern NODE *lerpls(NODE *); extern NODE *lbury(NODE *); extern NODE *ltrace(NODE *); extern NODE *lstep(NODE *); extern NODE *lburiedp(NODE *); extern NODE *ltracedp(NODE *); extern NODE *lsteppedp(NODE *); extern NODE *lunbury(NODE *); extern NODE *luntrace(NODE *); extern NODE *lunstep(NODE *); extern char *addsep(char *); extern NODE *ledit(NODE *); extern NODE *leditfile(NODE *); extern NODE *lthing(NODE *); extern NODE *lnamep(NODE *); extern NODE *lprocedurep(NODE *); extern NODE *lplistp(NODE *); extern NODE *lprimitivep(NODE *); extern NODE *ldefinedp(NODE *); extern NODE *lmacrop(NODE *); extern NODE *lcopydef(NODE *); extern NODE *lhelp(NODE *); extern NODE *larity(NODE *); /* error.c */ extern char *message_texts[]; extern NODE *throw_node; extern NODE *err_mesg; extern ERR_TYPES erract_errtype; extern void err_print(char *); extern NODE *err_logo(ERR_TYPES, NODE *); extern NODE *lerror(NODE *); extern NODE *lpause(NODE *); extern NODE *lcontinue(NODE *); /* eval.c */ extern NODE *var_stack; extern NODE *output_node, *output_unode, *last_call; extern CTRLTYPE stopping_flag; extern char *logolib, *helpfiles, *csls; extern FIXNUM dont_fix_ift; extern void eval_driver(NODE *); extern NODE *err_eval_driver(NODE *, BOOLEAN); extern NODE *lapply(NODE *); extern NODE *lqm(NODE *); extern NODE *deep_copy(NODE *); extern void tell_shadow(NODE *); extern int not_local(NODE *, NODE *); extern int num_saved_nodes; extern struct registers regs; extern NODE *Regs_Node; /* #ifdef OBJECTS extern NODE *val_eval_driver(NODE *seq); #endif */ /* lists.c */ extern NODE *lbutfirst(NODE *); extern NODE *lbutlast(NODE *); extern NODE *lfirst(NODE *); extern NODE *lfirsts(NODE *); extern NODE *lbfs(NODE *); extern NODE *llast(NODE *); extern NODE *llist(NODE *); extern NODE *lemptyp(NODE *); extern NODE *lascii(NODE *); extern NODE *lrawascii(NODE *); extern NODE *lbackslashedp(NODE *); extern NODE *lchar(NODE *); extern NODE *lcount(NODE *); extern NODE *lfput(NODE *); extern NODE *llput(NODE *); extern NODE *string_arg(NODE *); extern NODE *lword(NODE *); extern NODE *lsentence(NODE *); extern NODE *lwordp(NODE *); extern NODE *llistp(NODE *); extern NODE *lnumberp(NODE *); extern NODE *larrayp(NODE *); extern NODE *lmemberp(NODE *); extern NODE *lsubstringp(NODE *); extern NODE *lmember(NODE *); extern NODE *integer_arg(NODE *); extern FIXNUM int_arg(NODE *); extern NODE *litem(NODE *); extern NODE *lsetitem(NODE *); extern NODE *l_setitem(NODE *); extern NODE *larray(NODE *); extern NODE *larraytolist(NODE *); extern NODE *llisttoarray(NODE *); extern NODE *lform(NODE *); extern NODE *l_setfirst(NODE *); extern NODE *l_setbf(NODE *); /* files.c */ extern NODE *file_list; extern NODE *reader_name, *writer_name, *file_prefix; extern NODE *lseteditor(NODE *); extern NODE *lsetlibloc(NODE *); extern NODE *lsetcslsloc(NODE *); extern NODE *lsethelploc(NODE *); extern NODE *lsettemploc(NODE *); extern NODE *ldribble(NODE *); extern NODE *lnodribble(NODE *); extern NODE *lopenread(NODE *); extern NODE *lopenwrite(NODE *); extern NODE *lopenappend(NODE *); extern NODE *lopenupdate(NODE *); extern NODE *lallopen(NODE *); extern NODE *lclose(NODE *); extern NODE *lsetwrite(NODE *); extern NODE *lsetread(NODE *); extern NODE *lreader(NODE *); extern NODE *lwriter(NODE *); extern NODE *lerasefile(NODE *); extern NODE *lsave(NODE *); extern void silent_load(NODE *, char *); extern NODE *lload(NODE *); extern NODE *lcslsload(NODE *); extern NODE *lsetprefix(NODE *); extern NODE *lprefix(NODE *); extern NODE *lreadlist(NODE *); extern NODE *lreadword(NODE *); extern NODE *lreadrawline(NODE *); extern NODE *lreadchar(NODE *); extern NODE *lreadchars(NODE *); extern NODE *leofp(NODE *); extern NODE *lkeyp(NODE *); extern NODE *lreadpos(NODE *); extern NODE *lsetreadpos(NODE *); extern NODE *lwritepos(NODE *); extern NODE *lsetwritepos(NODE *); /* coms.c */ extern NODE *make_cont(enum labels, NODE *); extern NODE *loutput(NODE *); extern NODE *lstop(NODE *); extern NODE *lthrow(NODE *); extern NODE *lcatch(NODE *); extern NODE *lgoto(NODE *); extern NODE *ltag(NODE *); extern NODE *lnot(NODE *); extern NODE *land(NODE *); extern NODE *lor(NODE *); extern NODE *lif(NODE *); extern NODE *lifelse(NODE *); extern NODE *lrun(NODE *); extern NODE *lrunresult(NODE *); extern NODE *pos_int_arg(NODE *); extern int torf_arg(NODE *); extern NODE *lrepeat(NODE *); extern NODE *lrepcount(NODE *); extern NODE *lforever(NODE *); extern NODE *ltest(NODE *); extern NODE *liftrue(NODE *); extern NODE *liffalse(NODE *); extern void prepare_to_exit(BOOLEAN); extern NODE *lbye(NODE *); extern NODE *lwait(NODE *); extern NODE *lshell(NODE *); /* term.c */ extern int x_coord, y_coord, x_max, y_max; extern int interactive; extern void term_init(void); extern void charmode_on(void); extern void charmode_off(void); extern NODE *lcleartext(NODE *); extern NODE *lcursor(NODE *); extern NODE *lsetcursor(NODE *); extern NODE *lsetmargins(NODE *); extern NODE *lstandout(NODE *); /* libloc.c */ extern char *libloc, *helploc, *cslsloc, *temploc, *separator; /* paren.c */ extern NODE *the_generation; extern void untreeify_proc(NODE *); extern void make_tree_from_body(NODE *); extern void make_tree(NODE *); extern NODE *tree_dk_how; /* graphics.c */ extern mode_type current_mode; extern FLONUM turtle_x, turtle_y, turtle_heading, x_scale, y_scale; extern BOOLEAN turtle_shown; extern BOOLEAN refresh_p; extern FIXNUM g_round(FLONUM); void draw_turtle(void); extern NODE *numeric_arg(NODE *); extern NODE *lright(NODE *); extern NODE *lleft(NODE *); extern NODE *lforward(NODE *); extern NODE *lback(NODE *); extern NODE *lshowturtle(NODE *); extern NODE *lhideturtle(NODE *); extern NODE *lshownp(NODE *); extern NODE *lsetheading(NODE *); extern NODE *lheading(NODE *); extern NODE *pos_int_vector_arg(NODE *); extern NODE *ltowards(NODE *); extern NODE *lpos(NODE *); extern NODE *lscrunch(NODE *); extern NODE *lhome(NODE *); extern NODE *lclearscreen(NODE *); extern NODE *lclean(NODE *); extern NODE *lsetpos(NODE *); extern NODE *lsetxy(NODE *); extern NODE *lsetx(NODE *); extern NODE *lsety(NODE *); extern NODE *lwrap(NODE *); extern NODE *lfence(NODE *); extern NODE *lwindow(NODE *); extern NODE *lfill(NODE *); extern NODE *llabel(NODE *); extern NODE *ltextscreen(NODE *); extern NODE *lsplitscreen(NODE *); extern NODE *lfullscreen(NODE *); extern NODE *lpendownp(NODE *); extern NODE *lpenmode(NODE *); extern NODE *lpencolor(NODE *); extern NODE *lbackground(NODE *); extern NODE *lpensize(NODE *); extern NODE *lpenpattern(NODE *); extern NODE *lpendown(NODE *); extern NODE *lpenup(NODE *); extern NODE *lpenpaint(NODE *); extern NODE *lpenerase(NODE *); extern NODE *lpenreverse(NODE *); extern NODE *lsetpencolor(NODE *); extern NODE *lsetbackground(NODE *); extern NODE *lsetpalette(NODE *); extern NODE *lpalette(NODE *); extern NODE *lsetpensize(NODE *); extern NODE *lsetpenpattern(NODE *); extern NODE *lsetscrunch(NODE *); extern NODE *lmousepos(NODE *); extern NODE *lbuttonp(NODE *); extern NODE *lbutton(NODE *); extern NODE *ltone(NODE *); extern NODE *larc(NODE *); extern NODE *lrefresh(NODE *); extern NODE *lnorefresh(NODE *); extern NODE *lloadpict(NODE *); extern NODE *lsavepict(NODE *); extern NODE *lepspict(NODE *); extern void redraw_graphics(void); extern NODE *lscreenmode(NODE *); extern NODE *lturtlemode(NODE *); #ifdef mac #define SIGQUIT SIGABRT /* macterm.c */ extern void init_mac_memory(void); extern BOOLEAN check_mac_stop(void); extern void term_init_mac(void); extern void mac_gotoxy(int, int); extern NODE *lsetwindowtitle(NODE *); extern NODE *lsettextfont(NODE *); extern NODE *lsettextsize(NODE *); extern NODE *lsettextstyle(NODE *); extern NODE *lsetwindowsize(NODE *); extern NODE *lsetwindowxy(NODE *); extern NODE *lnewconsole(NODE *); extern NODE *lgraphtext(NODE *); extern NODE *lregulartext(NODE *); extern NODE *lcaninverse(NODE *); extern BOOLEAN mac_edit(); #ifndef SYMANTEC_C extern WindowPtr graphics_window, listener_window; #endif #endif #ifdef __RZTC__ /* ztcterm.c */ extern BOOLEAN in_graphics_mode, in_splitscreen; extern int ibm_screen_bottom; #include extern fg_coord_t MaxX, MaxY; extern void outtext(char *); extern void init_ibm_memory(void); extern volatile int ctrl_c_count; extern BOOLEAN check_ibm_stop(void); extern void term_init_ibm(void); extern void ibm_gotoxy(int, int); extern void ibm_clear_text(void); extern void ibm_clear_screen(void); extern void ibm_plain_mode(void); extern void ibm_bold_mode(void); extern void erase_graphics_top(void); extern void ztc_set_penc(FIXNUM); extern void t_screen(void); extern void s_screen(void); extern void check_scroll(void); extern void ztc_put_char(int); extern void fix_cursor(void); extern void zflush(void); extern void newline_bugfix(void); extern void ztc_getcr(void); extern NODE *set_text_color(NODE *); #endif #ifdef HAVE_WX extern void init_wx(int, char**); extern void printToScreen(char c, FILE * stream); extern char getFromWX(); extern char getFromWX_2(FILE * f); #endif #ifdef x_window /* xgraphics.c */ extern void x_window_init(int, char **); extern void check_X11_stop(void); extern int clearing_screen; #endif #ifdef WIN32 /* Win32trm.c */ #undef WIN32_DEBUG #undef CONSOLE #ifdef WIN32_DEBUG extern void WinDebug(char *); #endif extern int in_graphics_mode, in_splitscreen, cur_len, read_index; extern char *read_line, buffered_char; extern int char_mode; extern int line_avail, char_avail; extern void win32_advance_line(void); extern char *eight_dot_three(char *); extern BOOLEAN check_ibm_stop(void); extern NODE* win32_lsetcursor(NODE *); extern int win32_putc(int, FILE*); extern void win32_charmode_off(void), win32_charmode_on(void); extern void win32_repaint_screen(void); extern void win32_clear_text(void); extern void ibm_plain_mode(void); extern void ibm_bold_mode(void); extern void win32_update_text(void); extern void moveto(int, int); extern void lineto(int, int); extern void draw_string(char *); extern int win32_screen_bottom(void); extern void win32_text_cursor(void); extern NODE *set_text_color(NODE *); extern void winDoPaste(void); extern char *winPasteText; extern NODE *maximize(NODE *); #define SIGQUIT SIGABRT #endif #ifdef HAVE_WX #define rd_putc printToScreen #else #ifdef WIN32 #define rd_putc win32_putc #else /* !WIN32 */ #define rd_putc putc #endif #endif #ifdef OBJECTS /* obj.c */ extern NODE *logo_object, *current_object, *askexist; extern void obj_init(void); NODE *assoc(NODE *name, NODE *alist); extern NODE *llogo(NODE *); extern NODE *lsomething(NODE *); extern NODE *lkindof(NODE *); extern NODE *loneof(NODE *); extern NODE *lexist(NODE *); extern NODE *lhave(NODE *); extern NODE *ltalkto(NODE *); extern NODE *lask(NODE *); extern NODE *lself(NODE *); extern NODE *lparents(NODE *); extern NODE *lmynames(NODE *); extern NODE *lmynamep(NODE *); extern NODE *lmyprocs(NODE *); extern NODE *lmyprocp(NODE *); extern NODE *lrepresentation(NODE *); extern NODE *varValue(NODE *); extern NODE *varInObjectHierarchy(NODE *, BOOLEAN); extern NODE *varInThisObject(NODE *, BOOLEAN); extern NODE *procValue(NODE *); extern NODE *parent_list(NODE *); #endif ucblogo-5.5/wrksp.c0100644000161300001330000012777510275714211012265 0ustar bhdoe/* * wrksp.c logo workspace management module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef WIN32 #include #endif #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" #ifdef HAVE_WX void wxEditFile(char *); #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef ibm #include "process.h" #endif #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif char *editor, *editorname, *tempdir; int to_pending = 0; NODE *make_procnode(NODE *lst, NODE *wrds, int min, int df, int max) { return(cons_list(0, lst, wrds, make_intnode((FIXNUM)min), make_intnode((FIXNUM)df), make_intnode((FIXNUM)max), END_OF_LIST)); } NODE *get_bodywords(NODE *pproc, NODE *name) { NODE *val = bodywords__procnode(pproc); NODE *head = NIL, *tail = NIL; if (val != NIL) return(val); name = intern(name); head = cons_list(0, (is_macro(name) ? theName(Name_macro) : theName(Name_to)), name, END_OF_LIST); tail = cdr(head); val = formals__procnode(pproc); while (val != NIL) { if (is_list(car(val))) setcdr(tail, cons(cons(make_colon(caar(val)), cdar(val)), NIL)); else if (nodetype(car(val)) == INT) setcdr(tail, cons(car(val),NIL)); else setcdr(tail, cons(make_colon(car(val)),NIL)); tail = cdr(tail); val = cdr(val); } head = cons(head, NIL); tail = head; val = bodylist__procnode(pproc); while (val != NIL) { setcdr(tail, cons(runparse(car(val)), NIL)); tail = cdr(tail); val = cdr(val); } setcdr(tail, cons(cons(theName(Name_end), NIL), NIL)); /* setbodywords__procnode(pproc,head); */ /* confuses copydef */ return(head); } NODE *name_arg(NODE *args) { while (aggregate(car(args)) && NOT_THROWING) setcar(args, err_logo(BAD_DATA, car(args))); return car(args); } NODE *proc_name_arg(NODE *args) { while ((aggregate(car(args)) || numberp(car(args))) && NOT_THROWING) setcar(args, err_logo(BAD_DATA, car(args))); return car(args); } NODE *ltext(NODE *args) { NODE *name, *val = UNBOUND; name = proc_name_arg(args); if (NOT_THROWING) { val = procnode__caseobj(intern(name)); if (val == UNDEFINED) { err_logo(DK_HOW_UNREC,name); return UNBOUND; } else if (is_prim(val)) { err_logo(IS_PRIM,name); return UNBOUND; } else return text__procnode(val); } return UNBOUND; } NODE *lfulltext(NODE *args) { NODE *name, *val = UNBOUND; name = proc_name_arg(args); if (NOT_THROWING) { val = procnode__caseobj(intern(name)); if (val == UNDEFINED) { err_logo(DK_HOW_UNREC,name); return UNBOUND; } else if (is_prim(val)) { err_logo(IS_PRIM,name); return UNBOUND; } else return get_bodywords(val,name); } return UNBOUND; } BOOLEAN all_lists(NODE *val) { if (val == NIL) return TRUE; if (!is_list(car(val))) return FALSE; return all_lists(cdr(val)); } #ifdef OBJECTS BOOLEAN proc_exists(NODE *name) { if (current_object == logo_object) return procnode__caseobj(name) != UNDEFINED; else return assoc(name, getprocs(current_object)) != NIL; } BOOLEAN prim_exists(NODE *name) { NODE *binding; if (current_object == logo_object) return is_prim(procnode__caseobj(name)); else binding = assoc(name, getprocs(current_object)); return (binding==NIL ? FALSE : is_prim(getobject(binding))); } int find_old_default(NODE *name) { NODE *p; if (flag__caseobj(name, MIXED_ARITY)) return -2; p = procValue(name); if (p == UNDEFINED) return -1; return (is_prim(p) ? getprimdflt(p) : getint(dfltargs__procnode(p))); } #endif /* OBJECTS */ NODE *define_helper(NODE *args, BOOLEAN macro_flag) { /* macro_flag is -1 for anonymous function */ NODE *name = NIL, *val = NIL, *arg = NIL; int minimum = 0, deflt = 0, maximum = 0, old_default = -1; int redef = (varTrue(Redefp)); if (macro_flag >= 0) { name = proc_name_arg(args); if (NOT_THROWING) { name = intern(name); val = procnode__caseobj(name); if (!redef && is_prim(val)) { err_logo(IS_PRIM,name); return UNBOUND; } else if (val != UNDEFINED) { old_default = (is_prim(val) ? getprimdflt(val) : getint(dfltargs__procnode(val))); } } if (NOT_THROWING) { val = cadr(args); while ((val == NIL || !is_list(val) || !all_lists(val)) && NOT_THROWING) { setcar(cdr(args), err_logo(BAD_DATA, val)); val = cadr(args); } if (NOT_THROWING) val = deep_copy(val); /* 5.4 fixes bug about defined procedures sharing tree form */ } } else { /* lambda */ val = args; } if (NOT_THROWING) { args = car(val); if (args != NIL) { make_runparse(args); args = parsed__runparse(args); } setcar(val, args); while (args != NIL) { arg = car(args); if (arg != NIL && is_list(arg) && maximum != -1) { make_runparse(arg); arg = parsed__runparse(arg); setcar(args, arg); setcar(arg, intern(car(arg))); /* fixes crash for # as arg */ maximum++; if (arg == NIL || !is_word(car(arg))) { err_logo(BAD_DATA_UNREC, arg); break; } if (cdr(arg) == NIL) maximum = -1; } else if (nodetype(arg) == INT) { if ((unsigned)getint(arg) <= (unsigned) maximum && getint(arg) >= minimum) { deflt = getint(arg); } else { err_logo(BAD_DATA_UNREC, arg); break; } } else if (is_word(arg) && maximum == minimum) { minimum++; maximum++; deflt++; } else { err_logo(BAD_DATA_UNREC, arg); break; } args = cdr(args); if (check_throwing) break; } } if (macro_flag < 0) { return make_procnode(val, NIL, minimum, deflt, maximum); } else if (NOT_THROWING) { setprocnode__caseobj(name, make_procnode(val, NIL, minimum, deflt, maximum)); if (macro_flag) setflag__caseobj(name, PROC_MACRO); else clearflag__caseobj(name, PROC_MACRO); if (deflt != old_default && old_default >= 0) { the_generation = cons(NIL, NIL); } } return(UNBOUND); } NODE *ldefine(NODE *args) { return define_helper(args, FALSE); } NODE *ldefmacro(NODE *args) { return define_helper(args, TRUE); } NODE *anonymous_function(NODE *text) { return define_helper(text, -1); } char *strncasestr(char *big, char *little, FIXNUM len) { char *p, *q, pc, qc; FIXNUM i; while (*big != '\0') { while ((pc = *big++) != '\0' && tolower(pc) != tolower(*little)) ; if (pc == '\0') return NULL; p = big; q = little+1; i = len; while (--i > 0 && (qc = *q++) != '\0') { if ((pc = *p++) == '\0') return NULL; if (pc == '~') { while ((pc = *p++) != '\0' && pc != '\n') ; if (pc == '\0') return NULL; pc = *p++; } if (tolower(pc) != tolower(qc)) break; } if (i == 0) return big-1; } return NULL; /* not reached, I think */ } NODE *find_to(NODE *line) { char *lp = getstrptr(line); NODE *funn = cnv_node_to_strnode(fun); char *fp = getstrptr(funn); FIXNUM len = getstrlen(funn); char *p, c; p = lp; while (p != NULL) { p = strncasestr(p, fp, len); if (p == NULL) return(line); /* punt */ if ((c = *(p+len)) == ' ' || c == '\t' || c == '\n') { if (p == lp || ((c = *(p-1)) == ' ' || c == '\t' || c == '\n')) return make_strnode(p, getstrhead(line), getstrlen(line)-(p-lp), nodetype(line), strcpy); if (c == '[') return make_strnode(p, getstrhead(line), strchr(p, ']')-p, nodetype(line), strcpy); } p++; } return line; } NODE *to_helper(NODE *args, BOOLEAN macro_flag) { NODE *arg = NIL, *tnode = NIL, *proc_name, *forms = NIL, *lastnode = NIL, *body_words, *lastnode2, *body_list; int minimum = 0, deflt = 0, maximum = 0, old_default = -1; if (ufun != NIL && loadstream == stdin) { err_logo(NOT_INSIDE,NIL); return(UNBOUND); } if (args == NIL) { err_logo(NOT_ENOUGH,NIL); return(UNBOUND); } deepend_proc_name = proc_name = car(args); args = cdr(args); if (nodetype(proc_name) != CASEOBJ) err_logo(BAD_DATA_UNREC, proc_name); #ifdef OBJECTS else if ((proc_exists(proc_name) && loadstream == stdin) || prim_exists(proc_name)) #else /* OBJECTS */ else if ((procnode__caseobj(proc_name) != UNDEFINED && loadstream == stdin) || is_prim(procnode__caseobj(proc_name))) #endif /* OBJECTS */ err_logo(ALREADY_DEFINED, proc_name); else { #ifdef OBJECTS old_default = find_old_default(proc_name); #else /* OBJECTS */ NODE *old_proc = procnode__caseobj(proc_name); if (old_proc != UNDEFINED) { old_default = (is_prim(old_proc) ? getprimdflt(old_proc) : getint(dfltargs__procnode(old_proc))); } #endif /* OBJECTS */ while (args != NIL) { arg = car(args); args = cdr(args); if (nodetype(arg) == CONS && maximum != -1) { make_runparse(arg); arg = parsed__runparse(arg); maximum++; if (arg == NIL || !is_word(car(arg))) { err_logo(BAD_DATA_UNREC, arg); break; } if (nodetype(car(arg)) == COLON) setcar(arg, node__colon(car(arg))); if (nodetype(car(arg)) == QUOTE) setcar(arg, node__quote(car(arg))); if (cdr(arg) == NIL) maximum = -1; } else if (nodetype(arg) == INT) { if ((unsigned)getint(arg) <= (unsigned) maximum && getint(arg) >= minimum) { deflt = getint(arg); } else { err_logo(BAD_DATA_UNREC, arg); break; } } else if (is_word(arg) && maximum == minimum) { if (nodetype(arg) == COLON) arg = node__colon(arg); if (nodetype(arg) == QUOTE) arg = node__quote(arg); minimum++; maximum++; deflt++; } else { err_logo(BAD_DATA_UNREC, arg); break; } tnode = cons(arg, NIL); if (forms == NIL) forms = tnode; else setcdr(lastnode, tnode); lastnode = tnode; } } if (NOT_THROWING) { body_words = cons(find_to(current_line), NIL); lastnode2 = body_words; body_list = cons(forms, NIL); lastnode = body_list; to_pending++; /* for int or quit signal */ while (NOT_THROWING && to_pending && (!feof(loadstream))) { tnode = cons(reader(loadstream, "> "), NIL); if ((feof(loadstream))) { tnode = cons(theName(Name_end), NIL); } setcdr(lastnode2, tnode); lastnode2 = tnode; tnode = cons(parser(car(tnode), TRUE), NIL); if (car(tnode) != NIL && isName(caar(tnode), Name_end)) break; else if (car(tnode) != NIL) { setcdr(lastnode, tnode); lastnode = tnode; } } if (to_pending && NOT_THROWING) { setprocnode__caseobj(proc_name, make_procnode(body_list, body_words, minimum, deflt, maximum)); if (macro_flag) setflag__caseobj(proc_name, PROC_MACRO); else clearflag__caseobj(proc_name, PROC_MACRO); if (deflt != old_default && old_default >= 0) { the_generation = cons(NIL, NIL); } if (loadstream == stdin || varTrue(LoadNoisily)) { ndprintf(stdout, message_texts[LOAD_DEF], proc_name); } if (loadstream != stdin && varTrue(UnburyOnEdit)) { clearflag__caseobj(proc_name, PROC_BURIED); } } to_pending = 0; } deepend_proc_name = NIL; return(UNBOUND); } NODE *lto(NODE *args) { return to_helper(args, FALSE); } NODE *lmacro(NODE *args) { return to_helper(args, TRUE); } #ifdef OBJECTS /* If binding found in object hierarchy and as local, flag error, same as varValue. If binding found only in object hierarchy, set it. Otherwise (including if no binding found at all) set valnode in symbol table. Need to distinguish var local to --this-- procedure from var inherited from caller. Former is allowed to conflict with object variable. */ NODE *lmake(NODE *args) { NODE *what, *object, *bindings, *binding; what = name_arg(args); if (NOT_THROWING) { what = intern(what); if (varInObjectHierarchy(what, FALSE) != (NODE *)(-1)) { if (flag__caseobj(what, IS_LOCAL_VALUE)) { err_logo(LOCAL_AND_OBJ, what); return UNBOUND; } else { object = varInThisObject(what, FALSE); for (bindings = getvars(object); bindings != NIL; bindings = cdr(bindings)) { if (car(bindings) == what) { setobject(bindings, cadr(args)); break; } } } } else { setvalnode__caseobj(what, cadr(args)); if (!flag__caseobj(what, IS_LOCAL_VALUE)) setflag__caseobj(what, HAS_GLOBAL_VALUE); } if (flag__caseobj(what, VAL_TRACED)) { NODE *tvar = maybe_quote(cadr(args)); ndprintf(writestream, message_texts[TRACE_MAKE], make_quote(what), tvar); if (ufun != NIL) { ndprintf(writestream,message_texts[ERROR_IN],ufun,this_line); } new_line(writestream); } } return(UNBOUND); } #else /* OBJECTS */ NODE *lmake(NODE *args) { NODE *what; what = name_arg(args); if (NOT_THROWING) { what = intern(what); setvalnode__caseobj(what, cadr(args)); if (!flag__caseobj(what, IS_LOCAL_VALUE)) setflag__caseobj(what, HAS_GLOBAL_VALUE); if (flag__caseobj(what, VAL_TRACED)) { NODE *tvar = maybe_quote(cadr(args)); ndprintf(writestream, message_texts[TRACE_MAKE], make_quote(what), tvar); if (ufun != NIL) { ndprintf(writestream,message_texts[ERROR_IN],ufun,this_line); } new_line(writestream); } } return(UNBOUND); } #endif /* OBJECTS */ NODE *llocal(NODE *args) { NODE *arg = NIL; if (tailcall != 0) return UNBOUND; if (args==NIL) return UNBOUND; while (is_list(car(args)) && cdr(args) != NIL && NOT_THROWING) setcar(args, err_logo(BAD_DATA, car(args))); if (is_list(car(args))) args = car(args); while (args != NIL && NOT_THROWING) { arg = car(args); while (!is_word(arg) && NOT_THROWING) { arg = err_logo(BAD_DATA, arg); setcar(args, arg); /* prevent crash in lapply */ } if (NOT_THROWING) { arg = intern(arg); setcar(args, arg); /* local [a b] faster next time */ if (not_local(arg,var_stack)) { push(arg, var_stack); if (flag__caseobj(arg, IS_LOCAL_VALUE)) settype(var_stack, LOCALSAVE); setobject(var_stack, valnode__caseobj(arg)); setflag__caseobj(arg, IS_LOCAL_VALUE); } setvalnode__caseobj(arg, UNBOUND); tell_shadow(arg); args = cdr(args); } if (check_throwing) break; } return(UNBOUND); } NODE *lglobal(NODE *args) { NODE *arg = NIL; if (args==NIL) return UNBOUND; while (is_list(car(args)) && cdr(args) != NIL && NOT_THROWING) setcar(args, err_logo(BAD_DATA, car(args))); if (is_list(car(args))) args = car(args); while (args != NIL && NOT_THROWING) { arg = car(args); while (!is_word(arg) && NOT_THROWING) { arg = err_logo(BAD_DATA, arg); setcar(args, arg); /* prevent crash in lapply */ } if (NOT_THROWING) { arg = intern(arg); setcar(args, arg); /* local [a b] faster next time */ setflag__caseobj(arg, HAS_GLOBAL_VALUE); args = cdr(args); } if (check_throwing) break; } return(UNBOUND); } NODE *cnt_list = NIL; NODE *cnt_last = NIL; int want_buried = 0; typedef enum {c_PROCS, c_VARS, c_PLISTS, c_PRIMS} CNTLSTTYP; CNTLSTTYP contents_list_type; #ifdef OBJECTS4 /* For ancestry lists */ typedef enum {NORMAL, ANCESTRY} LSTFORM; /* For type of list wanted */ typedef enum {ACCESSIBLE, OWNED, INHERITED} LSTTYP; /* Depending on the current contents_list_type, this returns the variables or procedures of the current object. Signals error if plists */ NODE *contentsListType(NODE *obj) { switch (contents_list_type) { case c_VARS: return getvars(obj); case c_PROCS: return getprocs(obj); case c_PLISTS: err_logo(BAD_DATA, make_static_strnode("objects don't have plists!")); return; } } void normal_special_contents_map(NODE *sym) { special_contents_map(sym, NORMAL); } void ancestry_special_contents_map(NODE *sym) { special_contents_map(sym, ANCESTRY); } void fmt_map_oblist(LSTFORM format) { if (format == NORMAL) map_oblist(normal_special_contents_map); else map_oblist(ancestry_special_contents_map); } /** new things **/ /* get_contents with special format and normal format */ NODE *get_special_contents(LSTFORM format, LSTTYP type) { cnt_list = NIL; cnt_last = NIL; if (current_object == logo_object) fmt_map_oblist(format); else { /* for accessible, owned, or inherited, the current object's vars/procs have to be in cnt_list */ NODE *mylist = contentsListType(current_object); /* contains vars or procs of current object */ while (mylist != NIL) { putname(caar(mylist), current_object, format); mylist = cdr(mylist); } /* do not need to add parents' vars/procs for owned, but do for accessible and inherited */ if (type == ACCESSIBLE || type == INHERITED) { /* add your parents */ NODE *parlst = parent_list(current_object); while (parlst != NIL) { if (car(parlst) == logo_object) { fmt_map_oblist(format); } else { mylist = contentsListType(car(parlst)); while (mylist != NIL) { putname(caar(mylist), car(parlst), format); /* put name of var or proc, associated with parent object */ mylist = cdr(mylist); } } parlst = cdr(parlst); } /* if accessible, then remove the shadowed vars/procs */ if (type == ACCESSIBLE) { cnt_list = removeShadowed(cnt_list); } } } return(cnt_list); } /* used for getting the normal plist contents */ NODE *get_plistcontents() { cnt_list = NIL; cnt_last = NIL; map_oblist(contents_map); cnt_list = mergesrt(cnt_list); return(cnt_list); } /* puts name or name with object into cnt_list */ void putname(NODE *name, NODE *obj, LSTFORM format) { NODE *newNode; if (format == NORMAL) newNode = name; else newNode = cons(name, cons(obj, NIL)); if (cnt_list == NIL) { cnt_list = cons(newNode, NIL); cnt_last = cnt_list; } else { setcdr(cnt_last, newNode); cnt_last = cdr(cnt_last); } } /* contents_map for special format */ void special_contents_map(NODE *sym, LSTFORM format) { int flag_check = PROC_BURIED; if (want_buried) flag_check = want_buried; switch(contents_list_type) { case c_PROCS: if (procnode__object(sym) == UNDEFINED || is_prim(procnode__object(sym))) return; if (bck(flag__object(sym,flag_check))) return; break; case c_VARS: flag_check <<= 1; if (valnode__object(sym) == UNBOUND) return; if (bck(flag__object(sym,flag_check))) return; break; case c_PLISTS: err_logo(BAD_DATA, contents_list_type); } putname(canonical__object(sym), logo_object, format); } } /* checks if the car of the item is equal to the car of something in alist */ BOOLEAN carequal(NODE *item, NODE *alist) { while (alist != NIL) { if (car(item) == caar(alist) return true; alist = cdr(alist); } return false; } #endif int bck(int flag) { return (want_buried ? !flag : flag); } void contents_map(NODE *sym) { int flag_check = PROC_BURIED; if (want_buried) flag_check = want_buried; switch(contents_list_type) { case c_PROCS: if (procnode__object(sym) == UNDEFINED || is_prim(procnode__object(sym))) return; if (bck(flag__object(sym,flag_check))) return; break; case c_PRIMS: if (procnode__object(sym) == UNDEFINED || !is_prim(procnode__object(sym))) return; break; case c_VARS: flag_check <<= 1; if (valnode__object(sym) == UNBOUND) return; if (bck(flag__object(sym,flag_check))) return; break; case c_PLISTS: flag_check <<= 2; if (plist__object(sym) == NIL) return; if (bck(flag__object(sym,flag_check))) return; break; } if (cnt_list == NIL) { cnt_list = cons(canonical__object(sym), NIL); cnt_last = cnt_list; } else { setcdr(cnt_last, cons(canonical__object(sym), NIL)); cnt_last = cdr(cnt_last); } } void ms_listlist(NODE *nd) { while (nd != NIL) { setcar(nd, cons(car(nd), NIL)); nd = cdr(nd); } } NODE *merge(NODE *a, NODE *b) { NODE *ret, *tail; if (a == NIL) return(b); if (b == NIL) return(a); if (compare_node(car(a),car(b),FALSE) < 0) { ret = a; tail = a; a = cdr(a); } else { ret = b; tail = b; b = cdr(b); } while (a != NIL && b != NIL) { if (compare_node(car(a),car(b),FALSE) < 0) { setcdr(tail, a); a = cdr(a); } else { setcdr(tail, b); b = cdr(b); } tail = cdr(tail); } if (b == NIL) setcdr(tail, a); else setcdr(tail, b); return ret; } void mergepairs(NODE *nd) { while (nd != NIL && cdr(nd) != NIL) { setcar(nd, merge(car(nd), cadr(nd))); setcdr(nd, cddr(nd)); nd = cdr(nd); } } NODE *mergesrt(NODE *nd) { /* spelled funny to avoid library conflict */ if (nd == NIL) return(NIL); if (cdr(nd) == NIL) return(nd); ms_listlist(nd); while (cdr(nd) != NIL) mergepairs(nd); return car(nd); } NODE *get_contents() { cnt_list = NIL; cnt_last = NIL; map_oblist(contents_map); cnt_list = mergesrt(cnt_list); return(cnt_list); } #ifdef OBJECTS4 /* calls to new special_contents */ NODE *lcontents(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PLISTS; ret = cons(get_plistcontents(), NIL); contents_list_type = c_VARS; push(get_special_contents(ACCESSIBLE, NORMAL), ret); contents_list_type = c_PROCS; push(get_special_contents(ACCESSIBLE, NORMAL), ret); cnt_list = NIL; return(ret); } NODE *lburied(NODE *args) { NODE *ret; want_buried = PROC_BURIED; contents_list_type = c_PLISTS; ret = cons(get_plistcontents(), NIL); contents_list_type = c_VARS; push(get_special_contents(INHERITED, ANCESTRY), ret); contents_list_type = c_PROCS; push(get_special_contents(INHERITED, ANCESTRY), ret); cnt_list = NIL; return(ret); } NODE *ltraced(NODE *args) { NODE *ret; want_buried = PROC_TRACED; contents_list_type = c_PLISTS; ret = cons(get_plistcontents(), NIL); contents_list_type = c_VARS; push(get_special_contents(INHERITED, ANCESTRY), ret); /* not sure: INHERITED? */ contents_list_type = c_PROCS; push(get_special_contents(INHERITED, ANCESTRY), ret); /* not sure: INHERITED? */ cnt_list = NIL; return(ret); } NODE *lstepped(NODE *args) { NODE *ret; want_buried = PROC_STEPPED; contents_list_type = c_PLISTS; ret = cons(get_plistcontents(), NIL); contents_list_type = c_VARS; push(get_special_contents(INHERITED, ANCESTRY), ret); /* not sure: INHERITED? */ contents_list_type = c_PROCS; push(get_special_contents(INHERITED, ANCESTRY), ret); /* not sure: INHERITED? */ cnt_list = NIL; return(ret); } NODE *lprocedures(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PROCS; ret = get_special_contents(ACCESSIBLE, NORMAL); cnt_list = NIL; return(ret); } NODE *lnames(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_VARS; ret = cons(NIL, cons(get_special_contents(ACCESSIBLE, NORMAL), NIL)); cnt_list = NIL; return(ret); } NODE *lplists(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PLISTS; ret = cons(NIL, cons(NIL, cons(get_plistcontents(), NIL))); cnt_list = NIL; return(ret); } #else /* OBJECTS */ NODE *lcontents(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PLISTS; ret = cons(get_contents(), NIL); contents_list_type = c_VARS; push(get_contents(), ret); contents_list_type = c_PROCS; push(get_contents(), ret); cnt_list = NIL; return(ret); } NODE *lburied(NODE *args) { NODE *ret; want_buried = PROC_BURIED; contents_list_type = c_PLISTS; ret = cons(get_contents(), NIL); contents_list_type = c_VARS; push(get_contents(), ret); contents_list_type = c_PROCS; push(get_contents(), ret); cnt_list = NIL; return(ret); } NODE *ltraced(NODE *args) { NODE *ret; want_buried = PROC_TRACED; contents_list_type = c_PLISTS; ret = cons(get_contents(), NIL); contents_list_type = c_VARS; push(get_contents(), ret); contents_list_type = c_PROCS; push(get_contents(), ret); cnt_list = NIL; return(ret); } NODE *lstepped(NODE *args) { NODE *ret; want_buried = PROC_STEPPED; contents_list_type = c_PLISTS; ret = cons(get_contents(), NIL); contents_list_type = c_VARS; push(get_contents(), ret); contents_list_type = c_PROCS; push(get_contents(), ret); cnt_list = NIL; return(ret); } NODE *lprocedures(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PROCS; ret = get_contents(); cnt_list = NIL; return(ret); } NODE *lnames(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_VARS; ret = cons(NIL, cons(get_contents(), NIL)); cnt_list = NIL; return(ret); } NODE *lplists(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PLISTS; ret = cons(NIL, cons(NIL, cons(get_contents(), NIL))); cnt_list = NIL; return(ret); } #endif /* OBJECTS */ NODE *lprimitives(NODE *args) { NODE *ret; want_buried = 0; contents_list_type = c_PRIMS; ret = get_contents(); cnt_list = NIL; return(ret); } NODE *one_list(NODE *nd) { if (!is_list(nd)) return(cons(nd,NIL)); return nd; } void three_lists(NODE *arg, NODE **proclst, NODE **varlst, NODE **plistlst) { if (nodetype(car(arg)) == CONS) arg = car(arg); if (!is_list(car(arg))) *proclst = arg; else { *proclst = car(arg); if (cdr(arg) != NIL) { *varlst = one_list(cadr(arg)); if (cddr(arg) != NIL) { *plistlst = one_list(car(cddr(arg))); } } } if (!is_list(*proclst) || !is_list(*varlst) || !is_list(*plistlst)) { err_logo(BAD_DATA_UNREC,arg); *plistlst = *varlst = *proclst = NIL; } } char *expand_slash(NODE *wd) { char *result, *cp, *cp2; int i, len = getstrlen(wd), j; for (cp = getstrptr(wd), i=0, j = len; --j >= 0; ) if (getparity(*cp++)) i++; result = malloc(len+i+1); if (result == NULL) { err_logo(OUT_OF_MEM, NIL); return 0; } for (cp = getstrptr(wd), cp2 = result, j = len; --j >= 0; ) { if (getparity(*cp)) *cp2++ = '\\'; *cp2++ = clearparity(*cp++); } *cp2 = '\0'; return result; } NODE *po_helper(NODE *arg, int just_titles) { /* just_titles is -1 for EDIT, 0 for PO, 1 for HELP, 3 for POT */ NODE *proclst = NIL, *varlst = NIL, *plistlst = NIL, *tvar = NIL; NODE *plist, *oldfullp; oldfullp = valnode__caseobj(Fullprintp); setvalnode__caseobj(Fullprintp, theName(Name_true)); three_lists(arg, &proclst, &varlst, &plistlst); while (proclst != NIL) { if (aggregate(car(proclst))) { err_logo(BAD_DATA_UNREC, car(proclst)); break; } else tvar = procnode__caseobj(intern(car(proclst))); if (tvar == UNDEFINED) { if (just_titles < 0) { ndprintf(writestream,message_texts[EMPTY_PROC],car(proclst)); } else { err_logo(DK_HOW_UNREC, car(proclst)); break; } } else if (nodetype(tvar) & NT_PRIM) { err_logo(IS_PRIM, car(proclst)); break; } else { tvar = get_bodywords(tvar,car(proclst)); if (just_titles > 2) { if (is_list(car(tvar))) print_nobrak(writestream, car(tvar)); else { char *str = expand_slash(car(tvar)); ndprintf(writestream, "%t", str); free(str); } } else while (tvar != NIL) { if (is_list(car(tvar))) { if (just_titles == 2) break; print_nobrak(writestream, car(tvar)); } else { char *str = expand_slash(car(tvar)); if (just_titles == 2 && *str != ';') break; ndprintf(writestream, "%t", str); free(str); } new_line(writestream); tvar = cdr(tvar); if (just_titles == 1) just_titles++; } new_line(writestream); } proclst = cdr(proclst); if (check_throwing) break; } while (varlst != NIL && NOT_THROWING) { if (aggregate(car(varlst))) { err_logo(BAD_DATA_UNREC, car(varlst)); break; } else tvar = maybe_quote(valnode__caseobj(intern(car(varlst)))); if (tvar == UNBOUND) { if (just_titles >= 0) { err_logo(NO_VALUE, car(varlst)); break; } } else { ndprintf(writestream, message_texts[TRACE_MAKE], make_quote(car(varlst)), tvar); new_line(writestream); } varlst = cdr(varlst); if (check_throwing) break; } while (plistlst != NIL && NOT_THROWING) { if (aggregate(car(plistlst))) { err_logo(BAD_DATA_UNREC, car(plistlst)); break; } else { plist = plist__caseobj(intern(car(plistlst))); if (plist != NIL && just_titles > 0) { ndprintf(writestream, message_texts[POT_PLIST], maybe_quote(car(plistlst)), plist); } else while (plist != NIL) { ndprintf(writestream, "%t %s %s %s\n", message_texts[TRACE_PPROP], maybe_quote(car(plistlst)), maybe_quote(car(plist)), maybe_quote(cadr(plist))); plist = cddr(plist); } } plistlst = cdr(plistlst); if (check_throwing) break; } setvalnode__caseobj(Fullprintp, oldfullp); return(UNBOUND); } NODE *lpo(NODE *arg) { return(po_helper(arg,0)); } NODE *lpot(NODE *arg) { return(po_helper(arg,3)); } NODE *lerase(NODE *arg) { NODE *proclst = NIL, *varlst = NIL, *plistlst = NIL; NODE *nd, *what; int redef = (varTrue(Redefp)); three_lists(arg, &proclst, &varlst, &plistlst); if (proclst != NIL) the_generation = cons(NIL, NIL); while (proclst != NIL) { if (aggregate(car(proclst))) { err_logo(BAD_DATA_UNREC, car(proclst)); break; } nd = intern(car(proclst)); if (!redef && is_prim(procnode__caseobj(nd))) { err_logo(IS_PRIM, nd); break; } setprocnode__caseobj(nd, UNDEFINED); proclst = cdr(proclst); } while (varlst != NIL && NOT_THROWING) { if (aggregate(car(varlst))) { err_logo(BAD_DATA_UNREC, car(varlst)); break; } what = intern(car(varlst)); setvalnode__caseobj(what, UNBOUND); if (!flag__caseobj(what, IS_LOCAL_VALUE)) clearflag__caseobj(what, HAS_GLOBAL_VALUE); varlst = cdr(varlst); } while (plistlst != NIL && NOT_THROWING) { if (aggregate(car(plistlst))) { err_logo(BAD_DATA_UNREC, car(plistlst)); break; } setplist__caseobj(intern(car(plistlst)), NIL); plistlst = cdr(plistlst); } return(UNBOUND); } NODE *erall_helper(BOOLEAN procs, BOOLEAN vals, BOOLEAN plists) { NODE *nd, *obj; int loop; int redef = (varTrue(Redefp)); for (loop = 0; loop < HASH_LEN ; loop++) { for (nd = hash_table[loop]; nd != NIL; nd = cdr(nd)) { obj = car(nd); if (procs && !flag__object(obj, PROC_BURIED) && (procnode__object(obj) != UNDEFINED) && (redef || !is_prim(procnode__object(obj)))) setprocnode__object(obj, UNDEFINED); if (vals && !flag__object(obj, VAL_BURIED)) setvalnode__object(obj, UNBOUND); if (plists && !flag__object(obj, PLIST_BURIED)) setplist__object(obj, NIL); } } return UNBOUND; } NODE *lerall(NODE *args) { return erall_helper(TRUE, TRUE, TRUE); } NODE *lerps(NODE *args) { return erall_helper(TRUE, FALSE, FALSE); } NODE *lerns(NODE *args) { return erall_helper(FALSE, TRUE, FALSE); } NODE *lerpls(NODE *args) { return erall_helper(FALSE, FALSE, TRUE); } NODE *bury_helper(NODE *arg, BOOLEAN flag, BOOLEAN setp) { NODE *proclst = NIL, *varlst = NIL, *plistlst = NIL; three_lists(arg, &proclst, &varlst, &plistlst); while (proclst != NIL) { if (aggregate(car(proclst))) { err_logo(BAD_DATA_UNREC, car(proclst)); break; } if (setp) setflag__caseobj(intern(car(proclst)), flag); else return torf(flag__caseobj(intern(car(proclst)), flag)); proclst = cdr(proclst); if (check_throwing) break; } flag <<= 1; while (varlst != NIL && NOT_THROWING) { if (aggregate(car(varlst))) { err_logo(BAD_DATA_UNREC, car(varlst)); break; } if (setp) setflag__caseobj(intern(car(varlst)), flag); else return torf(flag__caseobj(intern(car(varlst)), flag)); varlst = cdr(varlst); if (check_throwing) break; } flag <<= 1; while (plistlst != NIL && NOT_THROWING) { if (aggregate(car(plistlst))) { err_logo(BAD_DATA_UNREC, car(plistlst)); break; } if (setp) setflag__caseobj(intern(car(plistlst)), flag); else return torf(flag__caseobj(intern(car(plistlst)), flag)); plistlst = cdr(plistlst); if (check_throwing) break; } if (!setp) err_logo(BAD_DATA_UNREC, NIL); return(UNBOUND); } NODE *lbury(NODE *arg) { return bury_helper(arg,PROC_BURIED,TRUE); } NODE *ltrace(NODE *arg) { return bury_helper(arg,PROC_TRACED,TRUE); } NODE *lstep(NODE *arg) { return bury_helper(arg,PROC_STEPPED,TRUE); } NODE *lburiedp(NODE *arg) { return bury_helper(arg,PROC_BURIED,FALSE); } NODE *ltracedp(NODE *arg) { return bury_helper(arg,PROC_TRACED,FALSE); } NODE *lsteppedp(NODE *arg) { return bury_helper(arg,PROC_STEPPED,FALSE); } NODE *unbury_helper(NODE *arg, int flag) { NODE *proclst = NIL, *varlst = NIL, *plistlst = NIL; three_lists(arg, &proclst, &varlst, &plistlst); while (proclst != NIL) { if (aggregate(car(proclst))) { err_logo(BAD_DATA_UNREC, car(proclst)); break; } clearflag__caseobj(intern(car(proclst)), flag); proclst = cdr(proclst); if (check_throwing) break; } flag <<= 1; while (varlst != NIL && NOT_THROWING) { if (aggregate(car(varlst))) { err_logo(BAD_DATA_UNREC, car(varlst)); break; } clearflag__caseobj(intern(car(varlst)), flag); varlst = cdr(varlst); if (check_throwing) break; } flag <<= 1; while (plistlst != NIL && NOT_THROWING) { if (aggregate(car(plistlst))) { err_logo(BAD_DATA_UNREC, car(plistlst)); break; } clearflag__caseobj(intern(car(plistlst)), flag); plistlst = cdr(plistlst); if (check_throwing) break; } return(UNBOUND); } NODE *lunbury(NODE *arg) { return unbury_helper(arg,PROC_BURIED); } NODE *luntrace(NODE *arg) { return unbury_helper(arg,PROC_TRACED); } NODE *lunstep(NODE *arg) { return unbury_helper(arg,PROC_STEPPED); } char *addsep(char *path) { static char result[70]; strcpy(result, path); if (result[0]) strcat(result, separator); return result; } char tmp_filename[500] = ""; NODE *leditfile(NODE *args) { NODE *arg = cnv_node_to_strnode(car(args)); if (NOT_THROWING) { noparity_strnzcpy(tmp_filename, getstrptr(arg), getstrlen(arg)); return ledit(NIL); } else return UNBOUND; } NODE *ledit(NODE *args) { FILE *holdstrm; #ifdef unix #ifndef HAVE_UNISTD_H extern int getpid(); #endif #endif #ifdef __RZTC__ BOOLEAN was_graphics; #endif NODE *tmp_line = NIL, *exec_list = NIL; if (tmp_filename[0] == '\0' || args != NIL) { #ifndef unix sprintf(tmp_filename, "%stemp.txt", addsep(tempdir)); #else sprintf(tmp_filename, "%s/logo%d", tempdir, (int)getpid()); #endif } if (args != NIL) { holdstrm = writestream; writestream = fopen(tmp_filename, "w"); if (writestream != NULL) { po_helper(args,-1); fclose(writestream); writestream = holdstrm; } else { err_logo(FILE_ERROR, make_static_strnode("Could not create editor file")); writestream = holdstrm; return(UNBOUND); } } if (stopping_flag == THROWING) return(UNBOUND); #ifdef mac if (!mac_edit()) return(UNBOUND); #else /* !mac */ #ifdef HAVE_WX // do something wxEditFile(tmp_filename); #else #ifdef ibm #ifdef __RZTC__ was_graphics = in_graphics_mode; if (in_graphics_mode) t_screen(); zflush(); #endif /* ztc */ if (spawnlp(P_WAIT, editor, editorname, tmp_filename, NULL)) { err_logo(FILE_ERROR, make_static_strnode ("Could not launch the editor")); return(UNBOUND); } #ifdef __RZTC__ if (was_graphics) s_screen(); else lcleartext(NIL); #endif /* ztc */ #ifdef WIN32 win32_repaint_screen(); #endif #else /* !ibm (so unix) */ if (fork() == 0) { execlp(editor, editorname, tmp_filename, 0); exit(1); } wait(0); #endif /* ibm */ #endif /* wx */ #endif /* mac */ holdstrm = loadstream; tmp_line = current_line; loadstream = fopen(tmp_filename, "r"); if (loadstream != NULL) { while (!feof(loadstream) && NOT_THROWING) { current_line = reader(loadstream, ""); exec_list = parser(current_line, TRUE); if (exec_list != NIL) eval_driver(exec_list); } fclose(loadstream); } else err_logo(FILE_ERROR, make_static_strnode("Could not read editor file")); loadstream = holdstrm; current_line = tmp_line; return(UNBOUND); } NODE *lthing(NODE *args) { NODE *val = UNBOUND, *arg; arg = name_arg(args); #ifdef OBJECTS if (NOT_THROWING) val = varValue(arg); #else if (NOT_THROWING) val = valnode__caseobj(intern(arg)); #endif while (val == UNBOUND && NOT_THROWING) val = err_logo(NO_VALUE, car(args)); return(val); } NODE *lnamep(NODE *args) { NODE *arg; arg = name_arg(args); if (NOT_THROWING) #ifdef OBJECTS return torf(varValue(arg) != UNBOUND); #else return torf(valnode__caseobj(intern(arg)) != UNBOUND); #endif return UNBOUND; } NODE *lprocedurep(NODE *args) { NODE *arg; arg = name_arg(args); if (NOT_THROWING) return torf(procnode__caseobj(intern(arg)) != UNDEFINED); return UNBOUND; } NODE *lplistp(NODE *args) { NODE *arg; arg = name_arg(args); if (NOT_THROWING) return torf(plist__caseobj(intern(arg)) != NIL); return UNBOUND; } NODE *check_proctype(NODE *args, int wanted) { NODE *arg, *cell = NIL; int isprim; arg = proc_name_arg(args); if (NOT_THROWING && (cell = procnode__caseobj(intern(arg))) == UNDEFINED) { return(FalseName()); } if (wanted == 2) return torf(is_macro(intern(arg))); isprim = is_prim(cell); if (NOT_THROWING) return torf((isprim != 0) == wanted); return(UNBOUND); } NODE *lprimitivep(NODE *args) { return(check_proctype(args,1)); } NODE *ldefinedp(NODE *args) { return(check_proctype(args,0)); } NODE *lmacrop(NODE *args) { return(check_proctype(args,2)); } NODE *larity(NODE *args) { NODE *arg = proc_name_arg(args); FIXNUM min; if (NOT_THROWING) { arg = procnode__caseobj(intern(arg)); if is_prim(arg) { min = getprimmin(arg); if (min == OK_NO_ARG) min = 0; return cons_list(0, make_intnode(min), make_intnode(getprimdflt(arg)), make_intnode(getprimmax(arg)), END_OF_LIST); } else if (arg == UNDEFINED) { err_logo(DK_HOW_UNREC, car(args)); return UNBOUND; } else { return cons_list(0, minargs__procnode(arg), dfltargs__procnode(arg), maxargs__procnode(arg), END_OF_LIST); } } return UNBOUND; } NODE *cpdf_newname(NODE *name, NODE*titleline) { NODE *nname=cnv_node_to_strnode(name); char *namestr=getstrptr(nname); char *titlestr=getstrptr(titleline); char buf[2000]; char *p1, *p2; p1 = titlestr+strcspn(titlestr, " \t"); p1 = p1+strspn(p1, " \t"); p2 = p1+strcspn(p1, " \t"); sprintf(buf, "%.*s%.*s%s", p1-titlestr, titlestr, getstrlen(nname), namestr, p2); return make_strnode(buf, NULL, strlen(buf), STRING, strcpy); } NODE *lcopydef(NODE *args) { NODE *arg1, *arg2; int redef = (varTrue(Redefp)); int old_default = -1, new_default; arg1 = proc_name_arg(args); arg2 = proc_name_arg(cdr(args)); if (NOT_THROWING) { arg1 = intern(arg1); arg2 = intern(arg2); } if (NOT_THROWING && procnode__caseobj(arg2) == UNDEFINED) err_logo(DK_HOW, arg2); if (NOT_THROWING && !redef && is_prim(procnode__caseobj(arg1))) err_logo(IS_PRIM, arg1); if (NOT_THROWING) { NODE *old_proc = procnode__caseobj(arg1); NODE *new_proc = procnode__caseobj(arg2); if (old_proc != UNDEFINED) { old_default = (is_prim(old_proc) ? getprimdflt(old_proc) : getint(dfltargs__procnode(old_proc))); } new_default = (is_prim(new_proc) ? getprimdflt(new_proc) : getint(dfltargs__procnode(new_proc))); if (old_default != new_default && old_default >= 0) { the_generation = cons(NIL, NIL); } if (is_prim(new_proc)) setprocnode__caseobj(arg1, new_proc); else { NODE *bwds=get_bodywords(new_proc,arg1); /* 5.5 */ setprocnode__caseobj(arg1, make_procnode(text__procnode(new_proc), cons(cpdf_newname(arg1,car(bwds)), cdr(bwds)), getint(minargs__procnode(new_proc)), getint(dfltargs__procnode(new_proc)), getint(maxargs__procnode(new_proc)))); } /* setflag__caseobj(arg1, PROC_BURIED); */ if (is_macro(arg2)) setflag__caseobj(arg1, PROC_MACRO); else clearflag__caseobj(arg1, PROC_MACRO); if (flag__caseobj(arg2, PROC_SPECFORM)) setflag__caseobj(arg1, PROC_SPECFORM); else clearflag__caseobj(arg1, PROC_SPECFORM); } return(UNBOUND); } char *fixhelp(char *ptr, int len) { static char result[32]; char *p, c; for (p = result; --len >= 0; *p++ = c) { c = *ptr++; if (c == '?') c = 'p'; else if (c == '.') c = 'd'; } *p = 0; return result; } char inops[] = "+-*/=<>"; NODE *lhelp(NODE *args) { NODE *arg = NIL, *pproc; char buffer[200]; #ifndef WIN32 char junk[20]; #endif FILE *fp; int lines; #ifdef __RZTC__ size_t len; #endif if (args == NIL) { /* #ifdef WIN32 sprintf(buffer, "%sHELPCONT", addsep(helpfiles)); #else */ sprintf(buffer, "%sHELPCONTENTS", addsep(helpfiles)); /* #endif */ } else if (is_word(car(args)) && car(args) != Null_Word) { arg = llowercase(args); /* setcar(args, arg); */ if (getstrlen(arg) == 1) { char *cp = strchr(inops,*(getstrptr(arg))); if (cp != NULL) { arg=cnv_node_to_strnode(theName(Name_sum+(cp-inops))); } } if (getstrlen(arg) == 2) { if (!strncmp(getstrptr(arg), "<=", 2)) arg=cnv_node_to_strnode(theName(Name_lessequalp)); if (!strncmp(getstrptr(arg), ">=", 2)) arg=cnv_node_to_strnode(theName(Name_greaterequalp)); if (!strncmp(getstrptr(arg), "<>", 2)) arg=cnv_node_to_strnode(theName(Name_notequalp)); } sprintf(buffer, "%s%s", addsep(helpfiles), fixhelp(getstrptr(arg), getstrlen(arg))); #ifdef __RZTC__ /* defined(ibm) || defined(WIN32) */ if (strlen(buffer) > (len = strlen(addsep(helpfiles))+8)) { buffer[len+5] = '\0'; buffer[len+4] = buffer[len+3]; buffer[len+3] = buffer[len+2]; buffer[len+2] = buffer[len+1]; buffer[len+1] = buffer[len]; buffer[len] = '.'; } #endif } else { err_logo(BAD_DATA_UNREC, car(args)); return UNBOUND; } fp = fopen(buffer, "r"); if (fp == NULL) { if (args == NIL) ndprintf(writestream, message_texts[NO_HELP]); else { pproc = procnode__caseobj(intern(car(args))); if (is_list(pproc)) { po_helper(args, 1); } else ndprintf(writestream, message_texts[NO_HELPON], arg); } } else { (void)ltextscreen(NIL); lines = 0; fgets(buffer, 200, fp); while (NOT_THROWING && !feof(fp)) { if (interactive && writestream==stdout && ++lines >= y_max) { ndprintf(writestream, message_texts[MORE_HELP]); input_blocking++; #ifndef TIOCSTI if (!setjmp(iblk_buf)) #endif #ifdef __RZTC__ ztc_getcr(); print_char(stdout, '\n'); #else #ifdef WIN32 (void)reader(stdin, ""); #else fgets(junk, 19, stdin); #endif #endif input_blocking = 0; update_coords('\n'); lines = 1; } ndprintf(writestream, "%t", buffer); fgets(buffer, 200, fp); } fclose(fp); } return UNBOUND; } ucblogo-5.5/intern.c0100644000161300001330000000761107547072620012411 0ustar bhdoe/* * intern.c logo data interning module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "logo.h" #include "globals.h" NODE *hash_table[HASH_LEN] = {NIL}; void map_oblist(void (*fcn)()) { int i; NODE *nd; for (i = 0; i < HASH_LEN; i++) for (nd = hash_table[i]; nd != NIL; nd = cdr(nd)) (*fcn) (car(nd)); } FIXNUM hash(char *s, int len) { /* Map S to an integer in the range 0 .. HASH_LEN-1. */ /* Method attributed to Peter Weinberger, adapted from Aho, Sethi, */ /* and Ullman's book, Compilers: Principles, Techniques, and */ /* Tools; figure 7.35. */ unsigned FIXNUM h = 0, g; while (--len >= 0) { h = (h << 4) + (FIXNUM)(*s++); g = h & (0xf << (WORDSIZE-4)); if (g != 0) { h ^= g ^ (g >> (WORDSIZE-8)); } } return h % HASH_LEN; } NODE *make_case(NODE *casestrnd, NODE *obj) { NODE *new_caseobj, *clistptr; clistptr = caselistptr__object(obj); new_caseobj = make_caseobj(casestrnd, obj); setcdr(clistptr, cons(new_caseobj, cdr(clistptr))); return(new_caseobj); } NODE *make_object(NODE *canonical, NODE *oproc, NODE *val, NODE *plist, NODE *casestrnd) { NODE *temp; temp = cons_list(0, canonical, oproc, val, plist, make_intnode((FIXNUM)0), END_OF_LIST); make_case(casestrnd, temp); return(temp); } NODE *make_instance(NODE *casend, NODE *lownd) { NODE *obj; FIXNUM hashind; /* Called only if arg isn't already in hash table */ obj = make_object(lownd, UNDEFINED, UNBOUND, NIL, casend); hashind = hash(getstrptr(lownd), getstrlen(lownd)); push(obj,(hash_table[hashind])); return car(caselist__object(obj)); } NODE *find_instance(NODE *lownd) { NODE *hash_entry, *thisobj = NIL; int cmpresult; hash_entry = hash_table[hash(getstrptr(lownd), getstrlen(lownd))]; while (hash_entry != NIL) { thisobj = car(hash_entry); cmpresult = compare_node(lownd, canonical__object(thisobj), FALSE); if (cmpresult == 0) break; else hash_entry = cdr(hash_entry); } if (hash_entry == NIL) return(NIL); else return(thisobj); } int case_compare(NODE *nd1, NODE *nd2) { if (backslashed(nd1) && backslashed(nd2)) { if (getstrlen(nd1) != getstrlen(nd2)) return(1); return(strncmp(getstrptr(nd1), getstrptr(nd2), getstrlen(nd1))); } if (backslashed(nd1) || backslashed(nd2)) return(1); return(compare_node(nd1, nd2, FALSE)); } NODE *find_case(NODE *strnd, NODE *obj) { NODE *clist; clist = caselist__object(obj); while (clist != NIL && case_compare(strnd, strnode__caseobj(car(clist)))) clist = cdr(clist); if (clist == NIL) return(NIL); else return(car(clist)); } NODE *intern(NODE *nd) { NODE *obj, *casedes, *lownd; if (nodetype(nd) == CASEOBJ) return(nd); nd = cnv_node_to_strnode(nd); lownd = make_strnode(getstrptr(nd), (struct string_block *)NULL, getstrlen(nd), STRING, noparitylow_strnzcpy); if ((obj = find_instance(lownd)) != NIL) { if ((casedes = find_case(nd, obj)) == NIL) casedes = make_case(nd, obj); } else casedes = make_instance(nd, lownd); return(casedes); } ucblogo-5.5/lists.c0100644000161300001330000004213210137762026012240 0ustar bhdoe/* * lists.c logo list functions module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "logo.h" #include "globals.h" #include NODE *bfable_arg(NODE *args) { NODE *arg = car(args); while ((arg == NIL || arg == UNBOUND || arg == Null_Word || nodetype(arg) == ARRAY) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } return arg; } NODE *list_arg(NODE *args) { NODE *arg = car(args); while (!(arg == NIL || is_list(arg)) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } return arg; } NODE *lbutfirst(NODE *args) { NODE *val = UNBOUND, *arg; arg = bfable_arg(args); if (NOT_THROWING) { if (is_list(arg)) val = cdr(arg); else { setcar(args, cnv_node_to_strnode(arg)); arg = car(args); if (getstrlen(arg) > 1) val = make_strnode(getstrptr(arg) + 1, getstrhead(arg), getstrlen(arg) - 1, nodetype(arg), strnzcpy); else val = Null_Word; } } return(val); } NODE *lbutlast(NODE *args) { NODE *val = UNBOUND, *lastnode = NIL, *tnode, *arg; arg = bfable_arg(args); if (NOT_THROWING) { if (is_list(arg)) { args = arg; val = NIL; while (cdr(args) != NIL) { tnode = cons(car(args), NIL); if (val == NIL) { val = tnode; lastnode = tnode; } else { setcdr(lastnode, tnode); lastnode = tnode; } args = cdr(args); if (check_throwing) break; } } else { setcar(args, cnv_node_to_strnode(arg)); arg = car(args); if (getstrlen(arg) > 1) val = make_strnode(getstrptr(arg), getstrhead(arg), getstrlen(arg) - 1, nodetype(arg), strnzcpy); else val = Null_Word; } } return(val); } NODE *lfirst(NODE *args) { NODE *val = UNBOUND, *arg; if (nodetype(car(args)) == ARRAY) { return make_intnode((FIXNUM)getarrorg(car(args))); } arg = bfable_arg(args); if (NOT_THROWING) { if (is_list(arg)) val = car(arg); else { setcar(args, cnv_node_to_strnode(arg)); arg = car(args); val = make_strnode(getstrptr(arg), getstrhead(arg), 1, nodetype(arg), strnzcpy); } } return(val); } NODE *lfirsts(NODE *args) { NODE *val = UNBOUND, *arg, *argp, *tail; arg = list_arg(args); if (car(args) == NIL) return(NIL); if (NOT_THROWING) { val = cons(lfirst(arg), NIL); tail = val; for (argp = cdr(arg); argp != NIL; argp = cdr(argp)) { setcdr(tail, cons(lfirst(argp), NIL)); tail = cdr(tail); if (check_throwing) break; } if (stopping_flag == THROWING) { return UNBOUND; } } return(val); } NODE *lbfs(NODE *args) { NODE *val = UNBOUND, *arg, *argp, *tail; arg = list_arg(args); if (car(args) == NIL) return(NIL); if (NOT_THROWING) { val = cons(lbutfirst(arg), NIL); tail = val; for (argp = cdr(arg); argp != NIL; argp = cdr(argp)) { setcdr(tail, cons(lbutfirst(argp), NIL)); tail = cdr(tail); if (check_throwing) break; } if (stopping_flag == THROWING) { return UNBOUND; } } return(val); } NODE *llast(NODE *args) { NODE *val = UNBOUND, *arg; arg = bfable_arg(args); if (NOT_THROWING) { if (is_list(arg)) { args = arg; while (cdr(args) != NIL) { args = cdr(args); if (check_throwing) break; } val = car(args); } else { setcar(args, cnv_node_to_strnode(arg)); arg = car(args); val = make_strnode(getstrptr(arg) + getstrlen(arg) - 1, getstrhead(arg), 1, nodetype(arg), strnzcpy); } } return(val); } NODE *llist(NODE *args) { return(args); } NODE *lemptyp(NODE *arg) { return torf(car(arg) == NIL || car(arg) == Null_Word); } NODE *char_arg(NODE *args) { NODE *arg = car(args), *val; val = cnv_node_to_strnode(arg); while ((val == UNBOUND || getstrlen(val) != 1) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); val = cnv_node_to_strnode(arg); } setcar(args,val); return(val); } NODE *lascii(NODE *args) { FIXNUM i; NODE *val = UNBOUND, *arg; arg = char_arg(args); if (NOT_THROWING) { if (nodetype(arg) == BACKSLASH_STRING) i = (FIXNUM)(*getstrptr(arg)) & 0377; else i = (FIXNUM)clearparity(*getstrptr(arg)) & 0377; val = make_intnode(i); } return(val); } NODE *lrawascii(NODE *args) { FIXNUM i; NODE *val = UNBOUND, *arg; arg = char_arg(args); if (NOT_THROWING) { i = (FIXNUM)((unsigned char)*getstrptr(arg)); val = make_intnode(i); } return(val); } NODE *lbackslashedp(NODE *args) { char i; NODE *arg; arg = char_arg(args); if (NOT_THROWING) { i = *getstrptr(arg); return torf(getparity(i)); } return(UNBOUND); } NODE *lchar(NODE *args) { NODE *val = UNBOUND, *arg; char c; arg = pos_int_arg(args); if (NOT_THROWING) { c = (char)getint(arg); val = make_strnode(&c, (struct string_block *)NULL, 1, STRING, strnzcpy); } return(val); } NODE *lcount(NODE *args) { int cnt = 0; NODE *arg; arg = car(args); if (arg != NIL && arg != Null_Word) { if (is_list(arg)) { args = arg; for (; args != NIL; cnt++) { args = cdr(args); if (check_throwing) break; } } else if (nodetype(arg) == ARRAY) { cnt = getarrdim(arg); } else { setcar(args, cnv_node_to_strnode(arg)); cnt = getstrlen(car(args)); } } return(make_intnode((FIXNUM)cnt)); } NODE *lfput(NODE *args) { NODE *lst, *arg; if (is_word(cadr(args)) && is_word(car(args)) && getstrlen(cnv_node_to_strnode(car(args))) == 1) return lword(args); arg = car(args); lst = list_arg(cdr(args)); if (NOT_THROWING) return cons(arg,lst); else return UNBOUND; } NODE *llput(NODE *args) { NODE *lst, *arg, *val = UNBOUND, *lastnode = NIL, *tnode = NIL; if (is_word(cadr(args)) && is_word(car(args)) && getstrlen(cnv_node_to_strnode(car(args))) == 1) return lword(cons(cadr(args), cons(car(args), NIL))); arg = car(args); lst = list_arg(cdr(args)); if (NOT_THROWING) { val = NIL; while (lst != NIL) { tnode = cons(car(lst), NIL); if (val == NIL) { val = tnode; } else { setcdr(lastnode, tnode); } lastnode = tnode; lst = cdr(lst); if (check_throwing) break; } if (val == NIL) val = cons(arg, NIL); else setcdr(lastnode, cons(arg, NIL)); } return(val); } NODE *string_arg(NODE *args) { NODE *arg = car(args), *val; val = cnv_node_to_strnode(arg); while (val == UNBOUND && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); val = cnv_node_to_strnode(arg); } setcar(args,val); return(val); } NODE *lword(NODE *args) { NODE *val = NIL, *arg = NIL; int cnt = 0; NODETYPES str_type = STRING; if (args == NIL) return Null_Word; val = args; while (val != NIL && NOT_THROWING) { arg = string_arg(val); val = cdr(val); if (NOT_THROWING) { if (backslashed(arg)) str_type = VBAR_STRING; cnt += getstrlen(arg); } } if (NOT_THROWING) val = make_strnode((char *)args, (struct string_block *)NULL, cnt, str_type, word_strnzcpy); /* kludge */ else val = UNBOUND; return(val); } NODE *lsentence(NODE *args) { NODE *tnode = NIL, *lastnode = NIL, *val = NIL, *arg = NIL; while (args != NIL && NOT_THROWING) { arg = car(args); while (nodetype(arg) == ARRAY && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); } args = cdr(args); if (stopping_flag == THROWING) break; if (is_list(arg)) { if (args == NIL) { /* 5.2 */ if (val == NIL) val = arg; else setcdr(lastnode, arg); break; } else while (arg != NIL && NOT_THROWING) { tnode = cons(car(arg), NIL); arg = cdr(arg); if (val == NIL) val = tnode; else setcdr(lastnode, tnode); lastnode = tnode; } } else { tnode = cons(arg, NIL); if (val == NIL) val = tnode; else setcdr(lastnode, tnode); lastnode = tnode; } } if (stopping_flag == THROWING) { return UNBOUND; } return(val); } NODE *lwordp(NODE *arg) { arg = car(arg); return torf(arg != UNBOUND && !aggregate(arg)); } NODE *llistp(NODE *arg) { arg = car(arg); return torf(is_list(arg)); } NODE *lnumberp(NODE *arg) { setcar(arg, cnv_node_to_numnode(car(arg))); return torf(car(arg) != UNBOUND); } NODE *larrayp(NODE *arg) { return torf(nodetype(car(arg)) == ARRAY); } NODE *memberp_help(NODE *args, BOOLEAN notp, BOOLEAN substr) { NODE *obj1, *obj2, *val; int leng; int caseig = varTrue(Caseignoredp); val = FalseName(); obj1 = car(args); obj2 = cadr(args); if (is_list(obj2)) { if (substr) return FalseName(); while (obj2 != NIL && NOT_THROWING) { if (equalp_help(obj1, car(obj2), caseig)) return (notp ? obj2 : TrueName()); obj2 = cdr(obj2); if (check_throwing) break; } return (notp ? NIL : FalseName()); } else if (nodetype(obj2) == ARRAY) { int len = getarrdim(obj2); NODE **data = getarrptr(obj2); if (notp) err_logo(BAD_DATA_UNREC,obj2); if (substr) return FalseName(); while (--len >= 0 && NOT_THROWING) { if (equalp_help(obj1, *data++, caseig)) return TrueName(); } return FalseName(); } else { NODE *tmp; int i; if (aggregate(obj1)) return (notp ? Null_Word : FalseName()); setcar (cdr(args), cnv_node_to_strnode(obj2)); obj2 = cadr(args); setcar (args, cnv_node_to_strnode(obj1)); obj1 = car(args); tmp = NIL; if (obj1 != UNBOUND && obj2 != UNBOUND && getstrlen(obj1) <= getstrlen(obj2) && (substr || (getstrlen(obj1) == 1))) { leng = getstrlen(obj2) - getstrlen(obj1); setcar(cdr(args),make_strnode(getstrptr(obj2), getstrhead(obj2), getstrlen(obj1), nodetype(obj2), strnzcpy)); tmp = cadr(args); for (i = 0; i <= leng; i++) { if (equalp_help(obj1, tmp, caseig)) { if (notp) { setstrlen(tmp,leng+getstrlen(obj1)-i); return tmp; } else return TrueName(); } setstrptr(tmp, getstrptr(tmp) + 1); } } return (notp ? Null_Word : FalseName()); } } NODE *lmemberp(NODE *args) { return(memberp_help(args, FALSE, FALSE)); } NODE *lsubstringp(NODE *args) { return(memberp_help(args, FALSE, TRUE)); } NODE *lmember(NODE *args) { return(memberp_help(args, TRUE, FALSE)); } NODE *integer_arg(NODE *args) { NODE *arg = car(args), *val; FIXNUM i; FLONUM f; val = cnv_node_to_numnode(arg); while ((nodetype(val) != INT) && NOT_THROWING) { if (nodetype(val) == FLOATT && fmod((f = getfloat(val)), 1.0) == 0.0 && f >= -(FLONUM)MAXLOGOINT && f < (FLONUM)MAXLOGOINT) { #if HAVE_IRINT i = irint(f); #else i = (FIXNUM)f; #endif val = make_intnode(i); break; } setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); val = cnv_node_to_numnode(arg); } setcar(args,val); if (nodetype(val) == INT) return(val); return UNBOUND; } FIXNUM int_arg(NODE *args) { NODE *arg =integer_arg(args); if (NOT_THROWING) return getint(arg); return 0; } NODE *litem(NODE *args) { int i; NODE *obj, *val; val = integer_arg(args); obj = cadr(args); while ((obj == NIL || obj == Null_Word) && NOT_THROWING) { setcar(cdr(args), err_logo(BAD_DATA, obj)); obj = cadr(args); } if (NOT_THROWING) { i = getint(val); if (is_list(obj)) { if (i <= 0) { err_logo(BAD_DATA_UNREC, val); return UNBOUND; } while (--i > 0) { obj = cdr(obj); if (obj == NIL) { err_logo(BAD_DATA_UNREC, val); return UNBOUND; } } return car(obj); } else if (nodetype(obj) == ARRAY) { i -= getarrorg(obj); if (i < 0 || i >= getarrdim(obj)) { err_logo(BAD_DATA_UNREC, val); return UNBOUND; } return (getarrptr(obj))[i]; } else { if (i <= 0) { err_logo(BAD_DATA_UNREC, val); return UNBOUND; } setcar (cdr(args), cnv_node_to_strnode(obj)); obj = cadr(args); if (i > getstrlen(obj)) { err_logo(BAD_DATA_UNREC, val); return UNBOUND; } return make_strnode(getstrptr(obj) + i - 1, getstrhead(obj), 1, nodetype(obj), strnzcpy); } } return(UNBOUND); } int circular(NODE *arr, NODE *new) { if (new == NIL) return(0); else if (nodetype(new) == ARRAY) { int i = getarrdim(new); NODE **p = getarrptr(new); if (new == arr) return(1); while (--i >= 0) { if (circular(arr,*p++)) return(1); } return(0); } else if (is_list(new)) { while (new != NIL) { if (circular(arr,car(new))) return(1); new = cdr(new); } return(0); } else return(0); } NODE *setitem_helper(NODE *args, BOOLEAN safe) { int i; NODE *obj, *val, *cont; val = integer_arg(args); obj = cadr(args); while (nodetype(obj) != ARRAY && NOT_THROWING) { setcar(cdr(args), err_logo(BAD_DATA, obj)); obj = cadr(args); } cont = car(cddr(args)); if (NOT_THROWING) { i = getint(val); if (safe) { while (circular(obj,cont) && NOT_THROWING) { setcar(cddr(args), err_logo(BAD_DATA, cont)); cont = car(cddr(args)); } } if (NOT_THROWING) { i -= getarrorg(obj); while ((i < 0 || i >= getarrdim(obj)) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, val)); val = integer_arg(args); i = getint(val); } if (NOT_THROWING) { (getarrptr(obj))[i] = cont; check_valid_oldyoung(obj, cont); } } } return(UNBOUND); } NODE *lsetitem(NODE *args) { return setitem_helper(args, TRUE); } NODE *l_setitem(NODE *args) { return setitem_helper(args, FALSE); } NODE *larray(NODE *args) { NODE *arg; FIXNUM d, o; arg = pos_int_arg(args); if (cdr(args) != NIL) o = int_arg(cdr(args)); else o = 1; if (NOT_THROWING) { d = getint(arg); arg = make_array(d); setarrorg(arg,o); return arg; } return UNBOUND; } NODE *llisttoarray(NODE *args) { int len = 0, org = 1, i; NODE *p, *arr = UNBOUND; while (car(args) != NIL && !is_list(car(args)) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, car(args))); } if (cdr(args) != NIL) { p = cnv_node_to_numnode(car(cdr(args))); while (nodetype(p) != INT && NOT_THROWING) { setcar(cdr(args), err_logo(BAD_DATA, car(cdr(args)))); p = cnv_node_to_numnode(car(cdr(args))); } } if (NOT_THROWING) { for (p = car(args); p != NIL; p = cdr(p)) len++; if (cdr(args) != NIL) org = getint(car(cdr(args))); arr = make_array(len); setarrorg(arr,org); i = 0; for (p = car(args); p != NIL; p = cdr(p)) (getarrptr(arr))[i++] = car(p); } return(arr); } NODE *larraytolist(NODE *args) { NODE *p = NIL, *arg; int i; while (nodetype(car(args)) != ARRAY && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, car(args))); } if (NOT_THROWING) { arg = car(args); for (i = getarrdim(arg) - 1; i >= 0; i--) p = cons(getarrptr(arg)[i], p); return p; } return UNBOUND; } FLONUM float_arg(NODE *args) { NODE *arg = car(args), *val; val = cnv_node_to_numnode(arg); while (!is_number(val) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); arg = car(args); val = cnv_node_to_numnode(arg); } setcar(args,val); if (nodetype(val) == FLOATT) return getfloat(val); if (nodetype(val) == INT) return (FLONUM)getint(val); return 0.0; } NODE *lform(NODE *args) { FLONUM number; int width, precision = 0; char result[100]; char format[20]; number = float_arg(args); width = (int)int_arg(cdr(args)); if (width < 0) { print_stringptr = format; print_stringlen = 20; ndprintf((FILE *)NULL,"%p\n",string_arg(cddr(args))); *print_stringptr = '\0'; } else precision = (int)int_arg(cddr(args)); if (NOT_THROWING) { if (width >= 100) width = 99; if (width < 0) sprintf(result,format,number); else sprintf(result,"%*.*f",width,precision,number); return(make_strnode(result, (struct string_block *)NULL, (int)strlen(result), STRING, strnzcpy)); } return(UNBOUND); } NODE *l_setfirst(NODE *args) { NODE *list, *newval; list = car(args); newval = cadr(args); while (NOT_THROWING && (list == NIL || !is_list(list))) { setcar(args, err_logo(BAD_DATA,list)); list = car(args); } setcar(list,newval); return(UNBOUND); } NODE *l_setbf(NODE *args) { NODE *list, *newval; list = car(args); newval = cadr(args); while (NOT_THROWING && (list == NIL || !is_list(list))) { setcar(args, err_logo(BAD_DATA,list)); list = car(args); } setcdr(list,newval); return(UNBOUND); } ucblogo-5.5/logo.h0100644000161300001330000005056610274571332012061 0ustar bhdoe/* * logo.h logo header file dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _LOGO_H #define _LOGO_H /* #define OBJECTS */ /* #define MEM_DEBUG */ #define ecma /* for European extended character set using parity bit */ #ifdef WIN32 #define ibm #undef __RZTC__ #define HAVE_MEMCPY #define SIG_TAKES_ARG #endif #ifdef __ZTC__ #ifndef THINK_C #define __RZTC__ #endif #endif #ifdef THINK_C #define mac #define HAVE_MEMCPY #endif #ifdef __TURBOC__ #define ibm #endif #ifdef __RZTC__ #define ibm #define HAVE_MEMCPY #define SIG_TAKES_ARG #endif #ifdef _MSC_VER #define ibm #endif #if !defined(ibm) && !defined(mac) #ifndef unix #define unix #endif #include "config.h" #ifndef X_DISPLAY_MISSING #define x_window #endif #else #define RETSIGTYPE void #define SIGRET #ifndef STDC_HEADERS #define STDC_HEADERS #endif #endif #include #include #include #ifdef STDC_HEADERS #include #else #include #include extern char *getenv(); #endif #ifdef ibm #include #endif #ifdef mac #define check_throwing (check_mac_stop() || stopping_flag == THROWING) #else #if defined(ibm) #define check_throwing (check_ibm_stop() || stopping_flag == THROWING) #else #if defined(HAVE_X11) #define check_throwing (check_X11_stop() || stopping_flag == THROWING) #else #define check_throwing (stopping_flag == THROWING) #endif #endif #endif typedef enum {wrapmode, fencemode, windowmode} mode_type; #define WORDSIZE (8*sizeof(long)) #define NIL (NODE *) 0 #define UNBOUND Unbound #define UNDEFINED Unbound #define END_OF_LIST (NODE *) 2 #define HASH_LEN 1021 /* a prime number */ #ifdef __RZTC__ #define SEG_SIZE 2000 #else #ifdef THINK_C #define SEG_SIZE 4000 #else #define SEG_SIZE 16000 /* Should be a fairly big number for optimal GC Performance */ #endif #endif #define MAX_PHYS_LINE 5000 #define MAX_NUMBER 200 /* max number of digits in a float */ #define STOP_PRIORITY 0 #define OUTPUT_PRIORITY 1 #define MAYBE_PRIORITY 2 #define TAIL_PRIORITY 2 /* largest tailcall priority */ #define MACRO_PRIORITY 3 #define PREFIX_PRIORITY 4 typedef long int NODETYPES; #ifdef OBJECTS #define NT_OBJ (NODETYPES)040000000 #endif #define NT_LOCAL (NODETYPES)020000000 #define NT_STACK (NODETYPES)010000000 #define NT_CONT (NODETYPES)04000000 #define NT_INFIX (NODETYPES)02000000 #define NT_LINE (NODETYPES)01000000 #define NT_TAILFORM (NODETYPES)0400000 #define NT_MACRO (NODETYPES)0200000 #define NT_TREE (NODETYPES)0100000 #define NT_EMPTY (NODETYPES)040000 #define NT_AGGR (NODETYPES)020000 #define NT_LIST (NODETYPES)010000 #define NT_RUNP (NODETYPES)004000 #define NT_ARRAY (NODETYPES)002000 #define NT_WORD (NODETYPES)001000 #define NT_NUMBER (NODETYPES)000400 #define NT_FLOAT (NODETYPES)000200 #define NT_PRIM (NODETYPES)000100 #define NT_VBAR (NODETYPES)000040 #define NT_STRING (NODETYPES)000020 #define NT_BACKSL (NODETYPES)000010 #define NT_PUNCT (NODETYPES)000004 #define NT_COLON (NODETYPES)000002 #define NT_CASEOBJ (NODETYPES)000001 #define PNIL (NODETYPES)(NT_EMPTY|NT_AGGR|NT_LIST) #define PUNBOUND (NODETYPES)0 #define CONS (NODETYPES)(NT_AGGR|NT_LIST) #define STRING (NODETYPES)(NT_WORD|NT_STRING) #define INT (NODETYPES)(NT_WORD|NT_NUMBER) #define FLOATT (NODETYPES)(NT_WORD|NT_NUMBER|NT_FLOAT) #define PRIM (NODETYPES)(NT_PRIM) #define MACRO (NODETYPES)(NT_PRIM|NT_MACRO) #define TAILFORM (NODETYPES)(NT_PRIM|NT_TAILFORM) #define CASEOBJ (NODETYPES)(NT_WORD|NT_CASEOBJ) #define INFIX (NODETYPES)(NT_PRIM|NT_INFIX) #define TREE (NODETYPES)(NT_AGGR|NT_LIST|NT_TREE) #define RUN_PARSE (NODETYPES)(NT_AGGR|NT_LIST|NT_RUNP) #define QUOTE (NODETYPES)(NT_WORD|NT_PUNCT) #define COLON (NODETYPES)(NT_WORD|NT_PUNCT|NT_COLON) #define BACKSLASH_STRING (NODETYPES)(NT_WORD|NT_STRING|NT_BACKSL) #define VBAR_STRING (NODETYPES)(NT_WORD|NT_STRING|NT_BACKSL|NT_VBAR) #define ARRAY (NODETYPES)(NT_AGGR|NT_ARRAY) #define LINE (NODETYPES)(NT_LINE|NT_LIST|NT_AGGR) #define CONT (NODETYPES)(NT_CONT|NT_LIST) #define STACK (NODETYPES)(NT_STACK|NT_LIST) #define NTFREE (NODETYPES)(-1) #define LOCALSAVE (NODETYPES)(CONS|NT_LOCAL) #ifdef OBJECTS #define OBJECT (NODETYPES)(NT_OBJ) #endif #define aggregate(nd) (nodetype(nd) & NT_AGGR) #define is_cont(nd) (nodetype(nd) == CONT) #define is_list(nd) (nodetype(nd) & NT_LIST) #define is_tree(nd) (nodetype(nd) & NT_TREE) #define is_string(nd) (nodetype(nd) & NT_STRING) #define is_number(nd) (nodetype(nd) & NT_NUMBER) #define is_prim(nd) (nodetype(nd) & NT_PRIM) #define is_word(nd) (nodetype(nd) & NT_WORD) #define runparsed(nd) (nodetype(nd) & NT_RUNP) #define backslashed(nd) (nodetype(nd) & NT_BACKSL) #define is_tailform(nd) (nodetype(nd) == TAILFORM) #ifdef OBJECTS #define is_object(nd) (nodetype(nd) == NT_OBJ) #endif typedef enum { FATAL, OUT_OF_MEM, STACK_OVERFLOW, TURTLE_OUT_OF_BOUNDS, BAD_DATA_UNREC, DIDNT_OUTPUT, NOT_ENOUGH, BAD_DATA, TOO_MUCH, DK_WHAT, PAREN_MISMATCH, NO_VALUE, UNEXPECTED_PAREN, DK_HOW, NO_CATCH_TAG, ALREADY_DEFINED, STOP_ERROR, ALREADY_DRIBBLING, FILE_ERROR, IF_WARNING, SHADOW_WARN, USER_ERR, IS_PRIM, NOT_INSIDE, DK_HOW_UNREC, NO_TEST, UNEXPECTED_BRACKET, UNEXPECTED_BRACE, BAD_GRAPH_INIT, ERR_MACRO, DK_WHAT_UP, AT_TOPLEVEL, APPLY_BAD_DATA, DEEPEND, OUT_OF_MEM_UNREC, USER_ERR_MESSAGE, DEEPEND_NONAME, BAD_DEFAULT, RUNRES_STOP, MISSING_SPACE, CANT_OPEN_ERROR, ALREADY_OPEN_ERROR, NOT_OPEN_ERROR, #ifdef OBJECTS LOCAL_AND_OBJ, #endif /* below this point aren't actually error codes, just messages */ THANK_YOU, NICE_DAY, NOSHELL_MAC, TYPE_EXIT, ERROR_IN, ERRACT_LOOP, PAUS_ING, TRACE_STOPS, TRACE_OUTPUTS, NO_FILE, NO_FIONREAD, MEM_LOW, CANT_OPEN, ALREADY_OPEN, NOT_OPEN, TRACE_PPROP, WELCOME_TO, CANT_STOP, CANT_GC, EXIT_NOW, LOAD_DEF, TRACE_MAKE, EMPTY_PROC, POT_PLIST, NO_HELP, NO_HELPON, MORE_HELP, MAX_MESSAGE} ERR_TYPES; /* MAX_MESSAGE must be last */ #ifdef WIN32 #define BOOLEAN int #else typedef int BOOLEAN; #endif #define FALSE 0 #define TRUE 1 #define even_p(x) !(x & 0x1) #define FIXNUM long #define FLONUM double #define MAXLOGOINT 0x7fffffff #define SAFEINT 0x00003fff /* safe to multiply w/o overflow */ struct string_block { unsigned FIXNUM str_refcnt; char str_str[1]; /* This array will be of variable length really */ }; #define getstrrefcnt(sh) ((sh)->str_refcnt) #define setstrrefcnt(sh, v) ((sh)->str_refcnt = (v)) #define incstrrefcnt(sh) (((sh)->str_refcnt)++) #define decstrrefcnt(sh) (--((sh)->str_refcnt)) typedef struct logo_node { NODETYPES node_type; int my_gen; /* Nodes's Generation */ /*GC*/ int gen_age; /* How many times to GC at this generation */ long int mark_gc; /* when marked */ struct logo_node *next; /* Link together nodes of the same age */ /*GC*/ struct logo_node *oldyoung_next; union { struct { struct logo_node *ncar; struct logo_node *ncdr; struct logo_node *nobj; /* used only for oblist etc */ } ncons; struct { char *nstring_ptr; struct string_block *nstring_head; FIXNUM nstring_len; } nstring; struct { struct logo_node * (*nprim_fun) (); short npriority; short nmin_args; short ndef_args; short nmax_args; } nprim; FIXNUM nint; FLONUM nfloat; struct { FIXNUM narray_dim; FIXNUM narray_origin; struct logo_node **narray_data; } narray; #ifdef OBJECTS struct { struct logo_node *nvars; struct logo_node *nprocs; struct logo_node *nparents; } nobject; #endif } nunion; } NODE; #define settype(node, type) ((node)->node_type = (type)) #define n_car nunion.ncons.ncar #define n_cdr nunion.ncons.ncdr #define n_obj nunion.ncons.nobj #define getobject(node) ((node)->n_obj) #define car(node) ((node)->n_car) #define cdr(node) ((node)->n_cdr) #define caar(node) ((node)->n_car->n_car) #define cadr(node) ((node)->n_cdr->n_car) #define cdar(node) ((node)->n_car->n_cdr) #define cddr(node) ((node)->n_cdr->n_cdr) #define n_str nunion.nstring.nstring_ptr #define n_len nunion.nstring.nstring_len #define n_head nunion.nstring.nstring_head #define getstrptr(node) ((node)->n_str) #define getstrlen(node) ((node)->n_len) #define getstrhead(node) ((node)->n_head) #define setstrptr(node,ptr) ((node)->n_str = (ptr)) #define setstrlen(node,len) ((node)->n_len = (len)) #define setstrhead(node,ptr) ((node)->n_head = (ptr)) #define n_int nunion.nint #define getint(node) ((node)->n_int) #define setint(node,num) ((node)->n_int = (num)) #define n_float nunion.nfloat #define getfloat(node) ((node)->n_float) #define setfloat(node,num) ((node)->n_float = (num)) #define n_pfun nunion.nprim.nprim_fun #define n_ppri nunion.nprim.npriority #define n_pmin nunion.nprim.nmin_args #define n_pdef nunion.nprim.ndef_args #define n_pmax nunion.nprim.nmax_args #define getprimfun(node) ((node)->n_pfun) #define setprimfun(node,fun) ((node)->n_pfun = (fun)) #define getprimmin(node) ((node)->n_pmin) #define setprimmin(node,num) ((node)->n_pmin = (num)) #define getprimmax(node) ((node)->n_pmax) #define setprimmax(node,num) ((node)->n_pmax = (num)) #define getprimdflt(node) ((node)->n_pdef) #define setprimdflt(node,num) ((node)->n_pdef = (num)) #define getprimpri(node) ((node)->n_ppri) #define setprimpri(node,num) ((node)->n_ppri = (num)) /* Special value for pmin, means that it's * OK if primitive name on line by itself even though defltargs=1 (ED, CO) */ #define OK_NO_ARG 01000 #define n_dim nunion.narray.narray_dim #define n_org nunion.narray.narray_origin #define n_array nunion.narray.narray_data #define getarrdim(node) ((node)->n_dim) #define getarrorg(node) ((node)->n_org) #define getarrptr(node) ((node)->n_array) #define setarrdim(node,len) ((node)->n_dim = (len)) #define setarrorg(node,org) ((node)->n_org = (org)) #define setarrptr(node,ptr) ((node)->n_array = (ptr)) #ifdef OBJECTS #define n_vars nunion.nobject.nvars #define n_procs nunion.nobject.nprocs #define n_parents nunion.nobject.nparents #define getvars(node) ((node)->n_vars) #define getprocs(node) ((node)->n_procs) #define getparents(node) ((node)->n_parents) #define setvars(node, vars) ((node)->n_vars = (vars)) #define setprocs(node, procs) ((node)->n_procs = (procs)) #define setparents(node, parents) ((node)->n_parents = (parents)) #define getsymbol(frame) car(frame) #define getvalue(frame) cadr(frame) #endif /* OBJECTS */ #ifdef ecma #define clearparity(ch) ecma_clear(ch) #define setparity(ch) ecma_set(ch) #define getparity(ch) ecma_get(ch) #define ecma_begin 003 /* first char used for quoteds */ #else #define clearparity(ch) (ch & 0x7f) #define setparity(ch) (ch | 0x80) #define getparity(ch) (ch & 0x80) #endif typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE; struct segment { struct segment *next; FIXNUM size; #ifdef mac struct logo_node nodes[1]; #else #ifdef __RZTC__ struct logo_node nodes[1]; #else struct logo_node nodes[0]; #endif #endif }; #define NOT_THROWING (stopping_flag != THROWING) #define RUNNING (stopping_flag == RUN) #define STOPPING (stopping_flag == STOP) #define canonical__object(o) car(o) #define procnode__object(o) cadr(o) #define setprocnode__object(o,v) setcar(cdr(o), v) #define valnode__object(o) cadr(cdr(o)) #define setvalnode__object(o,v) setcar(cddr(o), v) #define plist__object(o) cadr(cddr(o)) #define setplist__object(o,v) setcar(cdr(cddr(o)), v) #define obflags__object(o) car(cddr(cddr(o))) #define caselistptr__object(o) cddr(cddr(o)) #define caselist__object(o) cdr(cddr(cddr(o))) #define strnode__caseobj(co) car(co) #define object__caseobj(c) cdr(c) #define procnode__caseobj(c) procnode__object(object__caseobj(c)) #define setprocnode__caseobj(c,v) setprocnode__object(object__caseobj(c),v) #define valnode__caseobj(c) valnode__object(object__caseobj(c)) #define setvalnode__caseobj(c,v) setvalnode__object(object__caseobj(c),v) #define plist__caseobj(c) plist__object(object__caseobj(c)) #define setplist__caseobj(c,v) setplist__object(object__caseobj(c),v) #define obflags__caseobj(c) obflags__object(object__caseobj(c)) #define text__procnode(p) car(p) #define formals__procnode(p) caar(p) #define bodylist__procnode(p) cdar(p) #define bodywords__procnode(p) cadr(p) #define setbodywords__procnode(p,v) setcar(cdr(p),v) #define minargs__procnode(p) car(cddr(p)) #define dfltargs__procnode(p) cadr(cddr(p)) #define maxargs__procnode(p) car(cddr(cddr(p))) #define unparsed__runparse(rn) rn #define parsed__runparse(rn) getobject(rn) #define node__quote(q) car(q) #define node__colon(c) car(c) #define valnode__colon(c) valnode__caseobj(node__colon(c)) #define unparsed__tree(t) t #define treepair__tree(t) (getobject(t)) #define settreepair__tree(t, v) setobject(t, v) #define generation__tree(t) (car(treepair__tree(t))) #define setgeneration__tree(t, g) setcar(treepair__tree(t), g) #define tree__tree(t) cdr(treepair__tree(t)) #define settree__tree(t, v) settreepair__tree(t, cons(the_generation, v)) #define unparsed__line(l) (getobject(l)) #define generation__line(l) (generation__tree(unparsed__line(l))) #define tree__line(l) l #define cont__cont(c) (FIXNUM)car(c) #define val__cont(c) cdr(c) /* Object flags. Ones settable by users via bury_helper must come in threes * for proc, val, plist even if meaningless for some of those. */ #define PROC_BURIED 01 #define VAL_BURIED 02 #define PLIST_BURIED 04 #define PROC_TRACED 010 #define VAL_TRACED 020 #define PLIST_TRACED 040 #define PROC_STEPPED 0100 #define VAL_STEPPED 0200 #define PLIST_STEPPED 0400 #define PROC_MACRO 01000 #define PERMANENT 02000 #define HAS_GLOBAL_VALUE 04000 #define IS_LOCAL_VALUE 010000 #ifdef OBJECTS #define MIXED_ARITY 020000 #endif #define PROC_SPECFORM 040000 #define setflag__caseobj(c,f) ((obflags__caseobj(c))->n_int |= (f)) #define clearflag__caseobj(c,f) ((obflags__caseobj(c))->n_int &= ~(f)) #define flag__caseobj(c,f) (int)((obflags__caseobj(c))->n_int & (f)) #define flag__object(o,f) (int)((obflags__object(o))->n_int & (f)) #define is_macro(c) (flag__caseobj(c, PROC_MACRO)) #define push(obj, stack) stack = cons(obj, stack) #define pop(stack) stack = cdr(stack) /* evaluator labels, needed by macros in other files */ /* (Put the commonly used ones first.) */ #ifdef OBJECTS #define do_list(x) \ x(no_reset_args) x(eval_sequence_continue) \ x(accumulate_arg) x(compound_apply_continue) \ x(after_const_arg) x(begin_seq) x(begin_apply) \ x(set_args_continue) x(macro_return) \ x(repeat_continuation) x(repeat_followup) \ x(runresult_continuation) x(runresult_followup) \ x(catch_continuation) x(catch_followup) x(after_lambda) \ x(after_maybeoutput) \ x(withobject_continuation) x(withobject_followup) \ x(goto_continuation) \ x(begin_line) x(end_line) \ x(all_done) \ x(fall_off_want_output) x(op_want_stop) x(after_constant) #else /* OBJECTS */ #define do_list(x) \ x(no_reset_args) x(eval_sequence_continue) \ x(accumulate_arg) x(compound_apply_continue) \ x(after_const_arg) x(begin_seq) x(begin_apply) \ x(set_args_continue) x(macro_return) \ x(repeat_continuation) x(repeat_followup) \ x(runresult_continuation) x(runresult_followup) \ x(catch_continuation) x(catch_followup) x(after_lambda) \ x(after_maybeoutput) \ x(goto_continuation) \ x(begin_line) x(end_line) \ x(all_done) \ x(fall_off_want_output) x(op_want_stop) x(after_constant) #endif /* OBJECTS */ #define do_enum(x) x, enum labels { do_list(do_enum) NUM_TOKENS }; /* similarly, names that might be translated in Messages file */ #ifdef OBJECTS #define do_trans(x) \ x(true) x(false) x(end) x(output) x(stop) x(goto) x(tag) \ x(if) x(ifelse) x(to) x(macro) x(toplevel) x(system) x(error) x(nothing) \ x(textscreen) x(splitscreen) x(fullscreen) x(paint) x(erase) x(reverse) \ x(wrap) x(fence) x(window) x(sum) x(difference) x(product) x(quotient) \ x(equalp) x(lessp) x(greaterp) x(name) x(class) x(self) \ x(licenseplate) x(initlist) x(exist) #else #define do_trans(x) \ x(true) x(false) x(end) x(output) x(stop) x(goto) x(tag) \ x(if) x(ifelse) x(to) x(macro) x(toplevel) x(system) x(error) x(nothing) \ x(textscreen) x(splitscreen) x(fullscreen) x(paint) x(erase) x(reverse) \ x(wrap) x(fence) x(window) x(sum) x(difference) x(product) x(quotient) \ x(equalp) x(lessp) x(greaterp) x(lessequalp) x(greaterequalp) \ x(notequalp) #endif #define wd_enum(x) Name_ ## x, enum words { do_trans(wd_enum) NUM_WORDS }; struct wdtrans { NODE *English; NODE *Alt; }; /* evaluator val_status flags, used also in coms.c */ #define VALUE_OK 1 /* [instr instr instr exp] */ #define NO_VALUE_OK 2 /* [instr instr instr instr] */ #define OUTPUT_OK 4 /* [instr instr OUTPUT exp instr] */ #define STOP_OK 8 /* [instr instr STOP instr] */ #define OUTPUT_TAIL 16 /* not [repeat n [... output ...]] */ #define STOP_TAIL 32 /* not [repeat n [... stop ...]] */ /* evaluator registers that need saving around evals */ /* Node pointers must all come before other types. proc must be first; val_status must be first non-node. See end of init(). */ struct registers { NODE *r_proc; /* the procedure definition */ NODE *r_argl; /* evaluated argument list */ NODE *r_unev; /* list of unevaluated expressions */ NODE *r_fun; /* current function name */ NODE *r_ufun; /* current user-defined function name */ NODE *r_var; /* frame pointer into var_stack */ NODE *r_vsp; /* temp ptr into var_stack */ NODE *r_qm_list; /* question mark list */ NODE *r_formals; /* list of formal parameters */ NODE *r_last_ufun; /* the function that called this one */ NODE *r_this_line; /* the current instruction line */ NODE *r_last_line; /* the line that called this one */ NODE *r_current_unode; /* a pair to identify this proc call */ NODE *r_didnt_output_name; /* name of the proc that didn't OP */ NODE *r_didnt_get_output; /* procedure wanting output from EVAL */ FIXNUM r_val_status; /* tells what EVAL_SEQUENCE should do: */ FIXNUM r_tailcall; /* 0 in sequence, 1 for tail, -1 for arg */ FIXNUM r_repcount; /* count for repeat */ FIXNUM r_user_repcount; FIXNUM r_ift_iff_flag; }; /* definitions for evaluator registers */ #ifdef WANT_EVAL_REGS #define proc (regs.r_proc) #define argl (regs.r_argl) #define unev (regs.r_unev) #define fun (regs.r_fun) #define ufun (regs.r_ufun) #define var (regs.r_var) #define vsp (regs.r_vsp) #define qm_list (regs.r_qm_list) #define formals (regs.r_formals) #define last_ufun (regs.r_last_ufun) #define this_line (regs.r_this_line) #define last_line (regs.r_last_line) #define current_unode (regs.r_current_unode) #define didnt_output_name (regs.r_didnt_output_name) #define didnt_get_output (regs.r_didnt_get_output) #define val_status (regs.r_val_status) #define tailcall (regs.r_tailcall) #define repcount (regs.r_repcount) #define user_repcount (regs.r_user_repcount) #define ift_iff_flag (regs.r_ift_iff_flag) #define exp expresn #endif #endif /* _LOGO_H */ ucblogo-5.5/logodata.c0100644000161300001330000003270510275713410012675 0ustar bhdoe/* * logodata.c logo data management module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" #include #ifdef ibm #if !defined(__RZTC__) && !defined(_MSC_VER) #include #endif #endif char special_chars[] = " \t\n(?????+++~)[]-*/=<>\"\\:;|{}"; #ifdef ecma #include #define upper_p(ch) (isupper((ch) & 0377)) #define lower_p(ch) (islower((ch) & 0377)) char ecma_array[128]; int ecma_size = sizeof(special_chars)-1; char ecma_set(int ch) { ch &= 0377; if (ch >= 128) return(ch); return(ecma_array[ch]); } char ecma_clear(int ch) { ch &= 0377; if (ch < ecma_begin || ch >= ecma_begin+sizeof(special_chars)-1) return(ch); if (ch >= 007 && ch <= 015 && ch != 013) return(ch); return(special_chars[ch - ecma_begin]); } int ecma_get(int ch) { ch &= 0377; return ((ch >= ecma_begin && ch < ecma_begin+sizeof(special_chars)-1) && (ch < 007 || ch > 015 || ch == 013)); } #else #define upper_p(c) (c >= 'A' && c <= 'Z') #define lower_p(c) (c >= 'a' && c <= 'z') #endif char *strnzcpy(char *s1, char *s2, int n) { strncpy(s1, s2, n); s1[n] = '\0'; return(s1); } char *word_strnzcpy(char *s1, NODE *kludge, int n) { /* KLUDGE! */ char *temp = s1; while (kludge != NIL) { strncpy(s1, getstrptr(car(kludge)), getstrlen(car(kludge))); s1 += getstrlen(car(kludge)); kludge = cdr(kludge); } temp[n] = '\0'; return(temp); } char *noparity_strnzcpy(char *s1, char *s2, int n) { int i; for (i = 0; i < n; i++) s1[i] = clearparity(s2[i]); s1[n] = '\0'; return(s1); } char *mend_strnzcpy(char *s1, char *s2, int n) { int i, vbar = 0; for (i = 0; i < n; ) { while (*s2 == '|') { vbar = !vbar; s2++; } if (vbar) { if (strchr(special_chars,(int)*s2)) s1[i++] = setparity(*s2++); else s1[i++] = *s2++; } else { while (*s2 == ';' || (*s2 == '~' && *(s2 + 1) == '\n')) { while (*s2 == '~' && *(s2 + 1) == '\n') s2 += 2; if (*s2 == ';') do { s2++; } while (*s2 != '\0' && *s2 != '~' && *(s2 + 1) != '\n'); } if (*s2 != '|') s1[i++] = *s2++; } } s1[n] = '\0'; return(s1); } char *mend_nosemi(char *s1, char *s2, int n) { int i, vbar = 0; for (i = 0; i < n; ) { while (*s2 == '|') { vbar = !vbar; s2++; } if (vbar) { if (strchr(special_chars,(int)*s2)) s1[i++] = setparity(*s2++); else s1[i++] = *s2++; } else { while ((*s2 == '~' && *(s2 + 1) == '\n')) { while (*s2 == '~' && *(s2 + 1) == '\n') s2 += 2; } if (*s2 != '|') s1[i++] = *s2++; } } s1[n] = '\0'; return(s1); } char *quote_strnzcpy(char *s1, char *s2, int n) { s1[0] = '"'; strncpy(s1 + 1, s2, n - 1); s1[n] = '\0'; return(s1); } char *colon_strnzcpy(char *s1, char *s2, int n) { s1[0] = ':'; strncpy(s1 + 1, s2, n - 1); s1[n] = '\0'; return(s1); } #define uncapital(c) ((c) - 'A' + 'a') char *low_strnzcpy(char *s1, char *s2, int n) { char *temp = s1; int i; for (i = 0; i < n; i++) { if (upper_p(*s2)) *s1++ = uncapital(*s2++); else *s1++ = *s2++; } *s1 = '\0'; return(temp); } #define capital(c) ((c) - 'a' + 'A') char *cap_strnzcpy(char *s1, char *s2, int n) { char *temp = s1; int i; for (i = 0; i < n; i++) { if (lower_p(*s2)) *s1++ = capital(*s2++); else *s1++ = *s2++; } *s1 = '\0'; return(temp); } char *noparitylow_strnzcpy(char *s1, char *s2, int n) { int i; char c, *temp = s1; for (i = 0; i < n; i++) { c = clearparity(*s2++); if (upper_p(c)) *s1++ = uncapital(c); else *s1++ = c; } *s1 = '\0'; return(temp); } int low_strncmp(char *s1, char *s2, int n) { int i; for (i = 0; i < n; i++) { if (*s1 != *s2) { if (upper_p(*s2)) { if (upper_p(*s1)) { if (uncapital(*s1) != uncapital(*s2)) return(uncapital(*s1) - uncapital(*s2)); } else { if (*s1 != uncapital(*s2)) return(*s1 - uncapital(*s2)); } } else if (upper_p(*s1)) { if (uncapital(*s1) != *s2) return(uncapital(*s1) - *s2); } else return(*s1 - *s2); } s1++, s2++; } return(0); } int noparity_strncmp(char *s1, char *s2, int n) { int i; for (i = 0; i < n; i++) { if (clearparity(*s1) != clearparity(*s2)) return(clearparity(*s1) - clearparity(*s2)); s1++, s2++; } return(0); } int noparitylow_strncmp(char *s1, char *s2, int n) { int i; char c1, c2; for (i = 0; i < n; i++) { c1 = clearparity(*s1); c2 = clearparity(*s2); if (c1 != c2) { if (upper_p(c2)) { if (upper_p(c1)) { if (uncapital(c1) != uncapital(c2)) return(uncapital(c1) - uncapital(c2)); } else { if (c1 != uncapital(c2)) return(c1 - uncapital(c2)); } } else if (upper_p(c1)) { if (uncapital(c1) != c2) return(uncapital(c1) - c2); } else return(c1 - c2); } s1++, s2++; } return(0); } NODE *make_strnode(char *strptr, struct string_block *strhead, int len, NODETYPES typ, char *(*copy_routine)()) { NODE *strnode; if (len == 0 && Null_Word != NIL) return(Null_Word); strnode = newnode(typ); if (strhead == NULL) { strhead = (struct string_block *) malloc((size_t)len + sizeof(FIXNUM) + 1); if (strhead == NULL) { err_logo(OUT_OF_MEM, NIL); return UNBOUND; } (*copy_routine) (strhead->str_str, strptr, len); strptr = strhead->str_str; setstrrefcnt(strhead, 0); } setstrlen(strnode, len); setstrptr(strnode, strptr); setstrhead(strnode, strhead); incstrrefcnt(strhead); return(strnode); } void make_runparse(NODE *ndi) { NODE *rp_list; rp_list = runparse(ndi); setobject(ndi, rp_list); settype(ndi, RUN_PARSE); } NODE *make_quote(NODE *qnd) { NODE *nd; nd = cons(qnd, NIL); settype(nd, QUOTE); return(nd); } NODE *maybe_quote(NODE *nd) { if (nodetype(nd) == CONT) nd = cdr(nd); if (nd == UNBOUND || aggregate(nd) || numberp(nd)) return(nd); return(make_quote(nd)); } NODE *make_caseobj(NODE *cstrnd, NODE *obj) { NODE *nd; nd = cons(cstrnd, obj); settype(nd, CASEOBJ); return(nd); } NODE *make_colon(NODE *cnd) { NODE *nd; nd = cons(cnd, NIL); settype(nd, COLON); return(nd); } NODE *make_intnode(FIXNUM i) { NODE *nd = newnode(INT); setint(nd, i); return(nd); } NODE *make_floatnode(FLONUM f) { NODE *nd = newnode(FLOATT); setfloat(nd, f); return(nd); } NODE *cnv_node_to_numnode(NODE *ndi) { NODE *val; int dr; char s2[MAX_NUMBER], *s = s2; if (is_number(ndi)) return(ndi); ndi = cnv_node_to_strnode(ndi); if (ndi == UNBOUND) return(UNBOUND); if (((getstrlen(ndi)) < MAX_NUMBER) && (dr = numberp(ndi))) { if (backslashed(ndi)) noparity_strnzcpy(s, getstrptr(ndi), getstrlen(ndi)); else strnzcpy(s, getstrptr(ndi), getstrlen(ndi)); if (*s == '+') ++s; if (s2[getstrlen(ndi)-1] == '.') s2[getstrlen(ndi)-1] = 0; if (dr - 1 || getstrlen(ndi) > 9) { val = newnode(FLOATT); setfloat(val, atof(s)); } else { val = newnode(INT); setint(val, atol(s)); } return(val); } else { return(UNBOUND); } } NODE *cnv_node_to_strnode(NODE *nd) { char s[MAX_NUMBER]; if (nd == UNBOUND || aggregate(nd)) { return(UNBOUND); } switch(nodetype(nd)) { case STRING: case BACKSLASH_STRING: case VBAR_STRING: return(nd); case CASEOBJ: return strnode__caseobj(nd); case QUOTE: nd = cnv_node_to_strnode(node__quote(nd)); nd = make_strnode(getstrptr(nd), (struct string_block *)NULL, getstrlen(nd) + 1, nodetype(nd), quote_strnzcpy); return(nd); case COLON: nd = cnv_node_to_strnode(node__colon(nd)); nd = make_strnode(getstrptr(nd), (struct string_block *)NULL, getstrlen(nd) + 1, nodetype(nd), colon_strnzcpy); return(nd); case INT: sprintf(s, "%ld", getint(nd)); return(make_strnode(s, (struct string_block *)NULL, (int)strlen(s), STRING, strnzcpy)); case FLOATT: sprintf(s, "%0.15g", getfloat(nd)); return(make_strnode(s, (struct string_block *)NULL, (int)strlen(s), STRING, strnzcpy)); } return(UNBOUND); /* Can't get here, but makes compiler happy */ } NODE *make_static_strnode(char *strptr) { NODE *strnode = newnode(STRING); setstrptr(strnode, strptr); setstrhead(strnode, NULL); setstrlen(strnode, (int)strlen(strptr)); return(strnode); } NODE *cons_list(int dummy, ...) { va_list ap; NODE *nptr, *outline = NIL, *lastnode = NIL, *val; va_start(ap, dummy); while ( (nptr = va_arg(ap, NODE *)) != END_OF_LIST) { val = cons(nptr, NIL); if (outline == NIL) { outline = val; lastnode = outline; } else { setcdr(lastnode, val); lastnode = val; } } va_end(ap); return(outline); } NODE *make_array(FIXNUM len) { NODE *node; NODE **data; node = newnode(ARRAY); setarrorg(node,1); setarrdim(node,len); data = (NODE **)malloc((size_t)len * sizeof(NODE *)); if (data == NULL) { err_logo(OUT_OF_MEM, NIL); return UNBOUND; } setarrptr(node,data); while (--len >= 0) *data++ = NIL; return(node); } NODE *llowercase(NODE *args) { NODE *arg; arg = string_arg(args); if (NOT_THROWING) { return make_strnode(getstrptr(arg), (struct string_block *)NULL, getstrlen(arg), nodetype(arg), low_strnzcpy); } return UNBOUND; } NODE *luppercase(NODE *args) { NODE *arg; arg = string_arg(args); if (NOT_THROWING) { return make_strnode(getstrptr(arg), (struct string_block *)NULL, getstrlen(arg), nodetype(arg), cap_strnzcpy); } return UNBOUND; } /* property list stuff */ NODE *getprop(NODE *plist, NODE *name, BOOLEAN before) { NODE *prev = NIL; BOOLEAN caseig = FALSE; if (varTrue(Caseignoredp)) caseig = TRUE; while (plist != NIL) { if (compare_node(name,car(plist),caseig) == 0) { return(before ? prev : plist); } prev = plist; plist = cddr(plist); } return(NIL); } NODE *lgprop(NODE *args) { NODE *plname, *pname, *plist, *val = NIL; plname = string_arg(args); pname = string_arg(cdr(args)); if (NOT_THROWING) { plname = intern(plname); plist = plist__caseobj(plname); if (plist != NIL) val = getprop(plist, pname, FALSE); if (val != NIL) return cadr(val); } return NIL; } NODE *lpprop(NODE *args) { NODE *plname, *pname, *newval, *plist, *val = NIL; plname = string_arg(args); pname = string_arg(cdr(args)); newval = car(cddr(args)); if (NOT_THROWING) { plname = intern(plname); if (flag__caseobj(plname, PLIST_TRACED)) { ndprintf(writestream, "%t %s %s %s", message_texts[TRACE_PPROP], maybe_quote(plname), maybe_quote(pname), maybe_quote(newval)); if (ufun != NIL) ndprintf(writestream,message_texts[ERROR_IN],ufun,this_line); new_line(writestream); } plist = plist__caseobj(plname); if (plist != NIL) val = getprop(plist, pname, FALSE); if (val != NIL) setcar(cdr(val), newval); else setplist__caseobj(plname, cons(pname, cons(newval, plist))); } return(UNBOUND); } NODE *lremprop(NODE *args) { NODE *plname, *pname, *plist, *val = NIL; BOOLEAN caseig = FALSE; if (varTrue(Caseignoredp)) caseig = TRUE; plname = string_arg(args); pname = string_arg(cdr(args)); if (NOT_THROWING) { plname = intern(plname); plist = plist__caseobj(plname); if (plist != NIL) { if (compare_node(car(plist), pname, caseig) == 0) setplist__caseobj(plname, cddr(plist)); else { val = getprop(plist, pname, TRUE); if (val != NIL) setcdr(cdr(val), cddr(cddr(val))); } } } return(UNBOUND); } NODE *copy_list(NODE *arg) { NODE *tnode, *lastnode = NIL, *val = NIL; while (arg != NIL) { tnode = cons(car(arg), NIL); arg = cdr(arg); if (val == NIL) { lastnode = val = tnode; } else { setcdr(lastnode, tnode); lastnode = tnode; } } return(val); } NODE *lplist(NODE *args) { NODE *plname, *plist, *val = NIL; plname = string_arg(args); if (NOT_THROWING) { plname = intern(plname); plist = plist__caseobj(plname); if (plist != NIL) val = copy_list(plist); } return(val); } /* Boolean foreign language stuff */ int isName(NODE *nod, enum words wd) { return ((compare_node(nod, translations[wd].English, TRUE) == 0) || (compare_node(nod, translations[wd].Alt, TRUE) == 0)); } int varTrue(NODE *varb) { return isName(valnode__caseobj(varb), Name_true); } NODE *theName(enum words wd) { return(varTrue(UseAlternateNames) ? translations[wd].Alt : translations[wd].English); } NODE *TrueName() { return theName(Name_true); } NODE *FalseName() { return theName(Name_false); } ucblogo-5.5/macterm.c0100644000161300001330000004241110274565143012535 0ustar bhdoe/* * macterm.c macintosh screen module mak * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "logo.h" #include "globals.h" #include "macterm.h" #include #include #include #include #include #include #include #include char *LogoPlatformName="MacOS-Classic"; char windowtitle[100]; FILE *graphics, *console; WindowPtr graphics_window, listener_window; GrafPtr savePort; extern WindowPtr myWindow; /* the editor window */ FIXNUM pen_color = 7, back_ground = 0; /************************************************************/ void nop() { } int can_do_color = 0, want_color = 0; PaletteHandle the_palette; void get_can_do_color(void) { long ans; if (!Gestalt(gestaltQuickdrawVersion, &ans)) can_do_color = (ans != 0); } void init_mac_memory(void) { unsigned long AZ, AL; /* SetApplLimit((Ptr)(GetApplLimit() - 150000L)); MaxApplZone(); */ AL = (unsigned long)GetApplLimit(); AZ = (unsigned long)ApplicZone(); /* SetApplLimit((Ptr) ( (AZ + ((AL-AZ)*3)/4) & 0x00fffffe )); */ /* SetApplLimit((Ptr)(AZ + 300000L)); */ SetApplLimit((Ptr)((AZ + ((AL-AZ)*3)/4) & -2L)); /* PCB */ MaxApplZone(); } BOOLEAN check_mac_stop(void) { char the_key_map[16]; static int full = 400; static int gotkey = 0; extern void ProcessEvent(void); if (FreeMem() < 3000) { err_logo(STACK_OVERFLOW, NIL); return(1); } GetKeys((unsigned long *)&the_key_map); if (the_key_map[5] & 128 && the_key_map[6] & 128) { /* period and command are down */ if (!gotkey) { gotkey = 1; FlushEvents(everyEvent, 0); #ifdef SIG_TAKES_ARG logo_stop(0); #else logo_stop(); #endif return 1; } } else if (the_key_map[5] & 8 && the_key_map[6] & 128) { /* comma and command are down */ if (!gotkey) { gotkey = 1; FlushEvents(everyEvent, 0); #ifdef SIG_TAKES_ARG logo_pause(0); #else logo_pause(); #endif } } else gotkey = 0; if (--full == 0) { ProcessEvent(); full = 400; } return(0); } void term_init_mac(void) { MenuHandle menu_handle; get_can_do_color(); tty_charmode = 0; x_max = 80; y_max = 24; console_options.title = (unsigned char *)windowtitle; console_options.top-= 5; console_options.left-= 5; strncpy((char *)console_options.title, (char const *)"\pGraphics", 9); want_color = 1; graphics = fopenc(); want_color = 0; cgotoxy(1, 1, graphics); graphics_window = FrontWindow(); if (can_do_color) { the_palette = GetNewPalette(131); SetPalette(graphics_window, the_palette, 1); ActivatePalette(graphics_window); } SizeWindow(graphics_window, graphics_window->portRect.right, graphics_window->portRect.bottom - 1, 0); cs_helper(TRUE); console_options.top+= 10; console_options.left+= 10; strncpy((char *)console_options.title, (char const *)"\pBerkeley Logo", 14); console = fopenc(); lregulartext(NIL); cinverse(1,stdout); listener_window = FrontWindow(); console_options.title[0] = 0; menu_handle = GetMHandle(3); AppendMenu(menu_handle, "\p(-;(Accept Editor Changes/A;(Cancel Editor Changes"); AppendMenu(menu_handle, "\p(-;(Page Setup;(Print/P"); SetUpWindows(); prepare_to_draw; mac_set_bg(0L); mac_set_pc(7L); save_color(); done_drawing; x_coord = y_coord = 0; so_arr[0] = '\1'; so_arr[1] = '\0'; se_arr[0] = '\2'; se_arr[1] = '\0'; } void mac_gotoxy(int x, int y) { /* 4.4 if (x_coord < 0) x_coord = 0; if (x_coord >= console_options.ncols) x_coord = console_options.ncols - 1; if (y_coord < 0) y_coord = 0; if (y_coord >= console_options.nrows) y_coord = console_options.nrows - 1; */ cgotoxy(x_coord + 1, y_coord + 1, stdout); } /************************************************************/ /* These are primitives that can only exist on the mac and/or are ad hoc things Michael invented that we probably don't want to keep around in Berkeley Logo. */ NODE *lsetwindowtitle(NODE *arg) { NODE *name; name = string_arg(arg); if (name != UNBOUND) { noparity_strnzcpy((char *)(windowtitle + 1), getstrptr(name), (int)getstrlen(name)); windowtitle[0] = (char)getstrlen(name); } return(UNBOUND); } void option_helper(short* var, NODE *arg) { NODE *val; val = integer_arg(arg); if (NOT_THROWING) *var = (short)getint(val); } NODE *lsettextfont(NODE *arg) { option_helper(&console_options.txFont, arg); return(UNBOUND); } NODE *lsettextsize(NODE *arg) { option_helper(&console_options.txSize, arg); return(UNBOUND); } NODE *lsettextstyle(NODE *arg) { option_helper(&console_options.txFace, arg); return(UNBOUND); } NODE *lsetwindowsize(NODE *args) { NODE *xnode, *ynode = UNBOUND, *arg; arg = pos_int_vector_arg(args); if (NOT_THROWING) { xnode = car(arg); ynode = cadr(arg); console_options.ncols = max((int)getint(xnode), 40); console_options.nrows = max((int)getint(ynode), 5); } return(UNBOUND); } NODE *lsetwindowxy(NODE *args) { NODE *xnode, *ynode = UNBOUND, *arg; arg = pos_int_vector_arg(args); if (NOT_THROWING) { xnode = car(arg); ynode = cadr(arg); console_options.left = (int)getint(xnode); console_options.top = (int)getint(ynode); } return(UNBOUND); } NODE *lnewconsole(NODE *args) { FILE *c, *old; int was_graphics; was_graphics = (FrontWindow() == graphics_window); chide(stdin); fclose(stdin); fclose(stdout); fclose(stderr); c = fopenc(); fclose(stdin); fclose(stdout); freopenc(c, stdin); freopenc(c, stdout); freopenc(c, stderr); lcleartext(NIL); cinverse(1,stdout); if (was_graphics) { graphics_window = FrontWindow(); graphics = c; } else { listener_window = FrontWindow(); console = c; x_max = console_options.ncols; y_max = console_options.nrows; } return(UNBOUND); } NODE *lgraphtext(NODE *args) { freopenc(graphics, stdin); freopenc(graphics, stdout); freopenc(graphics, stderr); return(UNBOUND); } NODE *lregulartext(NODE *args) { freopenc(console, stdin); freopenc(console, stdout); freopenc(console, stderr); return(UNBOUND); } NODE *lcaninverse(NODE *args) { FIXNUM onoff = int_arg(args); if (NOT_THROWING) cinverse(onoff, stdin); return(UNBOUND); } /************************************************************/ /* These are the machine-specific graphics definitions. All versions must provide a set of functions analogous to these. */ void save_pen(pen_info *p) { GetPort(&savePort); SetPort(graphics_window); GetPenState(&(p->ps)); p->vis = graphics_window->pnVis; // p->color = graphics_window->fgColor; p->color = pen_color; SetPort(savePort); } void restore_pen(pen_info *p) { GetPort(&savePort); SetPort(graphics_window); SetPenState(&(p->ps)); graphics_window->pnVis = p->vis; // graphics_window->fgColor = p->color; mac_set_pc(p->color); SetPort(savePort); } void plain_xor_pen(void) { PenNormal(); PenMode(patXor); } FIXNUM color_table[8] = {33, 409, 341, 273, 205, 137, 69, 30}; FIXNUM hw_color(FIXNUM c) { if (c >= 0 && c < 8) return color_table[c]; if (c < 0) return c; return c-8; } int palette_color(FIXNUM c) { if (c == 7) return 0; if (c >= 0 && c < 7) return c+1; return c; } void mac_set_pc(FIXNUM c) { pen_color = c; if (can_do_color) PmForeColor(palette_color(c+2)); else graphics_window->fgColor = hw_color(c); } void mac_set_bg(FIXNUM c) { back_ground = c; if (can_do_color) PmBackColor(palette_color(c+2)); else graphics_window->bkColor = hw_color(c); redraw_graphics(); } void set_palette(int slot, unsigned int r, unsigned int g, unsigned int b) { RGBColor rgb; if (can_do_color) { slot+=2; rgb.red = r; rgb.green = g; rgb.blue = b; SetEntryColor(the_palette, slot, &rgb); SetEntryUsage(the_palette, slot, pmTolerant, 2000); ActivatePalette(graphics_window); redraw_graphics(); } } void get_palette(int slot, unsigned int *r, unsigned int *g, unsigned int *b) { RGBColor rgb; if (can_do_color) { slot+=2; GetEntryColor(the_palette, palette_color((FIXNUM)slot), &rgb); *r = rgb.red; *g = rgb.green; *b = rgb.blue; } else { *r = (slot&4 ? 65000 : 0); *g = (slot&2 ? 65000 : 0); *b = (slot&1 ? 65000 : 0); } } void set_pen_pattern(char *pat) { PenPat((struct Pattern *)pat); } void set_list_pen_pattern(NODE *arg) { NODE *cur_num, *temp; char p_arr[8]; int count; cur_num = arg; for (count = 0 ; count <= 7 && cur_num != NIL && NOT_THROWING ; count++) { temp = cnv_node_to_numnode(car(cur_num)); p_arr[count] = (char)getint(temp); cur_num = cdr(cur_num); } PenPat((struct Pattern *)p_arr); } #ifdef SYMANTEC_C union myPattU { char patt_ch[8]; struct Pattern patt_p; }; typedef union myPattU myPatt; void get_pen_pattern(char *pat) { PenState oil; int count; myPatt my_patt; GetPenState(&oil); my_patt.patt_p = oil.pnPat; for (count = 0; count < 8; count++) *(char *)(pat + count) = my_patt.patt_ch[count]; } NODE *Get_node_pen_pattern() { PenState oil; int count; myPatt my_patt; GetPenState(&oil); my_patt.patt_p = oil.pnPat; return(cons(make_intnode((FIXNUM)(my_patt.patt_ch[0])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[1])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[2])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[3])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[4])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[5])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[6])), cons(make_intnode((FIXNUM)(my_patt.patt_ch[7])), NIL))))))))); } #else void get_pen_pattern(char *pat) { PenState oil; int count; GetPenState(&oil); for (count = 0; count < 8; count++) *(char *)(pat + count) = oil.pnPat[count]; } NODE *Get_node_pen_pattern() { PenState oil; int count; GetPenState(&oil); return(cons(make_intnode((FIXNUM)(oil.pnPat[0])), cons(make_intnode((FIXNUM)(oil.pnPat[1])), cons(make_intnode((FIXNUM)(oil.pnPat[2])), cons(make_intnode((FIXNUM)(oil.pnPat[3])), cons(make_intnode((FIXNUM)(oil.pnPat[4])), cons(make_intnode((FIXNUM)(oil.pnPat[5])), cons(make_intnode((FIXNUM)(oil.pnPat[6])), cons(make_intnode((FIXNUM)(oil.pnPat[7])), NIL))))))))); } #endif void label(char *s) { short tmode; GetPort(&savePort); SetPort(graphics_window); MoveTo(g_round(graphics_window->portRect.right/2.0 + turtle_x), g_round(graphics_window->portRect.bottom/2.0 - turtle_y)); switch(pen_mode) { case patCopy : tmode = srcOr; break; case patBic : tmode = srcBic; break; case patXor : tmode = srcXor; break; default : tmode = srcCopy; break; /* can't happen */ } TextFont(monaco); TextSize(9); TextMode(tmode); DrawString((unsigned char const *)s); SetPort(savePort); } void logofill(void) { BitMap mask; if (can_do_color) { prepare_to_draw; mask.bounds = (*(graphics_window->visRgn))->rgnBBox; mask.bounds.right = mask.bounds.right - mask.bounds.left; mask.bounds.left = 0; mask.bounds.bottom = mask.bounds.bottom - mask.bounds.top; mask.bounds.top = 0; mask.rowBytes = ((mask.bounds.right + 15) / 8) & ~1; mask.baseAddr = malloc(mask.rowBytes * mask.bounds.bottom); if (mask.baseAddr == NULL) { err_logo(OUT_OF_MEM, NIL); done_drawing; return; } SeedCFill(&(graphics_window->portBits), &mask, &((*(graphics_window->visRgn))->rgnBBox), &(mask.bounds), graphics_window->pnLoc.h, graphics_window->pnLoc.v, 0, 0L); CopyMask(&mask, &mask, &(graphics_window->portBits), &(mask.bounds), &(mask.bounds), &((*(graphics_window->visRgn))->rgnBBox)); free(mask.baseAddr); done_drawing; } } void erase_screen(void) { int old_vis; GetPort(&savePort); SetPort(graphics_window); old_vis = graphics_window->pnVis; graphics_window->pnVis = 0; EraseRect(&graphics_window->portRect); graphics_window->pnVis = old_vis; SetPort(savePort); } void t_screen(void) { SelectWindow(listener_window); console_options.ncols = 80; console_options.nrows = 25; console_options.left = 15; console_options.top = 55; strncpy((char *)console_options.title, (char *)"\pBerkeley Logo", 14); lnewconsole(NIL); MoveWindow(myWindow, 15, 55, TRUE); MySizeWindow(myWindow, 488, 283); SelectWindow(listener_window); myGrow(listener_window, (listener_window == FrontWindow())); } void s_screen(void) { Rect bounds; int v; if (can_do_color) v = ((*(((CGrafPtr)graphics_window)->portPixMap))->bounds.bottom - (*(((CGrafPtr)graphics_window)->portPixMap))->bounds.top) - 84; else v = (graphics_window->portBits.bounds.bottom - graphics_window->portBits.bounds.top) - 84; SelectWindow(listener_window); console_options.ncols = 80; console_options.nrows = 6; console_options.left = 5; console_options.top = v + 6; strncpy((char *)console_options.title, (char *)"\pBerkeley Logo", 14); lnewconsole(NIL); MoveWindow(myWindow, 5, v, TRUE); MySizeWindow(myWindow, 488, 80); SelectWindow(listener_window); myGrow(listener_window, (listener_window == FrontWindow())); } void f_screen(void) { Rect bounds; int v; if (can_do_color) v = ((*(((CGrafPtr)graphics_window)->portPixMap))->bounds.bottom - (*(((CGrafPtr)graphics_window)->portPixMap))->bounds.top) - 84; else v = (graphics_window->portBits.bounds.bottom - graphics_window->portBits.bounds.top) - 84; SelectWindow(listener_window); console_options.ncols = 80; console_options.nrows = 0; console_options.left = 5; console_options.top = v + 52; strncpy((char *)console_options.title, (char *)"\pBerkeley Logo", 14); lnewconsole(NIL); MoveWindow(myWindow, 5, v, TRUE); MySizeWindow(myWindow, 488, 80); SelectWindow(graphics_window); myGrow(graphics_window, (graphics_window == FrontWindow())); } int in_fscreen(void) { return (console_options.nrows == 0); } FIXNUM mickey_x(void) { Point the_mouse; GetPort(&savePort); SetPort(graphics_window); GetMouse(&the_mouse); SetPort(savePort); return((FIXNUM)(the_mouse.h - graphics_window->portRect.right/2)); } FIXNUM mickey_y(void) { Point the_mouse; GetPort(&savePort); SetPort(graphics_window); GetMouse(&the_mouse); SetPort(savePort); return((FIXNUM)(graphics_window->portRect.bottom/2 - the_mouse.v)); } #ifdef SYMANTEC_C SndChannelPtr SoundChannel = NIL; #endif /* see Inside Macintosh vol. 2 pp. 237-241 for pitch values */ void tone(FIXNUM pitch, FIXNUM duration) { #ifndef SYMANTEC_C struct { int mode; int freq; int amp; int dur; } sound_rec; sound_rec.mode = -1; sound_rec.freq = (int)(387205L/pitch); sound_rec.amp = 200; sound_rec.dur = (int)duration; StartSound(&sound_rec, (long)8, (char *)(-1)); while (!SoundDone()) ; #endif #ifdef SYMANTEC_C SndCommand MyCommand; SCStatus ChannelStatus; pitch = (int) 60+((log(pitch/261.625))/(log(twelfthRootTwo))); duration *= 34; /* ticks to half-milliseconds */ if (duration>0 && duration<65536 && pitch >=0 && pitch<128) { if (SoundChannel == NIL) { SndNewChannel(&SoundChannel, squareWaveSynth, initMono+initChanLeft, (ProcPtr)NIL); } if (SoundChannel != NIL) { MyCommand.cmd = freqDurationCmd; MyCommand.param1 = duration; MyCommand.param2 = pitch; SndDoImmediate(SoundChannel, &MyCommand); ChannelStatus.scChannelBusy = true; while (ChannelStatus.scChannelBusy == true) SndChannelStatus(SoundChannel, sizeof(ChannelStatus), &ChannelStatus); } } #endif } /************************************************************/ void c_to_pascal_string(char *str, int len) { int count = len; char prev; while (count > 0) { prev = str[count - 1]; str[count] = clearparity(prev); count--; } str[0] = len; } void fixMacType(NODE *arg) { char *fnstr; FSSpec theFSSpec; arg = cnv_node_to_strnode(car(arg)); if (arg == UNBOUND) return; fnstr = (char *) malloc((size_t)getstrlen(arg) + 1); if (fnstr == NULL) { err_logo(FILE_ERROR, make_static_strnode("Not enough memory")); return; } noparity_strnzcpy(fnstr, getstrptr(arg), getstrlen(arg)); c_to_pascal_string(fnstr, getstrlen(arg)); FSMakeFSSpec(0, 0L, (unsigned char *)fnstr, &theFSSpec); HCreate(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name, '????', 'EPSF'); } ucblogo-5.5/csls/0040755000161300001330000000000010274277456011715 5ustar bhdoeucblogo-5.5/csls/algs0100644000161300001330000001442106131776560012562 0ustar bhdoe;;; Algorithms and Data Structures ;; Local optimization of quadratic formula to quadratic :a :b :c localmake "root sqrt (:b * :b-4 * :a * :c) localmake "x1 (-:b+:root)/(2 * :a) localmake "x2 (-:b-:root)/(2 * :a) print (sentence [The solutions are] :x1 "and :x2) end ;; Memoization of T function to t :n :k localmake "result gprop :n :k if not emptyp :result [output :result] make "result realt :n :k pprop :n :k :result output :result end to realt :n :k if equalp :k 0 [output 1] if equalp :n 0 [output 0] output (t :n :k-1) + (t :n-1 :k) end ;; Speedup of Simplex function to simplex :buttons output 2 * first (cascade :buttons [fput (sumprods butfirst ?2 ?1) ?1] [1] [fput 1 nextrow ?2] [1 1]) end to sumprods :a :b output reduce "sum (map "product :a :b) end to nextrow :combs if emptyp butfirst :combs [output :combs] output fput (sum first :combs first butfirst :combs) nextrow butfirst :combs end ;; Sorting -- selection sort to ssort :list if emptyp :list [output []] output ssort1 (first :list) (butfirst :list) [] end to ssort1 :min :in :out if emptyp :in [output fput :min ssort :out] if lessthanp :min (first :in) ~ [output ssort1 :min (butfirst :in) (fput first :in :out)] output ssort1 (first :in) (butfirst :in) (fput :min :out) end ;; Sorting -- partition sort to psort :list if emptyp :list [output []] if emptyp butfirst :list [output :list] localmake "split ((first :list) + (last :list)) / 2 if lessthanp first :list :split ~ [output psort1 :split (butfirst :list) (list first :list) []] output psort1 :split (butlast :list) (list last :list) [] end to psort1 :split :in :low :high if emptyp :in [output sentence (psort :low) (psort :high)] if lessthanp first :in :split ~ [output psort1 :split (butfirst :in) (fput first :in :low) :high] output psort1 :split (butfirst :in) :low (fput first :in :high) end ;; Sorting -- count comparisons to lessthanp :a :b if not namep "comparisons [make "comparisons 0] make "comparisons :comparisons+1 output :a < :b end to howmany print :comparisons ern "comparisons end ;; Abstract Data Type for Trees: Constructor to tree :datum :children output fput :datum :children end ;; Tree ADT: Selectors to datum :node output first :node end to children :node output butfirst :node end ;; Tree ADT: Mutator to addchild :tree :child .setbf :tree (fput :child butfirst :tree) end ;; Tree ADT: other procedures to leaf :datum output tree :datum [] end to leaves :leaves output map [leaf ?] :leaves end to leafp :node output emptyp children :node end ;; The World tree to worldtree make "world ~ tree "world ~ (list (tree "France leaves [Paris Dijon Avignon]) (tree "China leaves [Beijing Shanghai Guangzhou Suzhou]) (tree [United States] (list (tree [New York] leaves [[New York] Albany Rochester Armonk] ) (tree "Massachusetts leaves [Boston Cambridge Sudbury Maynard] ) (tree "California leaves [[San Francisco] Berkeley [Palo Alto] Pasadena] ) (tree "Washington leaves [Seattle Olympia] ) ) ) (tree "Canada (list (tree "Ontario leaves [Toronto Ottawa Windsor] ) (tree "Quebec leaves [Montreal Quebec Lachine] ) (tree "Manitoba leaves [Winnipeg]) ) ) ) end to locate :city output locate1 :city :world "false end to locate1 :city :subtree :wanttree if and :wanttree (equalp :city datum :subtree) [output :subtree] if leafp :subtree ~ [ifelse equalp :city datum :subtree [output (list :city)] [output []]] localmake "lower locate.in.forest :city (children :subtree) :wanttree if emptyp :lower [output []] output ifelse :wanttree [:lower] [fput (datum :subtree) :lower] end to locate.in.forest :city :forest :wanttree if emptyp :forest [output []] localmake "child locate1 :city first :forest :wanttree if not emptyp :child [output :child] output locate.in.forest :city butfirst :forest :wanttree end to cities :name output cities1 (finddatum :name :world) end to cities1 :subtree if leafp :subtree [output (list datum :subtree)] output map.se [cities1 ?] children :subtree end to finddatum :datum :tree output locate1 :name :tree "true end ;; Area code/city pairs ADT to areacode :pair output first :pair end to city :pair output butfirst :pair end ;; Area code linear search make "codelist [[202 Washington] [206 Seattle] [212 New York] [213 Los Angeles] [215 Philadelphia] [303 Denver] [305 Miami] [313 Detroit] [314 St. Louis] [401 Providence] [404 Atlanta] [408 Sunnyvale] [414 Milwaukee] [415 San Francisco] [504 New Orleans] [608 Madison] [612 St. Paul] [613 Kingston] [614 Columbus] [615 Nashville] [617 Boston] [702 Las Vegas] [704 Charlotte] [712 Sioux City] [714 Anaheim] [716 Rochester] [717 Scranton] [801 Salt Lake City] [804 Newport News] [805 Ventura] [808 Honolulu]] to listcity :code output city find [equalp :code areacode ?] :codelist end ;; Area code binary tree search to balance :list if emptyp :list [output []] if emptyp butfirst :list [output leaf first :list] output balance1 (int (count :list)/2) :list [] end to balance1 :count :in :out if equalp :count 0 ~ [output tree (first :in) (list balance reverse :out balance butfirst :in)] output balance1 (:count-1) (butfirst :in) (fput first :in :out) end to treecity :code output city treecity1 :code :codetree end to treecity1 :code :tree if emptyp :tree [output [0 no city]] localmake "datum datum :tree if :code = areacode :datum [output :datum] if :code < areacode :datum [output treecity1 :code lowbranch :tree] output treecity1 :code highbranch :tree end to lowbranch :tree if leafp :tree [output []] output first children :tree end to highbranch :tree if leafp :tree [output []] output last children :tree end ucblogo-5.5/csls/basic0100644000161300001330000001501410137214511012674 0ustar bhdoeto basic make "linenumbers [] make "readline [] forever [basicprompt] end to basicprompt print [] print "READY print [] make "line basicread if emptyp :line [stop] ifelse numberp first :line [compile split :line] [immediate :line] end to compile :commands make "number first :commands make :number :line ifelse emptyp butfirst :commands ~ [eraseline :number] ~ [makedef (word "basic% :number) butfirst :commands] end to makedef :name :commands make "definition [[]] foreach :commands [run list (word "compile. first ?) ?] queue "definition (list "nextline :number) define :name :definition make "linenumbers insert :number :linenumbers end to insert :num :list if emptyp :list [output (list :num)] if :num = first :list [output :list] if :num < first :list [output fput :num :list] output fput first :list (insert :num butfirst :list) end to eraseline :num make "linenumbers remove :num :linenumbers end to immediate :line if equalp :line [list] [foreach :linenumbers [print thing ?] stop] if equalp :line [run] [run (list (word "basic% first :linenumbers)) stop] if equalp :line [exit] [throw "toplevel] print sentence [Invalid command:] :line end ;; Compiling each BASIC command to compile.end :command queue "definition [stop] end to compile.goto :command queue "definition (list (word "basic% last :command) "stop) end to compile.gosub :command queue "definition (list (word "basic% last :command)) end to compile.return :command queue "definition [stop] end to compile.print :command make "command butfirst :command while [not emptyp :command] [c.print1] queue "definition [print []] end to c.print1 make "exp expression ifelse equalp first first :exp "" ~ [make "sym gensym make word "%% :sym butfirst butlast first :exp queue "definition list "type word ":%% :sym] ~ [queue "definition fput "type :exp] if emptyp :command [stop] make "delimiter pop "command if equalp :delimiter ", [queue "definition [type char 9] stop] if equalp :delimiter "\; [stop] (throw "error [Comma or semicolon needed in print.]) end to compile.input :command make "command butfirst :command if equalp first first :command "" ~ [make "sym gensym make "prompt pop "command make word "%% :sym butfirst butlast :prompt queue "definition list "type word ":%% :sym] while [not emptyp :command] [c.input1] end to c.input1 make "var pop "command queue "definition (list "make (word ""% :var) "readvalue) if emptyp :command [stop] make "delimiter pop "command if equalp :delimiter ", [stop] (throw "error [Comma needed in input.]) end to compile.let :command make "command butfirst :command make "var pop "command make "delimiter pop "command if not equalp :delimiter "= [(throw "error [Need = in let.])] make "exp expression queue "definition (sentence "make (word ""% :var) :exp) end to compile.if :command make "command butfirst :command make "exp expression make "delimiter pop "command if not equalp :delimiter "then [(throw "error [Need then after if.])] queue "definition (sentence "if :exp (list c.if1)) end to c.if1 local "definition make "definition [[]] run list (word "compile. first :command) :command ifelse (count :definition) = 2 ~ [output last :definition] ~ [make "newname word "% gensym define :newname :definition output (list :newname)] end to compile.for :command make "command butfirst :command make "var pop "command make "delimiter pop "command if not equalp :delimiter "= [(throw "error [Need = after for.])] make "start expression make "delimiter pop "command if not equalp :delimiter "to [(throw "error [Need to after for.])] make "end expression queue "definition (sentence "make (word ""% :var) :start) queue "definition (sentence "make (word ""let% :var) :end) make "newname word "% gensym queue "definition (sentence "make (word ""next% :var) (list (list :newname))) queue "definition (list :newname) define :name :definition make "name :newname make "definition [[]] end to compile.next :command make "command butfirst :command make "var pop "command queue "definition (sentence "make (word ""% :var) (word ":% :var) [+ 1]) queue "definition (sentence [if not greaterp] (word ":% :var) (word ":let% :var) (list (list "run (word ":next% :var) "stop))) end ;; Compile an expression for LET, IF, PRINT, or FOR to expression make "expr [] make "token expr1 while [not emptyp :token] [queue "expr :token make "token expr1] output :expr end to expr1 if emptyp :command [output []] make "token pop "command if memberp :token [+ - * / = < > ( )] [output :token] if memberp :token [, \; : then to] [push "command :token output []] if numberp :token [output :token] if equalp first :token "" [output :token] output word ":% :token end ;; reading input to basicread output basicread1 readword [] " end to basicread1 :input :output :token if emptyp :input [if not emptyp :token [push "output :token] output reverse :output] if equalp first :input "| | [if not emptyp :token [push "output :token] output basicread1 (butfirst :input) :output "] if equalp first :input "" [if not emptyp :token [push "output :token] output breadstring butfirst :input :output "] if memberp first :input [+ - * / = < > ( ) , \; :] ~ [if not emptyp :token [push "output :token] output basicread1 (butfirst :input) (fput first :input :output) "] output basicread1 (butfirst :input) :output (word :token first :input) end to breadstring :input :output :string if emptyp :input [(throw "error [String needs ending quote.])] if equalp first :input "" ~ [output basicread1 (butfirst :input) (fput (word "" :string "") :output) "] output breadstring (butfirst :input) :output (word :string first :input) end to split :line output fput first :line split1 (butfirst :line) [] [] end to split1 :input :output :command if emptyp :input [if not emptyp :command [push "output reverse :command] output reverse :output] if equalp first :input ": [if not emptyp :command [push "output reverse :command] output split1 (butfirst :input) :output []] output split1 (butfirst :input) :output (fput first :input :command) end ;; Runtime library to nextline :num make "target member :num :linenumbers if not emptyp :target [make "target butfirst :target] if not emptyp :target [run (list (word "basic% first :target))] end to readvalue while [emptyp :readline] [make "readline basicread] output pop "readline end ucblogo-5.5/csls/cards0100644000161300001330000000237406135447266012736 0ustar bhdoeprogram cards; {Shuffle a deck of cards} var ranks:array [0..51] of integer; suits:array [0..51] of char; i:integer; procedure showdeck; {Print the deck arrays} begin {showdeck} for i := 0 to 51 do begin if i mod 13 = 0 then writeln; write(ranks[i]:3,suits[i]); end; writeln; writeln end; {showdeck} procedure deck; {Create the deck in order} var i,j:integer; suitnames:packed array [0..3] of char; begin {deck} suitnames := 'HSDC'; for i := 0 to 12 do for j := 0 to 3 do begin ranks[13*j+i] := i+1; suits[13*j+i] := suitnames[j] end; writeln('The initial deck:'); showdeck end; {deck} procedure shuffle; {Shuffle the deck randomly} var rank,i,j:integer; suit:char; begin {shuffle} for i := 51 downto 1 do {For each card in the deck} begin j := random(i+1); {Pick a random card before it} rank := ranks[i]; {Interchange ranks} ranks[i] := ranks[j]; ranks[j] := rank; suit := suits[i]; {Interchange suits} suits[i] := suits[j]; suits[j] := suit end; writeln('The shuffled deck:'); showdeck end; {shuffle} begin {main program} deck; shuffle end. ucblogo-5.5/csls/crypto0100644000161300001330000001670306505037626013157 0ustar bhdoeto crypto :text make "text map "uppercase :text make "fulltext :text make "moretext [] make "textstack [] if not procedurep "letterp [copydef "letterp "namep] forletters "A "Z "initvars make "maxcount 0 initcount "single initcount "triple cleartext histogram :text redisplay "false if or guess.single guess.triple [showclear :text] parseloop end ;; Initialization to initcount :type setlist. :type [] setcount. :type 0 end to initvars :letter setcnt :letter 0 make :letter "| | setunbound :letter end ;; Histogram to histogram :text foreach :text [localmake "word filter "letterp ? foreach :word "histlet prepare.guess :word] end to histlet :letter localmake "cnt 1+cnt :letter setcursor list (index :letter) (nonneg 24-:cnt) type :letter setcnt :letter :cnt if :maxcount < :cnt [make "maxcount :cnt] end ;; Guessing letters to prepare.guess :word if equalp count :word 1 [tally "single :word] if equalp count :word 3 [tally "triple :word] end to tally :type :word localmake "countvar word :type :word if not memberp :word list. :type ~ [setlist. :type fput :word list. :type make :countvar 0] localmake "count (thing :countvar)+1 make :countvar :count if :count > (count. :type) ~ [setcount. :type :count setmax. :type :word] end to guess.single if emptyp (list. "single) [output "false] if emptyp butfirst (list. "single) ~ [qbind first (list. "single) "A output "true] qbind (max. "single) "A qbind (ifelse equalp first (list. "single) (max. "single) [last (list. "single)] [first (list. "single)]) ~ "I output "true end to guess.triple if emptyp (list. "triple) [output "false] if :maxcount < (3+cnt last (max. "triple)) ~ [qbind first (max. "triple) "T qbind first butfirst (max. "triple) "H qbind last (max. "triple) "E output "true] output "false end ;; Keyboard commands to parseloop forever [parsekey uppercase readchar] end to parsekey :char if :char = "@ [fullclear stop] if :char = "+ [moretext stop] if :char = "- [lesstext stop] if not letterp :char [beep stop] bind :char uppercase readchar end ;; Keeping track of guesses to bind :from :to if not equalp :to "| | [if not letterp :to [beep stop] if boundp :to [beep stop]] if letterp thing :from [dark thing :from] make :from :to fixtop :from if letterp :to [light :to] showclear :text end to qbind :from :to if letterp thing :from [stop] make :from :to fixtop :from light :to end ;; Maintaining the display to redisplay :flag cleartext showtop alphabet showcode :text if :flag [showclear :text] end ;; Top section of display (letter counts and guesses) to showtop setcursor [0 0] showrow "A "E showrow "F "J showrow "K "O showrow "P "T showrow "U "Y showrow "Z "Z end to showrow :from :to forletters :from :to [setposn ? cursor onetop ?] print [] end to onetop :letter localmake "count cnt :letter if :count = 0 [type word :letter "| | stop] localmake "text (word :letter "- twocol :count "- thing :letter) ifelse :maxcount < :count+3 [invtype :text] [type :text] type "| | end to twocol :number if :number > 9 [output :number] output word 0 :number end to fixtop :letter setcursor posn :letter onetop :letter end ;; Middle section of display (guessed cleartext letters) to alphabet setcursor [6 6] forletters "A "Z [ifelse boundp ? [invtype ?] [type ?]] end to light :letter setcursor list 6+(index :letter) 6 invtype :letter setbound :letter end to dark :letter setcursor list 6+(index :letter) 6 type :letter setunbound :letter end ;; Bottom section of display (coded text) to showcode :text make "moretext [] showcode1 8 0 :text end to showcode1 :row :col :text if emptyp :text [make "moretext [] stop] if :row > 22 [stop] if and equalp :row 16 equalp :col 0 [make "moretext :text] if (:col+count first :text) > 37 [showcode1 :row+2 0 :text stop] codeword :row :col first :text showcode1 :row (:col+1+count first :text) butfirst :text end to codeword :row :col :word setcursor list :col :row invtype :word end ;; Bottom section of display (cleartext) to showclear :text showclear1 8 0 :text 2 end to showclear1 :row :col :text :delta if emptyp :text [stop] if :row > 23 [stop] if keyp [stop] if (:col+count first :text) > 37 ~ [showclear1 :row+:delta 0 :text :delta stop] clearword :row :col first :text showclear1 :row (:col+1+count first :text) butfirst :text :delta end to clearword :row :col :word setcursor list :col :row+1 foreach :word [ifelse letterp ? [type thing ?] [type ?]] end ;; Windowing commands to fullclear cleartext showclear1 0 0 :fulltext 1 print [] invtype [type any char to redisplay] ignore readchar redisplay "true end to moretext if emptyp :moretext [beep stop] push "textstack :text make "text :moretext redisplay "true end to lesstext if emptyp :textstack [beep stop] make "text pop "textstack redisplay "true end ;; Iteration tool for letters to forletters :from :to :action for [lettercode [ascii :from] [ascii :to]] ~ [apply :action (list char :lettercode)] end ;; Data abstraction (constructors and selectors) to setbound :letter make word "bound :letter "true end to setunbound :letter make word "bound :letter "false end to boundp :letter output thing word "bound :letter end to setcnt :letter :thing make (word "cnt :letter) :thing end to cnt :letter output thing (word "cnt :letter) end to setposn :letter :thing make (word "posn :letter) :thing end to posn :letter output thing (word "posn :letter) end to setcount. :word :thing make (word "count. :word) :thing end to count. :word output thing (word "count. :word) end to setlist. :word :thing make (word "list. :word) :thing end to list. :word output thing (word "list. :word) end to setmax. :word :thing make (word "max. :word) :thing end to max. :word output thing (word "max. :word) end ;; Miscellaneous helpers to index :letter output (ascii :letter)-(ascii "A) end to beep tone 440 15 end to invtype :text type standout :text end to nonneg :number output ifelse :number < 0 [0] [:number] end ;; Sample cryptograms make "cgram1 [Dzynufqyjulli, jpqhq ok yr hoxpj qnzeujory qceqwj xhrtoyx zw oyjr u trhjptpolq trhln. oynqqn, rzh qceqkkogq eryeqhy tojp whrvlqfk rd qnzeujory uj whqkqyj kofwli fquyk jpuj jpq |xhrty-zwk| nr yrj pugq kzep u trhln. u nqeqyj qnzeujory uofk uj, whqwuhqk drh, u frhq trhjptpolq dzjzhq, tojp u noddqhqyj erffzyoji kwohoj, noddqhqyj reezwujoryk, uyn frhq hqul zjoloji jpuy ujjuoyoyx kjujzk uyn kuluhi.] make "cgram2 [Lvo vfkp lfzj md opaxflimn iz lm gitokflo fnp zlkonblvon f hmalv'z inilifliuo, fnp fl lvo zfyo liyo lm zoo lm il lvfl vo jnmwz wvfl iz noxozzfkh lm xmco wilv lvo mnbminb fxliuilioz fnp xaglako md zmxiolh, zm lvfl viz inilifliuo xfn to kogoufnl. il iz ftzakp lm lvinj lvfl lviz lfzj xfn to fxxmycgizvop th zm yaxv zillinb in f tms dfxinb dkmnl, yfnicagflinb zhytmgz fl lvo pikoxlimn md pizlfnl fpyinizlkflmkz. lviz iz kflvok f wfh lm kobiyonl fnp tkfinwfzv.] make "cgram3 [Pcodl hbdcx qxdrdlh yihcodr, hbd rzbiier gxd lih ziyqdhdlh hi hdgzb gwhbdlhcz echdxgzf, xdgnclp gr g ydglr ia ecudxghcil gln zwehcoghcil. gln c niwuh hbgh yirh ia wr jbi rdxciwref xdgn gln jxchd hbd dlpecrb eglpwgpd dodx edgxldn ch uf hbd xiwhd ia "xwl, rqih, xwl" hi rcegr ygxldx.] make "cgram4 [Jw btn xnsgsyp ejke gfebbcg, dtyjbn fbccsksg, ryu fbccsksg nswcsfpsu pes usgjns, wnssuba, ryu wtptns bw pes qbtyk, pesns zbtcu ls yb knrujyk, yb psgpjyk svfsxp rg r psrfejyk aspebu, ryu yb lcrfilbrnu dtykcsg. jy wrfp, zs rns ksppjyk cbfigpsx gfesutcjyk ryu knrujyk pb pes xbjyp bw pbnptns.] ucblogo-5.5/csls/diff0100644000161300001330000000766506030771346012553 0ustar bhdoeto diff :file1 :file2 :output local "caseignoredp make "caseignoredp "false openread :file1 openread :file2 if not emptyp :output [openwrite :output] setwrite :output print [DIFF results:] print sentence [< File 1 =] :file1 print sentence [> File 2 =] :file2 diff.same (makefile 1 :file1) (makefile 2 :file2) print "========== setread [] setwrite [] close :file1 close :file2 if not emptyp :output [close :output] end ;; Skip over identical lines in the two files. to diff.same :fib1 :fib2 local [line1 line2] do.while [make "line1 getline :fib1 make "line2 getline :fib2 if and listp :line1 listp :line2 [stop] ; Both files ended. ] [equalp :line1 :line2] addline :fib1 :line1 ; Difference found. addline :fib2 :line2 diff.differ :fib1 :fib2 end ;; Remember differing lines while looking for ones that match. to diff.differ :fib1 :fib2 local "line make "line readline :fib1 addline :fib1 :line ifelse memberp :line lines :fib2 ~ [diff.found :fib1 :fib2] ~ [diff.differ :fib2 :fib1] end to diff.found :fib1 :fib2 local "lines make "lines member2 (last butlast lines :fib1) ~ (last lines :fib1) ~ (lines :fib2) ifelse emptyp :lines ~ [diff.differ :fib2 :fib1] ~ [report :fib1 :fib2 (butlast butlast lines :fib1) (firstn (lines :fib2) (count lines :fib2)-(count :lines))] end to member2 :line1 :line2 :lines if emptyp butfirst :lines [output []] if and equalp :line1 first :lines equalp :line2 first butfirst :lines ~ [output :lines] output member2 :line1 :line2 butfirst :lines end to firstn :stuff :number if :number = 0 [output []] output fput (first :stuff) (firstn butfirst :stuff :number-1) end ;; Read from file or from saved lines. to getline :fib nextlinenum :fib output readline :fib end to readline :fib if savedp :fib [output popsaved :fib] setread filename :fib output readword end ;; Matching lines found, now report the differences. to report :fib1 :fib2 :lines1 :lines2 local [end1 end2 dashes] if equalp (which :fib1) 2 [report :fib2 :fib1 :lines2 :lines1 stop] print "========== make "end1 (linenum :fib1)+(count :lines1)-1 make "end2 (linenum :fib2)+(count :lines2)-1 make "dashes "false ifelse :end1 < (linenum :fib1) [ print (sentence "INSERT :end1+1 (word (linenum :fib2) "- :end2)) ] [ifelse :end2 < (linenum :fib2) [ print (sentence "DELETE (word (linenum :fib1) "- :end1) :end2+1) ] [ print (sentence "CHANGE (word (linenum :fib1) "- :end1) (word (linenum :fib2) "- :end2)) make "dashes "true ]] process :fib1 "|< | :lines1 :end1 if :dashes [print "-----] process :fib2 "|> | :lines2 :end2 diff.same :fib1 :fib2 end to process :fib :prompt :lines :end foreach :lines [type :prompt print ?] savelines :fib butfirst butfirst chop :lines (lines :fib) setlines :fib [] setlinenum :fib :end+2 end to chop :counter :stuff if emptyp :counter [output :stuff] output chop butfirst :counter butfirst :stuff end ;; Constructor, selectors, and mutators for File Information Block (FIB) ;; Five elements: file number, file name, line number, ;; differing lines, and saved lines for re-reading. to makefile :number :name local "file make "file array 5 ; Items 4 and 5 will be empty lists. setitem 1 :file :number setitem 2 :file :name setitem 3 :file 0 output :file end to which :fib output item 1 :fib end to filename :fib output item 2 :fib end to linenum :fib output item 3 :fib end to nextlinenum :fib setitem 3 :fib (item 3 :fib)+1 end to setlinenum :fib :value setitem 3 :fib :value end to addline :fib :line setitem 4 :fib (lput :line item 4 :fib) end to setlines :fib :value setitem 4 :fib :value end to lines :fib output item 4 :fib end to savelines :fib :value setitem 5 :fib (sentence :value item 5 :fib) end to savedp :fib output not emptyp item 5 :fib end to popsaved :fib local "result make "result first item 5 :fib setitem 5 :fib (butfirst item 5 :fib) output :result end ucblogo-5.5/csls/doctor0100644000161300001330000006305306505074732013130 0ustar bhdoeto doctor local [text sentence stuff a b c rules keywords memory] make "memory [] print [Hello, I am the doctor. What can I do for you?] print [Please end your remarks with an empty line.] print [] loop end ;; Controlling the conversation to loop make "text tokenize getstuff [] make "sentence getsentence :text analyze :sentence :keywords print [] loop end ;; Reading and preparing the input to getstuff :stuff localmake "line readlist if emptyp :line [output :stuff] output getstuff sentence :stuff :line end to tokenize :text output map.se [tokenword ? "] :text end to tokenword :word :out if emptyp :word [output :out] if memberp first :word [, " ] [output tokenword butfirst :word :out] if memberp first :word [. ? ! |;|] [output sentence :out ".] output tokenword butfirst :word word :out first :word end to getsentence :text make "keywords [] output getsentence1 decapitalize :text [] end to getsentence1 :text :out if emptyp :text [output :out] if equalp first :text ". ~ [ifelse emptyp :keywords ~ [output getsentence1 decapitalize butfirst :text []] [output :out]] checkpriority first :text output getsentence1 butfirst :text sentence :out translate first :text end to decapitalize :text if emptyp :text [output []] output fput lowercase first :text butfirst :text end to checkpriority :word localmake "priority gprop :word "priority if emptyp :priority [stop] if emptyp :keywords [make "keywords ( list :word ) stop] ifelse :priority > ( gprop first :keywords "priority ) ~ [make "keywords fput :word :keywords] ~ [make "keywords lput :word :keywords] end to translate :word localmake "new gprop :word "translation output ifelse emptyp :new [:word] [:new] end ;; Choosing the rule and replying to analyze :sentence :keywords local [rules keyword] if emptyp :keywords [norules stop] make "keyword first :keywords make "rules gprop :keyword "rules if wordp first :rules ~ [make "keyword first :rules make "rules gprop :keyword "rules] checkrules :keyword :rules end to checkrules :keyword :rules if not match first :rules :sentence ~ [checkrules :keyword butfirst butfirst :rules stop] dorule first butfirst :rules end to dorule :rule localmake "print first gprop :keyword :rule pprop :keyword :rule lput :print butfirst gprop :keyword :rule if equalp :print "newkey [analyze :sentence butfirst :keywords stop] if wordp :print [checkrules :print gprop :print "rules stop] if equalp first :print "pre ~ [analyze reconstruct first butfirst :print butfirst butfirst :print stop] print capitalize reconstruct :print memory :keyword :sentence end to reconstruct :sentence if emptyp :sentence [output []] if not equalp ": first first :sentence ~ [output fput first :sentence reconstruct butfirst :sentence] output sentence reword first :sentence reconstruct butfirst :sentence end to reword :word if memberp last :word [. ? ,] [output addpunct reword butlast :word last :word] output thing butfirst :word end to addpunct :stuff :char if wordp :stuff [output word :stuff :char] if emptyp :stuff [output :char] output sentence butlast :stuff word last :stuff :char end to capitalize :text if emptyp :text [output []] output fput (word uppercase first first :text butfirst first :text) butfirst :text end to memory :keyword :sentence local [rules rule name] make "rules gprop :keyword "memr if emptyp :rules [stop] if not match first :rules :sentence [stop] make "name last :rules make "rules gprop :keyword :name make "rule first :rules pprop :keyword :name lput :rule butfirst :rules make "memory fput reconstruct :sentence :memory end to norules ifelse :memflag [usememory] [lastresort] make "memflag not :memflag end to lastresort print first :lastresort make "lastresort lput first :lastresort butfirst :lastresort end to usememory if emptyp :memory [lastresort stop] print capitalize first :memory make "memory butfirst :memory end ;; Predicates for patterns to beliefp :word output not emptyp gprop :word "belief end to familyp :word output not emptyp gprop :word "family end ;; Procedures for adding to the script to addrule :word :pattern :results localmake "propname gensym pprop :word "rules (sentence gprop :word "rules list :pattern :propname) pprop :word :propname :results end to addmemr :word :pattern :results localmake "propname gensym pprop :word "memr (sentence gprop :word "memr list :pattern :propname) pprop :word :propname :results end ;; data make "gensym.number 80 make "lastresort [[I am not sure I understand you fully.] [Please go on.] [What does that suggest to you?] [Do you feel strongly about discussing such things?]] make "memflag "false pprop "alike "priority 10 pprop "alike "rules [dit] pprop "always "priority 1 pprop "always "rules [[#] g69] pprop "always "g69 [[Can you think of a specific example?] [When?] [What incident are you thinking of?] [Really, always?] [What if this never happened?]] pprop "am "priority 0 pprop "am "translation "are pprop "am "rules [[# are you #stuff] g18 [#] g19] pprop "am "g18 [[Do you believe you are :stuff?] [Would you want to be :stuff?] [You wish I would tell you you are :stuff.] [What would it mean if you were :stuff?] how] pprop "am "g19 [[Why do you say "am"?] [I don't understand that.]] pprop "are "priority 0 pprop "are "rules [[#a there are #b you #c] g20 [# there are &stuff] g21 [# are I #stuff] g22 [are #] g23 [# are #stuff] g24] pprop "are "g20 [[pre [:a there are :b] are]] pprop "are "g21 [[What makes you think there are :stuff?] [Do you usually consider :stuff?] [Do you wish there were :stuff?]] pprop "are "g22 [[Why are you interested in whether I am :stuff or not?] [Would you prefer if I weren't :stuff?] [Perhaps I am :stuff in your fantasies.] [Do you sometimes think I am :stuff?] how] pprop "are "g23 [how] pprop "are "g24 [[Did you think they might not be :stuff?] [Would you like it if they were not :stuff?] [What if they were not :stuff?] [Possibly they are :stuff.]] pprop "ask "priority 0 pprop "ask "rules [[# you ask #] g77 [# you ! asking #] g78 [# I #] g79 [#] g80] pprop "ask "g77 [how] pprop "ask "g78 [how] pprop "ask "g79 [you] pprop "ask "g80 [newkey] pprop "because "priority 0 pprop "because "rules [[#] g64] pprop "because "g64 [[Is that the real reason?] [Don't any other reasons come to mind?] [Does that reason seem to explain anything else?] [What other reasons might there be?] [You're not concealing anything from me, are you?]] pprop "believe "belief "true pprop "bet "belief "true pprop "brother "family "true pprop "can "priority 0 pprop "can "rules [[# can I #stuff] g58 [# can you #stuff] g59 [#] g60] pprop "can "g58 [[You believe I can :stuff, don't you?] how [You want me to be able to :stuff.] [Perhaps you would like to be able to :stuff yourself.]] pprop "can "g59 [[Whether or not you can :stuff depends more on you than on me.] [Do you want to be able to :stuff?] [Perhaps you don't want to :stuff.] how] pprop "can "g60 [how newkey] pprop "cant "translation "can't pprop "certainly "priority 0 pprop "certainly "rules [yes] pprop "children "family "true pprop "computer "priority 50 pprop "computer "rules [[#] g17] pprop "computer "g17 [[Do computers worry you?] [Why do you mention computers?] [What do you think machines have to do with your problem?] [Don't you think computers can help people?] [What about machines worries you?] [What do you think about machines?]] pprop "computers "priority 50 pprop "computers "rules [computer] pprop "dad "translation "father pprop "dad "family "true pprop "daddy "translation "father pprop "daddy "family "true pprop "deutsch "priority 0 pprop "deutsch "rules [[#] g15] pprop "deutsch "g15 [[I'm sorry, I speak only English.]] pprop "dit "rules [[#] g72] pprop "dit "g72 [[In what way?] [What resemblance do you see?] [What does that similarity suggest to you?] [What other connections do you see?] [What do you suppose that resemblance means?] [What is the connection, do you suppose?] [Could there really be some connection?] how] pprop "dont "translation "don't pprop "dream "priority 3 pprop "dream "rules [[#] g9] pprop "dream "g9 [[What does that dream suggest to you?] [Do you dream often?] [What persons appear in your dreams?] [Don't you believe that dream has something to do with your problem?] [Do you ever wish you could flee from reality?] newkey] pprop "dreamed "priority 4 pprop "dreamed "rules [[# you dreamed #stuff] g7 [#] g8] pprop "dreamed "g7 [[Really :stuff?] [Have you ever fantasied :stuff while you were awake?] [Have you dreamed :stuff before?] dream newkey] pprop "dreamed "g8 [dream newkey] pprop "dreams "translation "dream pprop "dreams "priority 3 pprop "dreams "rules [dream] pprop "dreamt "translation "dreamed pprop "dreamt "priority 4 pprop "dreamt "rules [dreamed] pprop "espanol "priority 0 pprop "espanol "rules [deutsch] pprop "everybody "priority 2 pprop "everybody "rules [everyone] pprop "everyone "priority 2 pprop "everyone "rules [[# !a:in [everyone everybody nobody noone] #] g68] pprop "everyone "g68 [[Really, :a?] [Surely not :a.] [Can you think of anyone in particular?] [Who, for example?] [You are thinking of a very special person.] [Who, may I ask?] [Someone special perhaps.] [You have a particular person in mind, don't you?] [Who do you think you're talking about?] [I suspect you're exaggerating a little.]] pprop "father "family "true pprop "feel "belief "true pprop "francais "priority 0 pprop "francais "rules [deutsch] pprop "hello "priority 0 pprop "hello "rules [[#] g16] pprop "hello "g16 [[How do you do. Please state your problem.]] pprop "how "priority 0 pprop "how "rules [[#] g63] pprop "how "g63 [[Why do you ask?] [Does that question interest you?] [What is it you really want to know?] [Are such questions much on your mind?] [What answer would please you most?] [What do you think?] [What comes to your mind when you ask that?] [Have you asked such questions before?] [Have you asked anyone else?]] pprop "husband "family "true pprop "i "priority 0 pprop "i "translation "you pprop "i "rules [[# you !:in [want need] #stuff] g32 [# you are # !stuff:in [sad unhappy depressed sick] #] g33 [# you are # !stuff:in [happy elated glad better] #] g34 [# you was #] g35 [# you !:beliefp you #stuff] g36 [# you # !:beliefp # i #] g37 [# you are #stuff] g38 [# you !:in [can't cannot] #stuff] g39 [# you don't #stuff] g40 [# you feel #stuff] g41 [# you #stuff i #] g42 [#stuff] g43] pprop "i "g32 [[What would it mean to you if you got :stuff?] [Why Do you want :stuff?] [Suppose you got :stuff soon.] [What if you never got :stuff?] [What would getting :stuff mean to you?] [You really want :stuff.] [I suspect you really don't want :stuff.]] pprop "i "g33 [[I'm sorry to hear you are :stuff.] [Do you think coming here will help you not to be :stuff?] [I'm sure it's not pleasant to be :stuff.] [Can you explain what made you :stuff?] [Please go on.]] pprop "i "g34 [[How have I helped you to be :stuff?] [Has your treatment made you :stuff?] [What makes you :stuff just now?] [Can you explain why you are suddenly :stuff?] [Are you sure?] [What do you mean by :stuff?]] pprop "i "g35 [was] pprop "i "g36 [[Do you really think so?] [But you are not sure you :stuff.] [Do you really doubt you :stuff?]] pprop "i "g37 [you] pprop "i "g38 [[Is it because you are :stuff that you came to me?] [How long have you been :stuff?] [Do you believe it normal to be :stuff?] [Do you enjoy being :stuff?]] pprop "i "g39 [[How do you know you can't :stuff?] [Have you tried?] [Perhaps you could :stuff now.] [Do you really want to be able to :stuff?]] pprop "i "g40 [[Don't you really :stuff?] [Why don't you :stuff?] [Do you wish to be able to :stuff?] [Does that trouble you?]] pprop "i "g41 [[Tell me more about such feelings.] [Do you often feel :stuff?] [Do you enjoy feeling :stuff?] [Of what does feeling :stuff remind you?]] pprop "i "g42 [[Perhaps in your fantasy we :stuff each other.] [Do you wish to :stuff me?] [You seem to need to :stuff me.] [Do you :stuff anyone else?]] pprop "i "g43 [[You say :stuff.] [Can you elaborate on that?] [Do you say :stuff for some special reason?] [That's quite interesting.]] pprop "i'm "priority 0 pprop "i'm "translation "you're pprop "i'm "rules [[# you're #stuff] g31] pprop "i'm "g31 [[pre [you are :stuff] I]] pprop "if "priority 3 pprop "if "rules [[#a if #b had #c] g5 [# if #stuff] g6] pprop "if "g5 [[pre [:a if :b might have :c] if]] pprop "if "g6 [[Do you think it's likely that :stuff?] [Do you wish that :stuff?] [What do you think about :stuff?]] pprop "is "priority 0 pprop "is "rules [[&a is &b] g61 [#] g62] pprop "is "g61 [[Suppose :a were not :b.] [Perhaps :a really is :b.] [Tell me more about :a.]] pprop "is "g62 [newkey] pprop "italiano "priority 0 pprop "italiano "rules [deutsch] pprop "like "priority 10 pprop "like "rules [[# !:in [am is are was] # like #] g70 [#] g71] pprop "like "g70 [dit] pprop "like "g71 [newkey] pprop "machine "priority 50 pprop "machine "rules [computer] pprop "machines "priority 50 pprop "machines "rules [computer] pprop "maybe "priority 0 pprop "maybe "rules [perhaps] pprop "me "translation "you pprop "mom "translation "mother pprop "mom "family "true pprop "mommy "translation "mother pprop "mommy "family "true pprop "mother "family "true pprop "my "priority 2 pprop "my "translation "your pprop "my "rules [[# your # !a:familyp #b] g55 [# your &stuff] g56 [#] g57] pprop "my "g55 [[Tell me more about your family.] [Who else in your family :b?] [Your :a?] [What else comes to mind when you think of your :a?]] pprop "my "g56 [[Your :stuff?] [Why do you say your :stuff?] [Does that suggest anything else which belongs to you?] [Is it important to you that your :stuff?]] pprop "my "g57 [newkey] pprop "my "memr [[# your &stuff] g12] pprop "my "g12 [[Earlier you said your :stuff.] [But your :stuff.] [Does that have anything to do with your statement about :stuff?]] pprop "myself "translation "yourself pprop "name "priority 15 pprop "name "rules [[#] g14] pprop "name "g14 [[I am not interested in names.] [I've told you before I don't care about names\; please continue.]] pprop "no "priority 0 pprop "no "rules [[no] g53 [#] g54] pprop "no "g53 [xxyyzz [pre [x no] no]] pprop "no "g54 [[Are you saying "no" just to be negative?] [You are being a bit negative.] [Why not?] [Why "no"?] newkey] pprop "nobody "priority 2 pprop "nobody "rules [everyone] pprop "noone "priority 2 pprop "noone "rules [everyone] pprop "perhaps "priority 0 pprop "perhaps "rules [[#] g13] pprop "perhaps "g13 [[You don't seem quite certain.] [Why the uncertain tone?] [Can't you be more positive?] [You aren't sure.] [Don't you know?]] pprop "problem "priority 5 pprop "problem "rules [[#a !b:in [is are] your !c:in [problem problems] #] g73 [# your !a:in [problem problems] !b:in [is are] #c] g74 [#] g75] pprop "problem "g73 [[:a :b your :c.] [Are you sure :a :b your :c?] [Perhaps :a :b not your real :c.] [You think you have problems?] [Do you often think about :a?]] pprop "problem "g74 [[Your :a :b :c?] [Are you sure your :a :b :c?] [Perhaps your real :a :b not :c.] [You think you have problems?]] pprop "problem "g75 [[Please continue, this may be interesting.] [Have you any other problems you wish to discuss?] [Perhaps you'd rather change the subject.] [You seem a bit uneasy.] newkey] pprop "problem "memr [[#stuff is your problem #] g76] pprop "problem "g76 [[Earlier you mentioned :stuff.] [Let's talk further about :stuff.] [Tell me more about :stuff.] [You haven't mentioned :stuff for a while.]] pprop "problems "priority 5 pprop "problems "rules [problem] pprop "remember "priority 5 pprop "remember "rules [[# you remember #stuff] g2 [# do I remember #stuff] g3 [#] g4] pprop "remember "g2 [[Do you often think of :stuff?] [Does thinking of :stuff bring anything else to mind?] [What else do you remember?] [Why do you remember :stuff just now?] [What in the present situation reminds you of :stuff?]] pprop "remember "g3 [[Did you think I would forget :stuff?] [Why do you think I should recall :stuff now?] [What about :stuff?] what [You mentioned :stuff.]] pprop "remember "g4 [newkey] pprop "same "priority 10 pprop "same "rules [dit] pprop "sister "family "true pprop "sorry "priority 0 pprop "sorry "rules [[#] g1] pprop "sorry "g1 [[Please don't apologize.] [Apologies are not necessary.] [What feelings do you have when you apologize?] [I've told you that apologies are not required.]] pprop "svenska "priority 0 pprop "svenska "rules [deutsch] pprop "think "belief "true pprop "was "priority 2 pprop "was "rules [[# was you #stuff] g26 [# you was #stuff] g27 [# was I #stuff] g28 [#] g29] pprop "was "g26 [[What if you were :stuff?] [Do you think you were :stuff?] [Were you :stuff?] [What would it mean if you were :stuff?] [What does " :stuff " suggest to you?] how] pprop "was "g27 [[Were you really?] [Why do you tell me you were :stuff now?] [Perhaps I already knew you were :stuff.]] pprop "was "g28 [[Would you like to believe I was :stuff?] [What suggests that I was :stuff?] [What do you think?] [Perhaps I was :stuff.] [What if I had been :stuff?]] pprop "was "g29 [newkey] pprop "we "translation "you pprop "we "priority 0 pprop "we "rules [I] pprop "were "priority 0 pprop "were "translation "was pprop "were "rules [was] pprop "what "priority 0 pprop "what "rules [[!:in [what where] #] g10 [# !a:in [what where] #b] g11] pprop "what "g10 [how] pprop "what "g11 [[Tell me about :a :b.] [:a :b?] [Do you want me to tell you :a :b?] [Really.] [I see.] newkey] pprop "where "priority 0 pprop "where "rules [how] pprop "why "priority 0 pprop "why "rules [[# why don't I #stuff] g65 [# why can't you #stuff] g66 [#] g67] pprop "why "g65 [[Do you believe I don't :stuff?] [Perhaps I will :stuff in good time.] [Should you :stuff yourself?] [You want me to :stuff?] how] pprop "why "g66 [[Do you think you should be able to :stuff?] [Do you want to be able to :stuff?] [Do you believe this will help you to :stuff?] [Have you any idea why you can't :stuff?] how] pprop "why "g67 [[Why indeed?] [Why "why"?] [Why not?] how newkey] pprop "wife "family "true pprop "wish "belief "true pprop "wont "translation "won't pprop "xxyyzz "priority 0 pprop "xxyyzz "rules [[#] g50] pprop "xxyyzz "g50 [[You're being somewhat short with me.] [You don't seem very talkative today.] [Perhaps you'd rather talk about something else.] [Are you using monosyllables for some reason?] newkey] pprop "yes "priority 0 pprop "yes "rules [[yes] g51 [#] g52] pprop "yes "g51 [xxyyzz [pre [x yes] yes]] pprop "yes "g52 [[You seem quite positive.] [You are sure.] [I see.] [I understand.] newkey] pprop "you "priority 0 pprop "you "translation "I pprop "you "rules [[# I remind you of #] g44 [# I are # you #] g45 [# I # are #stuff] g46 [# I #stuff you] g47 [# I &stuff] g48 [#] g49] pprop "you "g44 [dit] pprop "you "g45 [newkey] pprop "you "g46 [[What makes you think I am :stuff?] [Does it please you to believe I am :stuff?] [Perhaps you would like to be :stuff.] [Do you sometimes wish you were :stuff?]] pprop "you "g47 [[Why do you think I :stuff you?] [You like to think I :stuff you, don't you?] [What makes you think I :stuff you?] [Really, I :stuff you?] [Do you wish to believe I :stuff you?] [Suppose I did :stuff you. what would that mean?] [Does someone else believe I :stuff you?]] pprop "you "g48 [[We were discussing you, not me.] [Oh, I :stuff?] [Is this really relevant to your problem?] [Perhaps I do :stuff.] [Are you glad to know I :stuff?] [Do you :stuff?] [What are your feelings now?]] pprop "you "g49 [newkey] pprop "you're "priority 0 pprop "you're "translation "I'm pprop "you're "rules [[# I'm #stuff] g30] pprop "you're "g30 [[pre [I are :stuff] you]] pprop "your "priority 0 pprop "your "translation "my pprop "your "rules [[# my #stuff] g25] pprop "your "g25 [[Why are you concerned over my :stuff?] [What about your own :stuff?] [Are you worried about someone else's :stuff?] [Really, my :stuff?]] pprop "yourself "translation "myself to match :pat :sen local [special.var special.pred special.buffer in.list] if or wordp :pat wordp :sen [output "false] if emptyp :pat [output emptyp :sen] if listp first :pat [output special fput "!: :pat :sen] if memberp first first :pat [? # ! & @ ^] [output special :pat :sen] if emptyp :sen [output "false] if equalp first :pat first :sen [output match butfirst :pat butfirst :sen] output "false end ;; Parsing quantifiers to special :pat :sen set.special parse.special butfirst first :pat " output run word "match first first :pat end to parse.special :word :var if emptyp :word [output list :var "always] if equalp first :word ": [output list :var butfirst :word] output parse.special butfirst :word word :var first :word end to set.special :list make "special.var first :list make "special.pred last :list if emptyp :special.var [make "special.var "special.buffer] if memberp :special.pred [in anyof] [set.in] if not emptyp :special.pred [stop] make "special.pred first butfirst :pat make "pat fput first :pat butfirst butfirst :pat end to set.in make "in.list first butfirst :pat make "pat fput first :pat butfirst butfirst :pat end ;; Exactly one match to match! if emptyp :sen [output "false] if not try.pred [output "false] make :special.var first :sen output match butfirst :pat butfirst :sen end ;; Zero or one match to match? make :special.var [] if emptyp :sen [output match butfirst :pat :sen] if not try.pred [output match butfirst :pat :sen] make :special.var first :sen if match butfirst :pat butfirst :sen [output "true] make :special.var [] output match butfirst :pat :sen end ;; Zero or more matches to match# make :special.var [] output #test #gather :sen end to #gather :sen if emptyp :sen [output :sen] if not try.pred [output :sen] make :special.var lput first :sen thing :special.var output #gather butfirst :sen end to #test :sen if match butfirst :pat :sen [output "true] if emptyp thing :special.var [output "false] output #test2 fput last thing :special.var :sen end to #test2 :sen make :special.var butlast thing :special.var output #test :sen end ;; One or more matches to match& output &test match# end to &test :tf if emptyp thing :special.var [output "false] output :tf end ;; Zero or more matches (as few as possible) to match^ make :special.var [] output ^test :sen end to ^test :sen if match butfirst :pat :sen [output "true] if emptyp :sen [output "false] if not try.pred [output "false] make :special.var lput first :sen thing :special.var output ^test butfirst :sen end ;; Match words in a group to match@ make :special.var :sen output @test [] end to @test :sen if @try.pred [if match butfirst :pat :sen [output "true]] if emptyp thing :special.var [output "false] output @test2 fput last thing :special.var :sen end to @test2 :sen make :special.var butlast thing :special.var output @test :sen end ;; Applying the predicates to try.pred if listp :special.pred [output match :special.pred first :sen] output run list :special.pred quoted first :sen end to quoted :thing if listp :thing [output :thing] output word "" :thing end to @try.pred if listp :special.pred [output match :special.pred thing :special.var] output run list :special.pred thing :special.var end ;; Special predicates to always :x output "true end to in :word output memberp :word :in.list end to anyof :sen output anyof1 :sen :in.list end to anyof1 :sen :pats if emptyp :pats [output "false] if match first :pats :sen [output "true] output anyof1 :sen butfirst :pats end ucblogo-5.5/csls/format0100644000161300001330000000536206022554466013126 0ustar bhdoeto format :from :to openread :from openwrite :to setread :from setwrite :to init.vars loop setread [] setwrite [] close :from close :to end to init.vars make "pageheight 66 make "topmar 6 make "lines 54 make "leftmar 7 make "width 65 make "filltab 5 make "nofilltab 0 make "parskip 1 make "spacing 1 make "started "false make "filling "true make "printed 0 make "inline [] end to loop forever [if process nextword [stop]] end ;; Add a word to the output file, starting a new line if necessary to process :word if listp :word [output "true] if not :started [start] if (:linecount+1+count :word) > :width [putline] addword :word output "false end to addword :word if not emptyp :line [make "linecount :linecount+1] make "line lput :word :line make "linecount :linecount+count :word end to putline repeat :leftmar+:indent [type "| |] putwords :line ((count :line)-1) (:width-:linecount) newline skip :spacing end to putwords :line :spaces :filler local "perword if emptyp :line [stop] type first :line make "perword ifelse :spaces > 0 [int ((:filler+:spaces-1)/:spaces)] [0] if :filler > 0 [repeat :perword [type "| |]] type "| | putwords (butfirst :line) (:spaces-1) (:filler-:perword) end ;; Get the next input word, reading a new line if necessary to nextword if not emptyp :inline [output extract.word] if not :filling [break] make "inline readword if listp :inline [break output []] if emptyp :inline [break output nextword] if equalp first :inline "|*| ~ [run butfirst :inline make "inline "] make "inline skipspaces :inline output nextword end to extract.word local "result make "result firstword :inline make "inline skipfirst :inline output :result end to firstword :word if emptyp :word [output "] if equalp first :word "| | [output "] output word (first :word) (firstword butfirst :word) end to skipfirst :word if emptyp :word [output "] if equalp first :word "| | [output skipspaces :word] output skipfirst butfirst :word end to skipspaces :word if emptyp :word [output "] if equalp first :word "| | [output skipspaces butfirst :word] output :word end ;; Formatting helpers to start make "started "true repeat :topmar [print []] newindent end to newindent newline make "indent ifelse :filling [:filltab] [:nofilltab] make "linecount :indent end to newline make "line [] make "indent 0 make "linecount 0 end to break if emptyp :line [stop] make "linecount :width putline newindent if :filling [skip :parskip] end ;; Formatting commands to be invoked by the user to skip :howmany break repeat :howmany [print []] make "printed :printed+:howmany if :printed < :lines [stop] repeat :pageheight-:printed [print []] make "printed 0 end to nofill break make "filling "false newindent end to yesfill break if not :filling [skip :parskip] make "filling "true newindent end ucblogo-5.5/csls/fsm0100644000161300001330000002336406122111072012404 0ustar bhdoe;;; Finite State Machine Interpreter (FSM) to game :which fsm thing word "mach :which end to fsm :machine cleartext setcursor [0 3] localmake "start startpart :machine localmake "moves movepart :machine localmake "accept acceptpart :machine fsm1 :start end to fsm1 :here ifelse memberp :here :accept [accept] [reject] fsm1 (fsmnext :here readchar) end to fsmnext :here :input blank if memberp :input (list char 13 char 10) ~ [print ifelse memberp :here :accept ["| ACCEPT|] ["| REJECT|] output :start] type :input catch "error [output last find [fsmtest :here :input ?] :moves] output -1 end to fsmtest :here :input :move output and (equalp :here arrowtail :move) (memberp :input arrowtext :move) end ;; Display machine state to accept display "accept end to reject display "reject end to blank display "| | end to display :text localmake "oldpos cursor setcursor [15 1] type :text setcursor :oldpos end ;; Data abstraction for machines to startpart :machine output first :machine end to movepart :machine output first bf :machine end to acceptpart :machine output last :machine end to make.machine :start :moves :accept output (list :start :moves :accept) end ;; Data abstraction for arrows to arrowtail :arrow output first :arrow end to arrowtext :arrow output first butfirst :arrow end to arrowhead :arrow output last :arrow end to make.arrow :tail :text :head output (list :tail :text :head) end ;; Machine descriptions for the guessing game make "mach1 [1 [[1 AB 1]] [1]] make "mach2 [1 [[1 ABC 2] [2 ABC 1]] [1]] make "mach3 [1 [[1 A 2] [2 B 3] [3 ABC 3]] [3]] make "mach4 [1 [[1 A 2] [1 B 3] [1 C 4] [2 A 1] [3 B 1] [4 C 1]] [1]] make "mach5 [1 [[1 ABC 2] [2 B 1]] [1]] make "mach6 [1 [[1 A 2] [2 AB 2] [2 C 3] [3 AB 2] [3 C 3]] [3]] make "mach7 [1 [[1 AB 1] [1 C 2] [2 C 1]] [1]] make "mach8 [1 [[1 A 2] [1 BC 1] [2 A 1] [2 BC 2]] [1]] make "mach9 [1 [[1 AB 1] [1 C 2] [2 A 3] [2 B 1] [3 A 1]] [1]] make "mach10 [1 [[1 A 2] [1 BC 1] [2 A 2] [2 B 3] [2 C 1] [3 A 2] [3 B 1] [3 C 4] [4 A 2] [4 B 5] [4 C 1] [5 A 6] [5 BC 1] [6 ABC 6]] [6]] ;;; Regular Expression to FSM Translation (MACHINE) to machine :regexp localmake "nextstate 0 output optimize determine nondet :regexp end ;; First step: make a possibly nondeterministic machine to nondet :regexp if and (wordp :regexp) (equalp count :regexp 1) [output ndletter :regexp] if wordp :regexp [output ndor reduce "sentence :regexp] if equalp first :regexp "or [output ndor butfirst :regexp] if equalp first :regexp "* [output ndmany last :regexp] output ndconcat :regexp end ;; Alphabet rule to ndletter :letter localmake "from newstate localmake "to newstate output make.machine :from (list (make.arrow :from :letter :to)) (list :to) end ;; Concatenation rule to ndconcat :exprs output reduce "string (map "nondet :exprs) end to string :machine1 :machine2 output (make.machine (startpart :machine1) (sentence (movepart :machine1) (splice acceptpart :machine1 :machine2) (movepart :machine2)) (stringa (acceptpart :machine1) (startpart :machine2) (acceptpart :machine2))) end to stringa :accept1 :start2 :accept2 if memberp :start2 :accept2 [output sentence :accept1 :accept2] output :accept2 end ;; Alternatives rule to ndor :exprs localmake "newstart newstate localmake "machines (map "nondet :exprs) localmake "accepts map.se "acceptpart :machines output (make.machine :newstart (sentence map.se "movepart :machines map.se "or.splice :machines) ifelse not emptyp find [memberp (startpart ?) (acceptpart ?)] :machines [fput :newstart :accepts] [:accepts]) end to or.splice :machine output map [newtail ? :newstart] (arrows.from.start :machine) end ;; Repetition rule to ndmany :regexp localmake "machine nondet :regexp output (make.machine (startpart :machine) sentence (movepart :machine) (splice (acceptpart :machine) :machine) fput (startpart :machine) (acceptpart :machine)) end ;; Generate moves from a bunch of given states (:accepts) duplicating ;; the moves from the start state of some machine (:machine). ;; Used for concatenation rule to splice two formerly separate machines; ;; used for repetition rule to "splice" a machine to itself. to splice :accepts :machine output map.se [copy.to.accepts ?] (arrows.from.start :machine) end to arrows.from.start :machine output filter [equalp startpart :machine arrowtail ?] movepart :machine end to copy.to.accepts :move output map [newtail :move ?] :accepts end to newtail :arrow :tail output make.arrow :tail (arrowtext :arrow) (arrowhead :arrow) end ;; Make a new state number to newstate make "nextstate :nextstate+1 output :nextstate end ;; Second step: Turn nondeterministic FSM into a deterministic one ;; Also eliminates "orphan" (unreachable) states. to determine :machine localmake "moves movepart :machine localmake "accepts acceptpart :machine localmake "states [] localmake "join.state.list [] localmake "newmoves nd.traverse (startpart :machine) output make.machine (startpart :machine) ~ :newmoves ~ filter [memberp ? :states] :accepts end to nd.traverse :state if memberp :state :states [output []] make "states fput :state :states localmake "newmoves (check.nd filter [equalp arrowtail ? :state] :moves) output sentence :newmoves map.se "nd.traverse (map "arrowhead :newmoves) end to check.nd :movelist if emptyp :movelist [output []] localmake "letter arrowtext first :movelist localmake "heads sort map "arrowhead ~ filter [equalp :letter arrowtext ?] :movelist if emptyp butfirst :heads ~ [output fput first :movelist check.nd filter [not equalp :letter arrowtext ?] :movelist] localmake "check.heads member :heads :join.state.list if not emptyp :check.heads ~ [output fput make.arrow :state :letter first butfirst :check.heads ~ check.nd filter [not equalp :letter arrowtext ?] :movelist] localmake "join.state newstate make "join.state.list fput :heads fput :join.state :join.state.list make "moves sentence :moves ~ map [make.arrow :join.state arrowtext ? arrowhead ?] ~ filter [memberp arrowtail ? :heads] :moves if not emptyp find [memberp ? :accepts] :heads ~ [make "accepts sentence :accepts :join.state] output fput make.arrow :state :letter :join.state ~ check.nd filter [not equalp :letter arrowtext ?] :movelist end to sort :list if emptyp :list [output []] output insert first :list sort butfirst :list end to insert :value :sorted if emptyp :sorted [output (list :value)] if :value = first :sorted [output :sorted] if :value < first :sorted [output fput :value :sorted] output fput first :sorted insert :value butfirst :sorted end ;; Third step: Combine redundant states. ;; Also combines arrows with same head and tail: [1 A 2] [1 B 2] -> [1 AB 2]. to optimize :machine localmake "stubarray array :nextstate foreach (movepart :machine) "array.save localmake "states sort fput (startpart :machine) ~ map "arrowhead movepart :machine localmake "start startpart :machine foreach reverse :states [optimize.state ? ?rest] output (make.machine :start map.se [fix.arrows ? item ? :stubarray] :states filter [memberp ? :states] acceptpart :machine) end to array.save :move setitem (arrowtail :move) :stubarray ~ stub.add (arrow.stub :move) (item (arrowtail :move) :stubarray) end to stub.add :stub :stublist if emptyp :stublist [output (list :stub)] if (stub.head :stub) < (stub.head first :stublist) ~ [output fput :stub :stublist] if (stub.head :stub) = (stub.head first :stublist) ~ [output fput make.stub letter.join (stub.text :stub) (stub.text first :stublist) stub.head :stub butfirst :stublist] output fput first :stublist (stub.add :stub butfirst :stublist) end to letter.join :this :those if emptyp :those [output :this] if beforep :this first :those [output word :this :those] output word (first :those) (letter.join :this butfirst :those) end to optimize.state :state :others localmake "candidates filter (ifelse memberp :state acceptpart :machine [[memberp ? acceptpart :machine]] [[not memberp ? acceptpart :machine]]) ~ :others localmake "mymoves item :state :stubarray localmake "twin find [equalp (item ? :stubarray) :mymoves] :candidates if emptyp :twin [stop] make "states remove :state :states if equalp :start :state [make "start :twin] foreach :states ~ [setitem ? :stubarray (cascade [emptyp ?2] [stub.add (change.head :state :twin first ?2) ?1] filter [not equalp stub.head ? :state] item ? :stubarray [butfirst ?2] filter [equalp stub.head ? :state] item ? :stubarray)] end to change.head :from :to :stub if not equalp (stub.head :stub) :from [output :stub] output list (stub.text :stub) :to end to fix.arrows :state :stublist output map [stub.arrow :state ?] :stublist end ;; Data abstraction for "stub" arrow (no tail) to arrow.stub :arrow output butfirst :arrow end to make.stub :text :head output list :text :head end to stub.text :stub output first :stub end to stub.head :stub output last :stub end to stub.arrow :tail :stub output fput :tail :stub end ucblogo-5.5/csls/match0100644000161300001330000000667506104710230012722 0ustar bhdoeto match :pat :sen local [special.var special.pred special.buffer in.list] if or wordp :pat wordp :sen [output "false] if emptyp :pat [output emptyp :sen] if listp first :pat [output special fput "!: :pat :sen] if memberp first first :pat [? # ! & @ ^] [output special :pat :sen] if emptyp :sen [output "false] if equalp first :pat first :sen [output match butfirst :pat butfirst :sen] output "false end ;; Parsing quantifiers to special :pat :sen set.special parse.special butfirst first :pat " output run word "match first first :pat end to parse.special :word :var if emptyp :word [output list :var "always] if equalp first :word ": [output list :var butfirst :word] output parse.special butfirst :word word :var first :word end to set.special :list make "special.var first :list make "special.pred last :list if emptyp :special.var [make "special.var "special.buffer] if memberp :special.pred [in anyof] [set.in] if not emptyp :special.pred [stop] make "special.pred first butfirst :pat make "pat fput first :pat butfirst butfirst :pat end to set.in make "in.list first butfirst :pat make "pat fput first :pat butfirst butfirst :pat end ;; Exactly one match to match! if emptyp :sen [output "false] if not try.pred [output "false] make :special.var first :sen output match butfirst :pat butfirst :sen end ;; Zero or one match to match? make :special.var [] if emptyp :sen [output match butfirst :pat :sen] if not try.pred [output match butfirst :pat :sen] make :special.var first :sen if match butfirst :pat butfirst :sen [output "true] make :special.var [] output match butfirst :pat :sen end ;; Zero or more matches to match# make :special.var [] output #test #gather :sen end to #gather :sen if emptyp :sen [output :sen] if not try.pred [output :sen] make :special.var lput first :sen thing :special.var output #gather butfirst :sen end to #test :sen if match butfirst :pat :sen [output "true] if emptyp thing :special.var [output "false] output #test2 fput last thing :special.var :sen end to #test2 :sen make :special.var butlast thing :special.var output #test :sen end ;; One or more matches to match& output &test match# end to &test :tf if emptyp thing :special.var [output "false] output :tf end ;; Zero or more matches (as few as possible) to match^ make :special.var [] output ^test :sen end to ^test :sen if match butfirst :pat :sen [output "true] if emptyp :sen [output "false] if not try.pred [output "false] make :special.var lput first :sen thing :special.var output ^test butfirst :sen end ;; Match words in a group to match@ make :special.var :sen output @test [] end to @test :sen if @try.pred [if match butfirst :pat :sen [output "true]] if emptyp thing :special.var [output "false] output @test2 fput last thing :special.var :sen end to @test2 :sen make :special.var butlast thing :special.var output @test :sen end ;; Applying the predicates to try.pred if listp :special.pred [output match :special.pred first :sen] output run list :special.pred quoted first :sen end to quoted :thing if listp :thing [output :thing] output word "" :thing end to @try.pred if listp :special.pred [output match :special.pred thing :special.var] output run list :special.pred thing :special.var end ;; Special predicates to always :x output "true end to in :word output memberp :word :in.list end to anyof :sen output anyof1 :sen :in.list end to anyof1 :sen :pats if emptyp :pats [output "false] if match first :pats :sen [output "true] output anyof1 :sen butfirst :pats end ucblogo-5.5/csls/math0100644000161300001330000001631406321252134012553 0ustar bhdoe;;; Logic problem inference system ;; Establish categories to category :category.name :members print (list "category :category.name :members) if not namep "categories [make "categories []] make "categories lput :category.name :categories make :category.name :members foreach :members [pprop ? "category :category.name] end ;; Verify and falsify matches to verify :a :b settruth :a :b "true end to falsify :a :b settruth :a :b "false end to settruth :a :b :truth.value if equalp (gprop :a "category) (gprop :b "category) [stop] localmake "oldvalue get :a :b if equalp :oldvalue :truth.value [stop] if equalp :oldvalue (not :truth.value) ~ [(throw "error (sentence [inconsistency in settruth] :a :b :truth.value))] print (list :a :b "-> :truth.value) store :a :b :truth.value settruth1 :a :b :truth.value settruth1 :b :a :truth.value if not emptyp :oldvalue ~ [foreach (filter [equalp first ? :truth.value] :oldvalue) [apply "settruth butfirst ?]] end to settruth1 :a :b :truth.value apply (word "find not :truth.value) (list :a :b) foreach (gprop :a "true) [settruth ? :b :truth.value] if :truth.value [foreach (gprop :a "false) [falsify ? :b] pprop :a (gprop :b "category) :b] pprop :a :truth.value (fput :b gprop :a :truth.value) end to findfalse :a :b foreach (filter [not equalp get ? :b "true] peers :a) ~ [falsify ? :b] end to findtrue :a :b if equalp (count peers :a) (1+falses :a :b) ~ [verify (find [not equalp get ? :b "false] peers :a) :b] end to falses :a :b output count filter [equalp "false get ? :b] peers :a end to peers :a output thing gprop :a "category end ;; Common types of clues to differ :list print (list "differ :list) foreach :list [differ1 ? ?rest] end to differ1 :a :them foreach :them [falsify :a ?] end to justbefore :this :that :lineup falsify :this :that falsify :this last :lineup falsify :that first :lineup justbefore1 :this :that :lineup end to justbefore1 :this :that :slotlist if emptyp butfirst :slotlist [stop] equiv :this (first :slotlist) :that (first butfirst :slotlist) justbefore1 :this :that (butfirst :slotlist) end ;; Remember conditional linkages to implies :who1 :what1 :truth1 :who2 :what2 :truth2 implies1 :who1 :what1 :truth1 :who2 :what2 :truth2 implies1 :who2 :what2 (not :truth2) :who1 :what1 (not :truth1) end to implies1 :who1 :what1 :truth1 :who2 :what2 :truth2 localmake "old1 get :who1 :what1 if equalp :old1 :truth1 [settruth :who2 :what2 :truth2 stop] if equalp :old1 (not :truth1) [stop] if memberp (list :truth1 :who2 :what2 (not :truth2)) :old1 ~ [settruth :who1 :what1 (not :truth1) stop] if memberp (list :truth1 :what2 :who2 (not :truth2)) :old1 ~ [settruth :who1 :what1 (not :truth1) stop] store :who1 :what1 ~ fput (list :truth1 :who2 :what2 :truth2) :old1 end to equiv :who1 :what1 :who2 :what2 implies :who1 :what1 "true :who2 :what2 "true implies :who2 :what2 "true :who1 :what1 "true end to xor :who1 :what1 :who2 :what2 implies :who1 :what1 "true :who2 :what2 "false implies :who1 :what1 "false :who2 :what2 "true end ;; Interface to property list mechanism to get :a :b output gprop :a :b end to store :a :b :val pprop :a :b :val pprop :b :a :val end ;; Print the solution to solution foreach thing first :categories [solve1 ? butfirst :categories] end to solve1 :who :order type :who foreach :order [type "| | type gprop :who ?] print [] end ;; Get rid of old problem data to cleanup if not namep "categories [stop] ern :categories ern "categories erpls end ;; Anita Harnadek's problem to cub.reporter cleanup category "first [Jane Larry Opal Perry] category "last [Irving King Mendle Nathan] category "age [32 38 45 55] category "job [drafter pilot sergeant driver] differ [Jane King Larry Nathan] says "Jane "Irving 45 says "King "Perry "driver says "Larry "sergeant 45 says "Nathan "drafter 38 differ [Mendle Jane Opal Nathan] says "Mendle "pilot "Larry says "Jane "pilot 45 says "Opal 55 "driver says "Nathan 38 "driver print [] solution end to says :who :what1 :what2 print (list "says :who :what1 :what2) xor :who :what1 :who :what2 end ;; Diane Baldwin's problem to foote.family cleanup category "when [1st 2nd 3rd 4th 5th] category "name [Felix Fred Frank Francine Flo] category "street [Field Flag Fig Fork Frond] category "item [food film flashlight fan fiddle] category "position [1 2 3 4 5] print [Clue 1] justbefore "Flag "2nd :position justbefore "2nd "Fred :position print [Clue 2] male [film Fig 5th] print [Clue 3] justbefore "flashlight "Fork :position justbefore "Fork "1st :position female [1st] print [Clue 4] falsify "5th "Frond falsify "5th "fan print [Clue 5] justbefore "Francine "Frank :position justbefore "Francine "Frank :when print [Clue 6] female [3rd Flag] print [Clue 7] justbefore "fiddle "Frond :when justbefore "Flo "fiddle :when print [] solution end to male :stuff differ sentence :stuff [Francine Flo] end to female :stuff differ sentence :stuff [Felix Fred Frank] end ;;; Combinatorics toolkit to combs :list :howmany if equalp :howmany 0 [output [[]]] if equalp :howmany count :list [output (list :list)] output sentence (map [fput first :list ?] combs (butfirst :list) (:howmany-1)) ~ (combs (butfirst :list) :howmany) end to fact :n output cascade :n [# * ?] 1 end to perms :n :r if equalp :r 0 [output 1] output :n * perms :n-1 :r-1 end to choose :n :r output (perms :n :r)/(fact :r) end ;; The socks problem to socks :list localmake "total combs (expand :list) 2 localmake "matching filter [equalp first ? last ?] :total print (sentence [there are] count :total [possible pairs of socks.]) print (sentence [of these,] count :matching [are matching pairs.]) print sentence [probability of match =] ~ word (100 * (count :matching)/(count :total)) "% end to expand :list if emptyp :list [output []] if numberp first :list ~ [output cascade (first :list) [fput first butfirst :list ?] (expand butfirst butfirst :list)] output fput first :list expand butfirst :list end to socktest localmake "first pick [brown brown brown brown brown brown blue blue blue blue] localmake "second ~ pick (ifelse equalp :first "brown ~ [[brown brown brown brown brown blue blue blue blue]] ~ [[brown brown brown brown brown brown blue blue blue]]) output equalp :first :second end ;; The Simplex lock problem to lock :buttons output cascade :buttons [? + lock1 :buttons #] 1 end to lock1 :total :buttons localmake "perms perms :total :buttons output cascade (twoto (:buttons-1)) [? + lock2 :perms #-1 1] 0 end to lock2 :perms :links :factor if equalp :links 0 [output :perms/(fact :factor)] if equalp (remainder :links 2) 0 ~ [output lock2 :perms/(fact :factor) :links/2 1] output lock2 :perms (:links-1)/2 :factor+1 end to twoto :power output cascade :power [2 * ?] 1 end to simplex :buttons output 2 * f :buttons end to f :n if equalp :n 0 [output 1] output cascade :n [? + ((choose :n (#-1)) * f (#-1))] 0 end to simp :n output round (fact :n)/(power (ln 2) (:n+1)) end ;; The multinomial expansion problem to t :n :k if equalp :k 0 [output 1] if equalp :n 0 [output 0] output (t :n :k-1)+(t :n-1 :k) end ucblogo-5.5/csls/multi0100644000161300001330000000122206135447520012754 0ustar bhdoeprogram multi; {Multinomial expansion problem} var memo: array [0..4, 0..7] of integer; i,j: integer; function t(n,k:integer) : integer; function realt(n,k:integer) : integer; {without memoization} begin {realt} if k = 0 then realt := 1 else if n = 0 then realt := 0 else realt := t(n,k-1)+t(n-1,k) end; {realt} begin {t} if memo[n,k] < 0 then memo[n,k] := realt(n,k); t := memo[n,k] end; {t} begin {main program} {initialization} for i := 0 to 4 do for j := 0 to 7 do memo[i,j] := -1; {How many terms in (a+b+c+d)^7?} writeln(t(4,7)); end. ucblogo-5.5/csls/pascal0100644000161300001330000007265707316164550013112 0ustar bhdoeto compile :file if namep "peekchar [ern "peekchar] if namep "peektoken [ern "peektoken] if not namep "idlist [opsetup] if not emptyp :file [openread :file] setread :file ignore error catch "error [program] localmake "error error if not emptyp :error [print first butfirst :error] setread [] if not emptyp :file [close :file] end ;; Global setup to opsetup make "numregs 32 make "memsize 3000 pprop "|=| "binary [eql 2 [boolean []] 1] pprop "|<>| "binary [neq 2 [boolean []] 1] pprop "|<| "binary [less 2 [boolean []] 1] pprop "|>| "binary [gtr 2 [boolean []] 1] pprop "|<=| "binary [leq 2 [boolean []] 1] pprop "|>=| "binary [geq 2 [boolean []] 1] pprop "|+| "binary [add 2 [[] []] 2] pprop "|-| "binary [sub 2 [[] []] 2] pprop "or "binary [lor 2 [boolean boolean] 2] pprop "|*| "binary [mul 2 [[] []] 3] pprop "|/| "binary [quo 2 [real []] 3] pprop "div "binary [div 2 [integer integer] 3] pprop "mod "binary [rem 2 [integer integer] 3] pprop "and "binary [land 2 [boolean boolean] 3] pprop "|+| "unary [plus 1 [[] []] 4] pprop "|-| "unary [minus 1 [[] []] 4] pprop "not "unary [lnot 1 [boolean boolean] 4] make "idlist `[[trunc function int [1 ,[framesize.fun+1]]] [round function round [1 ,[framesize.fun+1]]] [random function random [1 ,[framesize.fun+1]]]] make "int [integer real] make "round [integer real] make "random [integer integer] end ;; Block structure to program mustbe "program localmake "progname token ifbe "|(| [ignore commalist [id] mustbe "|)|] mustbe "|;| localmake "lexical.depth 0 localmake "namesused [] localmake "needint "false localmake "needround "false localmake "needrandom "false localmake "idlist :idlist localmake "frame [0 0] localmake "id (list :progname "program (newlname :progname) :frame) push "idlist :id localmake "codeinto word "% :progname make :codeinto [] localmake "framesize framesize.proc program1 mustbe ". code [exit] foreach [int round random] "plibrary make :codeinto reverse thing :codeinto end to program1 localmake "regsused (array :numregs 0) for [i reg.firstfree :numregs-1] [setitem :i :regsused "false] ifbe "var [varpart] .setfirst butfirst :frame :framesize if :lexical.depth = 0 [code (list "add reg.globalptr reg.zero reg.zero) code (list "add reg.frameptr reg.zero reg.zero) code (list "addi reg.stackptr reg.zero :framesize)] localmake "bodytag gensym code (list "jump (word "" :bodytag)) tryprocpart code :bodytag mustbe "begin blockbody "end end to plibrary :func if not thing (word "need :func) [stop] code :func code (list "rload reg.firstfree (memaddr framesize.fun reg.frameptr)) code (list (word "s :func) reg.retval reg.firstfree) code (list "add reg.stackptr reg.frameptr reg.zero) code (list "rload reg.frameptr (memaddr frame.prevframe reg.stackptr)) code (list "jr reg.retaddr) end ;; Variable declarations to varpart local [token namelist type] make "token token make "peektoken :token if reservedp :token [stop] vargroup foreach :namelist [newvar ? :type] mustbe "|;| varpart end to vargroup make "namelist commalist [id] mustbe ": ifbe "packed [] make "type token ifelse equalp :type "array [make "type arraytype] [typecheck :type] end to id local "token make "token token if letterp ascii first :token [output :token] make "peektoken :token output [] end to arraytype local [ranges type] mustbe "|[| make "ranges commalist [range] mustbe "|]| mustbe "of make "type token typecheck :type output list :type :ranges end to range local [first last] make "first range1 mustbe ".. make "last range1 if :first > :last ~ [(throw "error (sentence [array bounds not increasing:] :first ".. :last))] output list :first (1 + :last - :first) end to range1 local "bound make "bound token if equalp first :bound "' [output ascii first butfirst :bound] if equalp :bound "|-| [make "bound minus token] if equalp :bound int :bound [output :bound] (throw "error sentence [array bound not ordinal:] :bound) end to typecheck :type if memberp :type [real integer char boolean] [stop] (throw "error sentence [undefined type] :type) end to newvar :pname :type if reservedp :pname [(throw "error sentence :pname [reserved word])] push "idlist (list :pname :type (list :lexical.depth :framesize) "false) make "framesize :framesize + ifelse listp :type [arraysize :type] [1] end to arraysize :type output reduce "product map [last ?] last :type end ;; Procedure and function declarations to tryprocpart ifbeelse "procedure ~ [procedure tryprocpart] ~ [ifbe "function [function tryprocpart]] end to procedure proc1 "procedure framesize.proc end to function proc1 "function framesize.fun end to proc1 :proctype :framesize localmake "procname token localmake "lexical.depth :lexical.depth+1 localmake "frame (list :lexical.depth 0) push "idlist (list :procname :proctype (newlname :procname) :frame) localmake "idlist :idlist make lname :procname [] ifbe "|(| [arglist] if equalp :proctype "function ~ [mustbe ": localmake "type token typecheck :type make lname :procname fput :type thing lname :procname] mustbe "|;| code lname :procname code (list "store reg.retaddr (memaddr frame.retaddr reg.frameptr)) program1 if equalp :proctype "function ~ [code (list "rload reg.retval (memaddr frame.retval reg.frameptr))] code (list "rload reg.retaddr (memaddr frame.retaddr reg.frameptr)) code (list "add reg.stackptr reg.frameptr reg.zero) code (list "rload reg.frameptr (memaddr frame.prevframe reg.stackptr)) code (list "jr reg.retaddr) mustbe "|;| end to arglist local [token namelist type varflag] make "varflag "false ifbe "var [make "varflag "true] vargroup foreach :namelist [newarg ? :type :varflag] ifbeelse "|;| [arglist] [mustbe "|)|] end to newarg :pname :type :varflag if reservedp :pname [(throw "error sentence :pname [reserved word])] localmake "pointer (list :lexical.depth :framesize) push "idlist (list :pname :type :pointer :varflag) make "framesize :framesize + ifelse (and listp :type not :varflag) ~ [arraysize :type] [1] queue lname :procname ifelse :varflag [list "var :type] [:type] end ;; Statement part to blockbody :endword statement ifbeelse "|;| [blockbody :endword] [mustbe :endword] end to statement local [token type] ifbe "begin [compound stop] ifbe "for [pfor stop] ifbe "if [pif stop] ifbe "while [pwhile stop] ifbe "repeat [prepeat stop] ifbe "write [pwrite stop] ifbe "writeln [pwriteln stop] make "token token make "peektoken :token if memberp :token [|;| end until] [stop] make "type gettype :token if emptyp :type [(throw "error sentence :token [can't begin statement])] if equalp :type "procedure [pproccall stop] if equalp :type "function [pfunset stop] passign end ;; Compound statement to compound blockbody "end end ;; Structured statements to pfor local [var init step final looptag endtag testreg] make "var token mustbe "|:=| make "init pinteger pexpr make "step 1 ifbeelse "downto [make "step -1] [mustbe "to] make "final pinteger pexpr mustbe "do make "looptag gensym make "endtag gensym code :looptag localmake "id getid :var codestore :init (id.pointer :id) (id.varp :id) 0 make "testreg newregister code (list (ifelse :step<0 ["less] ["gtr]) :testreg :init :final) code (list "jumpt :testreg (word "" :endtag)) regfree :testreg statement code (list "addi :init :init :step) code (list "jump (word "" :looptag)) code :endtag regfree :init regfree :final end to prepeat local [cond looptag] make "looptag gensym code :looptag blockbody "until make "cond pboolean pexpr code (list "jumpf :cond (word "" :looptag)) regfree :cond end to pif local [cond elsetag endtag] make "cond pboolean pexpr make "elsetag gensym make "endtag gensym mustbe "then code (list "jumpf :cond (word "" :elsetag)) regfree :cond statement code (list "jump (word "" :endtag)) code :elsetag ifbe "else [statement] code :endtag end to pwhile local [cond looptag endtag] make "looptag gensym make "endtag gensym code :looptag make "cond pboolean pexpr code (list "jumpf :cond (word "" :endtag)) regfree :cond mustbe "do statement code (list "jump (word "" :looptag)) code :endtag end ;; Simple statements: write and writeln to pwrite mustbe "|(| pwrite1 end to pwrite1 pwrite2 ifbe "|)| [stop] ifbeelse ", [pwrite1] [(throw "error [missing comma])] end to pwrite2 localmake "result pwrite3 ifbe ": [.setfirst (butfirst :result) token] code :result if not equalp first :result "putstr [regfree last :result] end to pwrite3 localmake "token token if equalp first :token "' ~ [output (list "putstr 1 (list butlast butfirst :token))] make "peektoken :token localmake "result pexpr if equalp first :result "char [output (list "putch 1 pchar :result)] if equalp first :result "boolean [output (list "puttf 1 pboolean :result)] if equalp first :result "integer [output (list "putint 10 pinteger :result)] output (list "putreal 20 preal :result) end to pwriteln ifbe "|(| [pwrite1] code [newline] end ;; Simple statements: procedure call to pproccall localmake "pname token localmake "id getid :pname localmake "lname id.lname :id localmake "vartypes thing :lname pproccall1 framesize.proc end to pproccall1 :offset code (list "store reg.newfp (memaddr frame.save.newfp reg.stackptr)) code (list "add reg.newfp reg.stackptr reg.zero) code (list "addi reg.stackptr reg.stackptr (last id.frame :id)) code (list "store reg.frameptr (memaddr frame.prevframe reg.newfp)) localmake "newdepth first id.frame :id ifelse :newdepth > :lexical.depth ~ [code (list "store reg.frameptr (memaddr frame.outerframe reg.newfp))] ~ [localmake "tempreg newregister code (list "rload :tempreg (memaddr frame.outerframe reg.frameptr)) repeat (:lexical.depth - :newdepth) [code (list "rload :tempreg (memaddr frame.outerframe :tempreg))] code (list "store :tempreg (memaddr frame.outerframe reg.newfp)) regfree :tempreg] if not emptyp :vartypes [mustbe "|(| procargs :vartypes :offset] for [i reg.firstfree :numregs-1] ~ [if item :i :regsused [code (list "store :i (memaddr frame.regsave+:i reg.frameptr))]] code (list "add reg.frameptr reg.newfp reg.zero) code (list "rload reg.newfp (memaddr frame.save.newfp reg.frameptr)) code (list "jal reg.retaddr (word "" :lname)) for [i reg.firstfree :numregs-1] ~ [if item :i :regsused [code (list "rload :i (memaddr frame.regsave+:i reg.frameptr))]] end to procargs :types :offset if emptyp :types [mustbe "|)| stop] localmake "next procarg first :types :offset if not emptyp butfirst :types [mustbe ",] procargs butfirst :types :offset+:next end to procarg :type :offset local "result if equalp first :type "var [output procvararg last :type] if listp :type [output procarrayarg :type] make "result check.type :type pexpr code (list "store :result (memaddr :offset reg.newfp)) regfree :result output 1 end to procvararg :ftype local [pname id type index] make "pname token make "id getid :pname make "type id.type :id ifelse wordp :ftype ~ [setindex "true] ~ [make "index 0] if not equalp :type :ftype ~ [(throw "error sentence :pname [arg wrong type])] localmake "target memsetup (id.pointer :id) (id.varp :id) :index localmake "tempreg newregister code (list "addi :tempreg (last :target) (first :target)) code (list "store :tempreg (memaddr :offset reg.newfp)) regfree last :target regfree :tempreg output 1 end to procarrayarg :type localmake "pname token localmake "id getid :pname if not equalp :type (id.type :id) ~ [(throw "error (sentence "array :pname [wrong type for arg]))] localmake "size arraysize :type localmake "rtarget memsetup (id.pointer :id) (id.varp :id) 0 localmake "pointreg newregister code (list "addi :pointreg reg.newfp :offset) localmake "ltarget (list 0 :pointreg) copyarray output :size end ;; Simple statements: assignment statement (including function value) to passign local [name id type index value pointer target] make "name token make "index [] ifbe "|[| [make "index commalist [pexpr] mustbe "|]|] mustbe "|:=| make "id getid :name make "pointer id.pointer :id make "type id.type :id passign1 end to pfunset local [name id type index value pointer target] make "name token make "index [] if not equalp :name :procname ~ [(throw "error sentence [assign to wrong function] :name)] mustbe "|:=| make "pointer (list :lexical.depth frame.retval) make "type first thing lname :name make "id (list :name :type :pointer "false) passign1 end to passign1 if and (listp :type) (emptyp :index) [parrayassign :id stop] setindex "false make "value check.type :type pexpr codestore :value (id.pointer :id) (id.varp :id) :index regfree :value end to noimmediate :value if equalp exp.mode :value "immediate ~ [localmake "reg newregister code (list "addi :reg reg.zero exp.value :value) output (list exp.type :value "register :reg)] output :value end to check.type :type :result if equalp :type "real [output preal :result] if equalp :type "integer [output pinteger :result] if equalp :type "char [output pchar :result] if equalp :type "boolean [output pboolean :result] end to preal :expr [:pval noimmediate :expr] if equalp exp.type :pval "real [output exp.value :pval] output pinteger :pval end to pinteger :expr [:pval noimmediate :expr] local "type make "type exp.type :pval if memberp :type [integer boolean char] [output exp.value :pval] (throw "error sentence exp.type :pval [isn't ordinal]) end to pchar :expr [:pval noimmediate :expr] if equalp exp.type :pval "char [output exp.value :pval] (throw "error sentence exp.type :pval [not character value]) end to pboolean :expr [:pval noimmediate :expr] if equalp exp.type :pval "boolean [output exp.value :pval] (throw "error sentence exp.type :pval [not true or false]) end to parrayassign :id localmake "right token if equalp first :right "' ~ [pstringassign :type (butlast butfirst :right) stop] localmake "rid getid :right if not equalp (id.type :id) (id.type :rid) ~ [(throw "error (sentence "arrays :name "and :right [unequal types]))] localmake "size arraysize id.type :id localmake "ltarget memsetup (id.pointer :id) (id.varp :id) 0 localmake "rtarget memsetup (id.pointer :rid) (id.varp :rid) 0 copyarray end to pstringassign :type :string if not equalp first :type "char [stringlose] if not emptyp butfirst last :type [stringlose] if not equalp (last first last :type) (count :string) [stringlose] localmake "ltarget memsetup (id.pointer :id) (id.varp :id) 0 pstringassign1 newregister (first :ltarget) (last :ltarget) :string regfree last :ltarget end to pstringassign1 :tempreg :offset :reg :string if emptyp :string [regfree :tempreg stop] code (list "addi :tempreg reg.zero ascii first :string) code (list "store :tempreg (memaddr :offset :reg)) pstringassign1 :tempreg :offset+1 :reg (butfirst :string) end to stringlose (throw "error sentence :name [not string array or wrong size]) end ;; Multiple array indices to linear index computation to setindex :parseflag ifelse listp :type ~ [if :parseflag [mustbe "|[| make "index commalist [pexpr] mustbe "|]| ] make "index lindex last :type :index make "type first :type] ~ [make "index 0] end to lindex :bounds :index output lindex1 (offset pinteger noimmediate first :index first first :bounds) ~ butfirst :bounds butfirst :index end to lindex1 :sofar :bounds :index if emptyp :bounds [output :sofar] output lindex1 (nextindex :sofar last first :bounds pinteger noimmediate first :index first first :bounds) ~ butfirst :bounds butfirst :index end to nextindex :old :factor :new :offset code (list "muli :old :old :factor) localmake "newreg offset :new :offset code (list "add :old :old :newreg) regfree :newreg output :old end to offset :indexreg :lowbound if not equalp :lowbound 0 [code (list "subi :indexreg :indexreg :lowbound)] output :indexreg end ;; Memory interface: load and store instructions to codeload :reg :pointer :varflag :index localmake "target memsetup :pointer :varflag :index code (list "rload :reg targetaddr) regfree last :target end to codestore :reg :pointer :varflag :index localmake "target memsetup :pointer :varflag :index code (list "store :reg targetaddr) regfree last :target end to targetaddr output memaddr (first :target) (last :target) end to memaddr :offset :index output (word :offset "\( :index "\)) end to memsetup :pointer :varflag :index localmake "depth first :pointer localmake "offset last :pointer local "newreg ifelse equalp :depth 0 ~ [make "newreg reg.globalptr] ~ [ifelse equalp :depth :lexical.depth [make "newreg reg.frameptr] [make "newreg newregister code (list "rload :newreg (memaddr frame.outerframe reg.frameptr)) repeat (:lexical.depth - :depth) - 1 [code (list "rload :newreg (memaddr frame.outerframe :newreg))]]] if :varflag ~ [ifelse :newreg = reg.frameptr [make "newreg newregister code (list "rload :newreg (memaddr :offset reg.frameptr))] [code (list "rload :newreg (memaddr :offset :newreg))] make "offset 0] if not equalp :index 0 ~ [code (list "add :index :index :newreg) regfree :newreg make "newreg :index] output list :offset :newreg end to copyarray localmake "looptag gensym localmake "sizereg newregister code (list "addi :sizereg reg.zero :size) code :looptag localmake "tempreg newregister code (list "rload :tempreg (memaddr (first :rtarget) (last :rtarget))) code (list "store :tempreg (memaddr (first :ltarget) (last :ltarget))) code (list "addi (last :rtarget) (last :rtarget) 1) code (list "addi (last :ltarget) (last :ltarget) 1) code (list "subi :sizereg :sizereg 1) code (list "gtr :tempreg :sizereg reg.zero) code (list "jumpt :tempreg (word "" :looptag)) regfree :sizereg regfree :tempreg regfree last :ltarget regfree last :rtarget end ;; Expressions to pexpr local [opstack datastack parenlevel] make "opstack [[popen 1 0]] make "datastack [] make "parenlevel 0 output pexpr1 end to pexpr1 local [token op] make "token token while [equalp :token "|(|] [popen make "token token] make "op pgetunary :token if not emptyp :op [output pexprop :op] push "datastack pdata :token make "token token while [and (:parenlevel > 0) (equalp :token "|)| )] ~ [pclose make "token token] make "op pgetbinary :token if not emptyp :op [output pexprop :op] make "peektoken :token pclose if not emptyp :opstack [(throw "error [too many operators])] if not emptyp butfirst :datastack [(throw "error [too many operands])] output pop "datastack end to pexprop :op while [(op.prec :op) < (1 + op.prec first :opstack)] [ppopop] push "opstack :op output pexpr1 end to popen push "opstack [popen 1 0] make "parenlevel :parenlevel + 1 end to pclose while [(op.prec first :opstack) > 0] [ppopop] ignore pop "opstack make "parenlevel :parenlevel - 1 end to pgetunary :token output gprop :token "unary end to pgetbinary :token output gprop :token "binary end to ppopop local [op function args left right type reg] make "op pop "opstack make "function op.instr :op if equalp :function "plus [stop] make "args op.nargs :op make "right pop "datastack make "left (ifelse equalp :args 2 [pop "datastack] [[[] []]]) make "type pnewtype :op exp.type :left exp.type :right if equalp exp.mode :left "immediate ~ [localmake "leftreg newregister code (list "addi :leftreg reg.zero exp.value :left) make "left (list exp.type :left "register :leftreg)] ifelse equalp exp.mode :left "register ~ [make "reg exp.value :left] ~ [ifelse equalp exp.mode :right "register [make "reg exp.value :right] [make "reg newregister]] if equalp :function "minus ~ [make "left (list exp.type :right "register reg.zero) make "function "sub make "args 2] if equalp exp.mode :right "immediate ~ [make "function word :function "i] ifelse equalp :args 2 ~ [code (list :function :reg exp.value :left exp.value :right)] ~ [code (list :function :reg exp.value :right)] if not equalp :reg exp.value :left [regfree exp.value :left] if (and (equalp exp.mode :right "register) (not equalp :reg exp.value :right)) ~ [regfree exp.value :right] push "datastack (list :type "register :reg) end to pnewtype :op :ltype :rtype local "type make "type op.types :op if emptyp :ltype [make "ltype :rtype] if not emptyp last :type [pchecktype last :type :ltype :rtype] if and (equalp :ltype "real) (equalp :rtype "integer) [make "rtype "real] if and (equalp :ltype "integer) (equalp :rtype "real) [make "ltype "real] if not equalp :ltype :rtype [(throw "error [type clash])] if emptyp last :type ~ [if not memberp :rtype [integer real] [(throw "error [nonarithmetic type])]] if emptyp first :type [output :rtype] output first :type end to pchecktype :want :left :right if not equalp :want :left [(throw "error (sentence :left "isn't :want))] if not equalp :want :right [(throw "error (sentence :right "isn't :want))] end ;; Expression elements to pdata :token if equalp :token "true [output [boolean immediate 1]] if equalp :token "false [output [boolean immediate 0]] if equalp first :token "' [output pchardata :token] if numberp :token [output (list numtype :token "immediate :token)] localmake "id getid :token if emptyp :id [(throw "error sentence [undefined symbol] :token)] localmake "type id.type :id if equalp :type "function [output pfuncall :token] local "index setindex "true localmake "reg newregister codeload :reg (id.pointer :id) (id.varp :id) :index output (list :type "register :reg) end to pchardata :token if not equalp count :token 3 ~ [(throw "error sentence :token [not single character])] output (list "char "immediate ascii first butfirst :token) end to numtype :number if memberp ". :number [output "real] if memberp "e :number [output "real] output "integer end to pfuncall :pname localmake "id getid :pname localmake "lname id.lname :id if namep (word "need :lname) [make (word "need :lname) "true] localmake "vartypes thing :lname localmake "returntype first :vartypes make "vartypes butfirst :vartypes pproccall1 framesize.fun localmake "reg newregister code (list "add :reg reg.retval reg.zero) output (list :returntype "register :reg) end ;; Parsing assistance to code :stuff if emptyp :stuff [stop] push :codeinto :stuff end to commalist :test [:sofar []] local [result token] make "result run :test if emptyp :result [output :sofar] ifbe ", [output (commalist :test (lput :result :sofar))] output lput :result :sofar end .macro ifbe :wanted :action localmake "token token if equalp :token :wanted [output :action] make "peektoken :token output [] end .macro ifbeelse :wanted :action :else localmake "token token if equalp :token :wanted [output :action] make "peektoken :token output :else end to mustbe :wanted localmake "token token if equalp :token :wanted [stop] (throw "error (sentence "expected :wanted "got :token)) end to newregister for [i reg.firstfree :numregs-1] ~ [if not item :i :regsused [setitem :i :regsused "true output :i]] (throw "error [not enough registers available]) end to regfree :reg setitem :reg :regsused "false end to reservedp :word output memberp :word [and array begin case const div do downto else end ~ file for forward function goto if in label mod nil ~ not of packed procedure program record repeat set ~ then to type until var while with] end ;; Lexical analysis to token local [token char] if namep "peektoken [make "token :peektoken ern "peektoken output :token] make "char getchar if equalp :char "|{| [skipcomment output token] if equalp :char char 32 [output token] if equalp :char char 13 [output token] if equalp :char char 10 [output token] if equalp :char "' [output string "'] if memberp :char [+ - * / = ( , ) |[| |]| |;|] [output :char] if equalp :char "|<| [output twochar "|<| [= >]] if equalp :char "|>| [output twochar "|>| [=]] if equalp :char ". [output twochar ". [.]] if equalp :char ": [output twochar ": [=]] if numberp :char [output number :char] if letterp ascii :char [output token1 lowercase :char] (throw "error sentence [unrecognized character:] :char) end to skipcomment if equalp getchar "|}| [stop] skipcomment end to string :string local "char make "char getchar if not equalp :char "' [output string word :string :char] make "char getchar if equalp :char "' [output string word :string :char] make "peekchar :char output word :string "' end to twochar :old :ok localmake "char getchar if memberp :char :ok [output word :old :char] make "peekchar :char output :old end to number :num local "char make "char getchar if equalp :char ". ~ [make "char getchar ~ ifelse equalp :char ". ~ [make "peektoken ".. output :num] ~ [make "peekchar :char output number word :num ".]] if equalp :char "e [output number word :num twochar "e [+ -]] if numberp :char [output number word :num :char] make "peekchar :char output :num end to token1 :token local "char make "char getchar if or letterp ascii :char numberp :char ~ [output token1 word :token lowercase :char] make "peekchar :char output :token end to letterp :code if and (:code > 64) (:code < 91) [output "true] output and (:code > 96) (:code < 123) end to getchar local "char if namep "peekchar [make "char :peekchar ern "peekchar output :char] if eofp [output char 1] output rc1 end to rc1 local "result make "result readchar type :result output :result end ;; Data abstraction: ID List to newlname :word if memberp :word :namesused [output gensym] if namep word "% :word [output gensym] push "namesused :word output word "% :word end to lname :word local "result make "result getid :word if not emptyp :result [output item 3 :result] (throw "error sentence [unrecognized identifier] :word) end to gettype :word local "result make "result getid :word if not emptyp :result [output item 2 :result] (throw "error sentence [unrecognized identifier] :word) end to getid :word [:list :idlist] if emptyp :list [output []] if equalp :word first first :list [output first :list] output (getid :word butfirst :list) end to id.type :id output item 2 :id end to id.pointer :id output item 3 :id end to id.lname :id output item 3 :id end to id.varp :id output item 4 :id end to id.frame :id output item 4 :id end ;; Data abstraction: Frame slots to frame.retaddr output 0 end to frame.save.newfp output 1 end to frame.outerframe output 2 end to frame.prevframe output 3 end to frame.regsave output 4 end to framesize.proc output 4+:numregs end to frame.retval output 4+:numregs end to framesize.fun output 5+:numregs end ;; Data abstraction: Operators to op.instr :op output first :op end to op.nargs :op output first bf :op end to op.types :op output item 3 :op end to op.prec :op output last :op end ;; Data abstraction: Expressions to exp.type :exp output first :exp end to exp.mode :exp output first butfirst :exp end to exp.value :exp output last :exp end ;; Data abstraction: Registers to reg.zero output 0 end to reg.retaddr output 1 end to reg.stackptr output 2 end to reg.globalptr output 3 end to reg.frameptr output 4 end to reg.newfp output 5 end to reg.retval output 6 end to reg.firstfree output 7 end ;; Runtime (machine simulation) to prun :progname localmake "prog thing word "% :progname localmake "regs (array :numregs 0) local filter "wordp :prog foreach :prog [if wordp ? [make ? ?rest]] localmake "memory (array :memsize 0) setitem 0 :regs 0 if not procedurep "add [runsetup] prun1 :prog end to prun1 :pc if emptyp :pc [stop] if listp first :pc [run first :pc] prun1 butfirst :pc end to rload :reg :offset :index setitem :reg :regs (item (item :index :regs)+:offset :memory) end to store :reg :offset :index setitem (item :index :regs)+:offset :memory (item :reg :regs) end to runsetup foreach [[add sum] [sub difference] [mul product] [quo quotient] [div [int quotient]] [rem remainder] [land product] [lor [tobool lessp 0 sum]] [eql [tobool equalp]] [neq [tobool not equalp]] [less [tobool lessp]] [gtr [tobool greaterp]] [leq [tobool not greaterp]] [geq [tobool not lessp]]] ~ [define first ? `[[dest src1 src2] [setitem :dest :regs ,@[last ?] (item :src1 :regs) (item :src2 :regs)]] define word first ? "i `[[dest src1 immed] [setitem :dest :regs ,@[last ?] (item :src1 :regs) :immed]]] foreach [[lnot [difference 1]] [sint int] [sround round] [srandom random]] ~ [define first ? `[[dest src] [setitem :dest :regs ,@[last ?] (item :src :regs)]] define word first ? "i `[[dest immed] [setitem :dest :regs ,@[last ?] :immed]]] end to tobool :tf output ifelse :tf [1] [0] end to jump :label make "pc fput :label thing :label end to jumpt :reg :label if (item :reg :regs)=1 [jump :label] end to jumpf :reg :label if (item :reg :regs)=0 [jump :label] end to jr :reg make "pc item :reg :regs end to jal :reg :label setitem :reg :regs :pc jump :label end to putch :width :reg spaces :width 1 type char (item :reg :regs) end to putstr :width :string spaces :width (count first :string) type :string end to puttf :width :bool spaces :width 1 type ifelse (item :bool :regs)=0 ["F] ["T] end to putint :width :reg localmake "num (item :reg :regs) spaces :width count :num type :num end to putreal :width :reg putint :width :reg end to spaces :width :count if :width > :count [repeat :width - :count [type "| |]] end to newline print [] end to exit make "pc [exit] end ucblogo-5.5/csls/playfair0100644000161300001330000000403305757175170013444 0ustar bhdoeto playfair :keyword :message local [matrix a b c d e f g h i j k l m n o p q r s t u v w x y z] setkeyword jtoi lowercase :keyword output encode (reduce "word :message) end ;; Prepare the code array to setkeyword :word make "matrix reorder word :word (remove :word "abcdefghiklmnopqrstuvwxyz) make "j :i end to remove :letters :string if emptyp :string [output "] if memberp first :string :letters [output remove :letters bf :string] output word first :string remove :letters bf :string end to reorder :string output reorder1 :string (mdarray [5 5]) 1 1 end to reorder1 :string :array :row :column if :row=6 [output :array] if :column=6 [output reorder1 :string :array :row+1 1] mdsetitem (list :row :column) :array first :string make first :string (list :row :column) output reorder1 (butfirst :string) :array :row :column+1 end ;; Encode the message to encode :message if emptyp :message [output "] if emptyp butfirst :message [output paircode first :message "q] if equalp (jtoi first :message) (jtoi first butfirst :message) ~ [output word (paircode first :message "q) (encode butfirst :message)] output word (paircode first :message first butfirst :message) ~ (encode butfirst butfirst :message) end to paircode :one :two local [row1 column1 row2 column2] make "row1 first thing :one make "column1 last thing :one make "row2 first thing :two make "column2 last thing :two if :row1 = :row2 ~ [output letters (list :row1 rotate (:column1+1)) ~ (list :row1 rotate (:column2+1))] if :column1 = :column2 ~ [output letters (list rotate (:row1+1) :column1) ~ (list rotate (:row2+1) :column1)] output letters (list :row1 :column2) (list :row2 :column1) end to rotate :index output ifelse :index = 6 [1] [:index] end to letters :one :two output word letter :one letter :two end to letter :rowcol output itoj mditem :rowcol :matrix end ;; I and J conversion to jtoi :word output map [ifelse equalp ? "j ["i] [?]] :word end to itoj :letter if :letter = "i [if (random 3) = 0 [output "j]] output :letter end ucblogo-5.5/csls/plot0100644000161300001330000000164006102422714012574 0ustar bhdoeto plot :inputs keyword :inputs [maxharm 5 deltax 2 yscale 75 cycles 1 xrange 230 skip 2] localmake "xscale :cycles*180/:xrange splitscreen clearscreen hideturtle penup setpos list (-:xrange) 0 pendown for [x :deltax [2*:xrange] :deltax] ~ [setpos list (xcor+:deltax) (:yscale * series :maxharm)] end ;; Compute the Fourier series values to series :harmonic if :harmonic < 1 [output 0] output (term :harmonic)+(series :harmonic-:skip) end to term :harmonic output (sin :xscale * :harmonic * :x) / :harmonic end ;; Handle keyword inputs .macro keyword :inputs :defaults if or (wordp :inputs) (numberp first :inputs) ~ [make "inputs sentence (first :defaults) :inputs] output `[local ,[filter [not numberp ?] :defaults] setup.values ,[:defaults] setup.values ,[:inputs]] end to setup.values :list if emptyp :list [stop] make first :list first butfirst :list setup.values butfirst butfirst :list end ucblogo-5.5/csls/poker0100644000161300001330000000306205752214130012737 0ustar bhdoeto pokerhand :cards local [ranks suits rankarray] poker.init :cards if fourp [print [four of a kind] stop] if full.housep [print [full house] stop] if threep [print [three of a kind] stop] if pairp [print ifelse paircount = 1 [[one pair]] [[two pairs]] stop] if ace.highp [print ifelse flushp [[royal flush]] [[straight]] stop] if straightp [print ifelse flushp [[straight flush]] [[straight]] stop] if flushp [print [flush] stop] print [nothing!] end to poker.init :cards make "ranks map [ranknum butlast ?] :cards make "suits remdup map "last :cards make "rankarray {0 0 0 0 0 0 0 0 0 0 0 0 0} foreach :ranks [setitem ? :rankarray (item ? :rankarray)+1] end to ranknum :rank if :rank = "a [output 1] if :rank = "j [output 11] if :rank = "q [output 12] if :rank = "k [output 13] output :rank end to fourp output memberp 4 :rankarray end to threep output memberp 3 :rankarray end to pairp output memberp 2 :rankarray end to full.housep output and threep pairp end to paircount output count locate 2 1 end to locate :number :index if :index > 13 [output []] if (item :index :rankarray) = :number ~ [output fput :index (locate :number :index+1)] output locate :number :index+1 end to flushp output emptyp butfirst :suits end to straightp output nogap (reduce "min :ranks) 5 end to min :a :b output ifelse :a < :b [:a] [:b] end to nogap :smallest :howmany if :howmany=0 [output "true] if not equalp (item :smallest :rankarray) 1 [output "false] output nogap :smallest+1 :howmany-1 end to ace.highp if not equalp (item 1 :rankarray) 1 [output "false] output nogap 10 4 end ucblogo-5.5/csls/pour0100644000161300001330000000553605745507160012626 0ustar bhdoe;; Initialization to pour :sizes :goal local [oldstates pitchers won] make "oldstates (list all.empty :sizes) make "pitchers fput 0 (map [#] :sizes) make "won "false win breadth.first make.path [] all.empty :sizes end to all.empty :list output map [0] :list end ;; Tree search to breadth.first :root op breadth.descend (list :root) end to breadth.descend :queue if emptyp :queue [output []] if :won [output last :queue] op breadth.descend sentence (butfirst :queue) ~ (children first :queue) end ;; Generate children to children :path output map.se [children1 :path ?] :pitchers end to children1 :path :from output map.se [child :path :from ?] :pitchers end to child :path :from :to local [state newstate] if :won [output []] if equalp :from :to [output []] make "state path.state :path if not riverp :from ~ [if equalp (water :from) 0 [output []]] if not riverp :to ~ [if equalp (water :to) (size :to) [output []]] make "newstate (newstate :state :from :to) if memberp :newstate :oldstates [output []] make "oldstates fput :newstate :oldstates if memberp :goal :newstate [make "won "true] output (list make.path (fput list :from :to path.moves :path) :newstate) end to newstate :state :from :to if riverp :to [output replace :state :from 0] if riverp :from [output replace :state :to (size :to)] if (water :from) < (room :to) ~ [output replace2 :state ~ :from 0 ~ :to ((water :from)+(water :to))] output replace2 :state ~ :from ((water :from)-(room :to)) ~ :to (size :to) end ;; Printing the result to win :path if emptyp :path [print [Can't do it!] stop] foreach (reverse path.moves :path) "win1 print sentence [Final quantities are] (path.state :path) end to win1 :move print (sentence [Pour from] (printform first :move) [to] (printform last :move)) end to printform :pitcher if riverp :pitcher [output "river] output size :pitcher end ;; Path data abstraction to make.path :moves :state output fput :moves :state end to path.moves :path output first :path end to path.state :path output butfirst :path end ;; Pitcher data abstraction to riverp :pitcher output equalp :pitcher 0 end to size :pitcher output item :pitcher :sizes end to water :pitcher output item :pitcher :state end to room :pitcher output (size :pitcher)-(water :pitcher) end ;; List processing utilities to replace :list :index :value if equalp :index 1 [output fput :value butfirst :list] output fput first :list (replace butfirst :list :index-1 :value) end to replace2 :list :index1 :value1 :index2 :value2 if equalp :index1 1 ~ [output fput :value1 replace butfirst :list :index2-1 :value2] if equalp :index2 1 ~ [output fput :value2 replace butfirst :list :index1-1 :value1] output fput first :list ~ replace2 butfirst :list :index1-1 :value1 :index2-1 :value2 end ucblogo-5.5/csls/psort0100644000161300001330000000400706135447672013005 0ustar bhdoeprogram psort; {partition sort demo} var data: array [0..100] of integer; i: integer; procedure showdata; {print the array} var i: integer; begin {showdata} for i := 0 to 99 do begin if i mod 20 = 0 then writeln; write(data[i]:3) end; writeln; writeln end; {showdata} function median(lower,upper:integer):integer; {find the median of three values from the data array} var mid: integer; begin mid := (lower+upper) div 2; if (data[lower] <= data[mid]) and (data[mid] <= data[upper]) then median := mid else if (data[lower] >= data[mid]) and (data[mid] >= data[upper]) then median := mid else if (data[mid] <= data[lower]) and (data[lower] <= data[upper]) then median := lower else if (data[mid] >= data[lower]) and (data[lower] >= data[upper]) then median := lower else median := upper end; procedure sort(lower,upper:integer); {sort part of the array} var key,i,j:integer; procedure exch(var a,b:integer); {exchange two integers} var temp:integer; begin {exch} temp := a; a := b; b := temp end; {exch} begin {sort} if upper > lower then begin exch (data[lower],data[median(lower,upper)]); key := data[lower]; i := lower; j := upper+1; repeat i := i+1 until data[i] >= key; repeat j := j-1 until data[j] <= key; while (i <= j) do begin exch(data[i], data[j]); repeat i := i+1 until data[i] >= key; repeat j := j-1 until data[j] <= key end; exch(data[lower], data[j]); sort(lower,j-1); sort(i,upper) end end; {sort} begin {main program} data[100] := 200; for i := 0 to 99 do data[i] := random(100); writeln('Data before sorting:'); showdata; sort(0,99); writeln('Data after sorting:'); showdata end. ucblogo-5.5/csls/solitaire0100644000161300001330000002363606050377274013636 0ustar bhdoeto solitaire print [Welcome to solitaire] instruct localmake "allranks [A 2 3 4 5 6 7 8 9 10 J Q K] localmake "numranks map "ranknum :allranks localmake "suits [H S D C] localmake "reds [H D] localmake "deckarray (listtoarray (crossmap "word :allranks :suits) 0) localmake "upping "false catch "exit [forever [onegame cleartext]] cleartext end to s solitaire end to onegame print [Shuffling, please wait...] local [card cards digit pile where] localmake "onto [] local map [word "top ?] :suits local cascade 9 [(sentence (word "shown #) (word "hidden #) ?)] [] localmake "ranks :allranks localmake "numstacks 7 local map [word "num ?] :numranks foreach :numranks [make word "num ? 4] localmake "hand shuffle 52 :deckarray setempty "pile initstacks foreach :suits [settop ? "] redisplay catch "endgame [forever [catch "bell [parsecmd]]] end ;; Initialization to instruct print [] print [Here are the commands you can type:] type "| | type (sentence standout "+ standout "=) type "| | print [Deal three cards onto pile] instruct1 "P [Play top card from pile] instruct1 "R [Redisplay the board] instruct1 "? [Retype these instructions] instruct1 "card [Play that card] instruct1 "M [Move same card again] instruct1 "W [Play up as much as possible (Win)] instruct1 "G [Give up (start a new game)] instruct1 "X [Exit to Logo] print [A card consists of a rank:] type "| | print (sentence standout [A 2 3 4 5 6 7 8 9 10 J Q K] "or standout "T [for 10]) print [followed by a suit:] type "| | print standout [H S D C] print (sentence [or followed by] standout ". [to play all possible suits up]) print [] print [If you make a mistake, hit delete or backspace.] print [] print [To move an entire stack,] type "| | print [hit the shifted stack number:] type "| | print (sentence standout [! @ # $ % ^ &] [for stacks]) type "| | print [1 2 3 4 5 6 7] print [] end to instruct1 :key :meaning type "| | type standout :key repeat 5-count :key [type "| |] print :meaning end to shuffle :len :array if :len=0 [output arraytolist :array] localmake "choice random :len localmake "temp item :choice :array setitem :choice :array (item :len-1 :array) setitem :len-1 :array :temp output shuffle :len-1 :array end to initstacks for [num 1 7] [inithidden :num turnup :num] end to inithidden :num localmake "name hidden :num setempty :name repeat :num [push :name deal] end ;; Reading and interpreting user commands to parsecmd if emptyp :digit [setcursor [1 22] type "| | setcursor [1 22]] local "char make "char uppercase readchar if equalp :char "T [parsedigit 1 parsezero stop] if memberp :char [1 2 3 4 5 6 7 8 9 A J Q K] [parsedigit :char stop] if equalp :char "0 [parsezero stop] if memberp :char :suits [play.by.name :char stop] if equalp :char ". [allup stop] if equalp :char "W [wingame stop] if equalp :char "M [again stop] if memberp :char [+ =] [hand3 stop] if equalp :char "R [redisplay stop] if equalp :char "? [helper stop] if equalp :char "P [playpile stop] if and equalp :char "|(| not emptyp :digit [cheat stop] if and equalp :char "|)| not emptyp :digit [newstack stop] if memberp :char [! @ # $ % ^ & * ( )] ~ [playstack :char [! @ # $ % ^ & * ( )] stop] if memberp :char (list "| | char 8 char 127) [rubout stop] if equalp :char "G [throw "endgame] if equalp :char "X [throw "exit] bell end to parsedigit :char if not emptyp :digit [bell] make "digit :char type :digit end to parsezero if not equalp :digit 1 [bell] make "digit 10 type 0 end to rubout setcursor [1 22] type "| | setcursor [1 22] setempty "digit end to bell if not :upping [type char 7] setempty "digit throw "bell end ;; Deal three cards from the hand to hand3 if not emptyp :digit [bell] if and emptyp :hand emptyp :pile [bell] push "pile deal repeat 2 [if not emptyp :hand [push "pile deal]] dispile dishand end to deal if emptyp :hand [make "hand reverse :pile setempty "pile] if emptyp :hand [output []] output pop "hand end ;; Select card to play by position (pile or stack) or by name to playpile if emptyp :pile [bell] if not emptyp :digit [bell] make "card first :pile make "where [rempile] carddis :card playcard end to playstack :which :list if not emptyp :digit [bell] foreach :list [if equalp :which ? [playstack1 # stop]] end to playstack1 :num if greaterp :num :numstacks [bell] if stackemptyp shown :num [bell] make "card last thing shown :num make "where sentence "remshown :num carddis :card playcard end to play.by.name :char if emptyp :digit [bell] if equalp :digit 1 [make "digit "a] type :char wait 0 make "card word :digit :char setempty "digit findcard if not emptyp :where [playcard] end to findcard if findpile [stop] make "where findshown if emptyp :where [bell] end to findpile if emptyp :pile [output "false] if equalp :card first :pile [make "where [rempile] output "true] output "false end to findshown for [num 1 :numstacks] ~ [if memberp :card thing shown :num [output sentence "remshown :num]] output [] end ;; Figure out all possible places to play card, then pick one to playcard setempty "onto if not coveredp [checktop] if and not :upping ~ or (emptyp :onto) (not upsafep rank :card) ~ [checkonto] if emptyp :onto [bell] run :where run first :onto end to coveredp if equalp :where [rempile] [output "false] output not equalp :card first thing shown last :where end to upsafep :rank if memberp :rank [A 2] [output "true] output equalp 0 thing word "num ((ranknum :rank)-2) end to checktop if (ranknum rank :card) = 1 + (ranknum top suit :card) ~ [push "onto (list "playtop word "" suit :card)] end to checkonto for [num :numstacks 1] ~ [ifelse stackemptyp shown :num [checkempty :num] [checkfull :num thing shown :num]] end to checkempty :num if equalp rank :card "k [push "onto (list "playonto :num)] end to checkfull :num :stack if equalp (redp :card) (redp first :stack) [stop] if ((ranknum rank first :stack) = 1 + (ranknum rank :card)) ~ [push "onto (list "playonto :num)] end ;; Play card, step 1: remove from old position to rempile make "cards (list (pop "pile)) dispile end to remshown :num setempty "cards remshown1 :num (count thing shown :num) if stackemptyp shown :num [turnup :num disstack :num] end to remshown1 :num :length do.until [push "cards (pop shown :num)] ~ [equalp :card first :cards] for [i 1 [count :cards]] ~ [setcursor list (5*:num - 4) (5+:length-:i) type "| |] end to turnup :num setempty shown :num if stackemptyp hidden :num [stop] push (shown :num) (pop hidden :num) end ;; Play card, step 2: put in new position to playtop :suit localmake "var word "num ranknum rank :card settop :suit rank :card distop :suit make :var (thing :var)-1 if (thing :var)=0 [make "ranks butfirst :ranks] end to playonto :num localmake "row 4+count thing shown :num localmake "col 5*:num-4 for [i 1 [count :cards]] ~ [localmake "card pop "cards push (shown :num) :card setcursor list :col :row+:i carddis :card] end ;; Update screen display to redisplay cleartext for [num 1 :numstacks] [disstack :num] foreach :suits "distop dispile dishand setcursor [1 22] setempty "digit end to disstack :num setcursor list (-3 + 5 * :num) 4 type ifelse stackemptyp hidden :num ["| |] ["-] if stackemptyp shown :num [setcursor list (-4 + 5 * :num) 5 type "| | stop] localmake "stack (thing shown :num) localmake "col 5*:num-4 for [i [count :stack] 1] ~ [setcursor list :col :i+4 carddis pop "stack] end to distop :suit if emptyp top :suit [stop] if equalp :suit "H [distop1 4 stop] if equalp :suit "S [distop1 11 stop] if equalp :suit "D [distop1 18 stop] distop1 25 end to distop1 :col setcursor list :col 2 carddis word (top :suit) :suit end to dispile setcursor [32 23] ifelse emptyp :pile [type "| |] [carddis first :pile] end to dishand setcursor [27 23] type count :hand type "| | end to carddis :card ifelse memberp suit :card :reds [redtype :card] [blacktype :card] type "| | end to redtype :word type :word end to blacktype :word type standout :word end ;; Miscellaneous user commands to again if not emptyp :digit [bell] if emptyp :onto [bell] make "where list "remshown last pop "onto if emptyp :onto [bell] carddis :card run :where run first :onto end to helper cleartext instruct print standout [type any key to continue] ignore rc redisplay end to allup if emptyp :digit [bell] if equalp :digit 1 [make "digit "a] localmake "upping "true type ". wait 0 foreach map [word :digit ?] [H S D C] ~ [catch "bell [make "card ? findcard if not emptyp :where [playcard]]] setempty "digit end to wingame type "W localmake "cursor cursor foreach :ranks [if not upsafep ? [stop] make "digit ? ~ allup ~ setempty "digit ~ setcursor :cursor] if equalp (map "top [H S D C]) [K K K K] ~ [ct print [you win!] wait 120 throw "endgame] end to newstack localmake "num :numstacks+1 setcursor [1 22] type "| | if not equalp :digit 9 [bell] setempty hidden :num setempty shown :num make "numstacks :num setempty "digit end to cheat setcursor [1 22] type "| | if not equalp :digit 8 [bell] if and emptyp :hand emptyp :pile [bell] push "pile deal dispile dishand setempty "digit end ;; Data abstraction (ranks) to rank :card output butlast :card end to ranknum :rank if emptyp :rank [output 0] if numberp :rank [output :rank] if :rank = "A [output 1] if :rank = "J [output 11] if :rank = "Q [output 12] if :rank = "K [output 13] end ;; Data abstraction (suits) to suit :card output last :card end to redp :card output memberp (suit :card) :reds end ;; Data abstraction (tops) to top :suit output thing word "top :suit end to settop :suit :value make (word "top :suit) :value end ;; Data abstraction (card stacks) to shown :num output word "shown :num end to hidden :num output word "hidden :num end ;; Data abstraction (pushdown stacks) to stackemptyp :name output emptyp thing :name end to setempty :stack make :stack [] end ucblogo-5.5/csls/student0100644000161300001330000010676506141776764013346 0ustar bhdoeto student :prob say [The problem to be solved is] :prob make "prob map.se [depunct ?] :prob localmake "orgprob :prob student1 :prob ~ [[[the perimeter of ! rectangle] [twice the sum of the length and width of the rectangle]] [[two numbers] [one of the numbers and the other number]] [[two numbers] [one number and the other number]]] end to student1 :prob :idioms local [simsen shelf aunits units wanted ans var lasteqn ref eqt1 beg end idiom reply] make "prob idioms :prob if match [^ two numbers #] :prob ~ [make "idiom find [match (sentence "^beg first ? "#end) :orgprob] :idioms ~ tryidiom stop] while [match [^beg the the #end] :prob] [make "prob (sentence :beg "the :end)] say [With mandatory substitutions the problem is] :prob ifelse match [# @:in [[as old as] [age] [years old]] #] :prob ~ [ageprob] [make "simsen bracket :prob] lsay [The simple sentences are] :simsen foreach [aunits wanted ans var lasteqn ref units] [make ? []] make "shelf filter [not emptyp ?] map.se [senform ?] :simsen lsay [The equations to be solved are] :shelf make "units remdup :units if trysolve :shelf :wanted :units :aunits [print [The problem is solved.] stop] make "eqt1 remdup geteqns :var if not emptyp :eqt1 [lsay [Using the following known relationships] :eqt1] student2 :eqt1 end to student2 :eqt1 make "var remdup sentence (map.se [varterms ?] :eqt1) :var make "eqt1 sentence :eqt1 vartest :var if not emptyp :eqt1 ~ [if trysolve (sentence :shelf :eqt1) :wanted :units :aunits [print [The problem is solved.] stop]] make "idiom find [match (sentence "^beg first ? "#end) :orgprob] :idioms if not emptyp :idiom [tryidiom stop] lsay [Do you know any more relationships among these variables?] :var make "reply readlist if equalp :reply [yes] [print [Tell me.] make "reply readlist] if equalp :reply [no] [print [] print [I can't solve this problem.] stop] make "reply map.se [depunct ?] :reply if dlm last :reply [make "reply butlast :reply] if not match [^beg is #end] :reply [print [I don't understand that.] stop] make "shelf sentence :shelf :eqt1 student2 (list (list "equal opform :beg opform :end)) end ;; Mandatory substitutions to depunct :word if emptyp :word [output []] if equalp first :word "$ [output sentence "$ depunct butfirst :word] if equalp last :word "% [output sentence depunct butlast :word "percent] if memberp last :word [. ? |;| ,] [output sentence depunct butlast :word last :word] if emptyp butfirst :word [output :word] if equalp last2 :word "'s [output sentence depunct butlast butlast :word "s] output :word end to last2 :word output word (last butlast :word) (last :word) end to idioms :sent local "number output changes :sent ~ [[[the sum of] ["sum]] [[square of] ["square]] [[of] ["numof]] [[how old] ["what]] [[is equal to] ["is]] [[years younger than] [[less than]]] [[years older than] ["plus]] [[percent less than] ["perless]] [[less than] ["lessthan]] [[these] ["the]] [[more than] ["plus]] [[first two numbers] [[the first number and the second number]]] [[three numbers] [[the first number and the second number and the third number]]] [[one half] [0.5]] [[twice] [[2 times]]] [[$ !number] [sentence :number "dollars]] [[consecutive to] [[1 plus]]] [[larger than] ["plus]] [[per cent] ["percent]] [[how many] ["howm]] [[is multiplied by] ["ismulby]] [[is divided by] ["isdivby]] [[multiplied by] ["times]] [[divided by] ["divby]]] end to changes :sent :list localmake "keywords map.se [findkey first ?] :list output changes1 :sent :list :keywords end to findkey :pattern if equalp first :pattern "!:in [output first butfirst :pattern] if equalp first :pattern "?:in [output sentence (item 2 :pattern) (item 3 :pattern)] output first :pattern end to changes1 :sent :list :keywords if emptyp :sent [output []] if memberp first :sent :keywords [output changes2 :sent :list :keywords] output fput first :sent changes1 butfirst :sent :list :keywords end to changes2 :sent :list :keywords changes3 :list :list output fput first :sent changes1 butfirst :sent :list :keywords end to changes3 :biglist :nowlist if emptyp :nowlist [stop] if changeone first :nowlist [changes3 :biglist :biglist stop] changes3 :biglist butfirst :nowlist end to changeone :change local "end if not match (sentence first :change [#end]) :sent [output "false] make "sent run (sentence "sentence last :change ":end) output "true end ;; Division into simple sentences to bracket :prob output bkt1 finddelim :prob end to finddelim :sent output finddelim1 :sent [] [] end to finddelim1 :in :out :simples if emptyp :in ~ [ifelse emptyp :out [output :simples] [output lput (sentence :out ".) :simples]] if dlm first :in ~ [output finddelim1 (nocap butfirst :in) [] (lput (sentence :out first :in) :simples)] output finddelim1 (butfirst :in) (sentence :out first :in) :simples end to nocap :words if emptyp :words [output []] if personp first :words [output :words] output sentence (lowercase first :words) butfirst :words end to bkt1 :problist local [first word rest] if emptyp :problist [output []] if not memberp ", first :problist ~ [output fput first :problist bkt1 butfirst :problist] if match [if ^first , !word:qword #rest] first :problist ~ [output bkt1 fput (sentence :first ".) fput (sentence :word :rest) butfirst :problist] if match [^first , and #rest] first :problist ~ [output fput (sentence :first ".) (bkt1 fput :rest butfirst :problist)] output fput first :problist bkt1 butfirst :problist end ;; Age problems to ageprob local [beg end sym who num subj ages] while [match [^beg as old as #end] :prob] [make "prob sentence :beg :end] while [match [^beg years old #end] :prob] [make "prob sentence :beg :end] while [match [^beg will be when #end] :prob] ~ [make "sym gensym make "prob (sentence :beg "in :sym [years . in] :sym "years :end)] while [match [^beg was when #end] :prob] ~ [make "sym gensym make "prob (sentence :beg :sym [years ago .] :sym [years ago] :end)] while [match [^beg !who:personp will be in !num years #end] :prob] ~ [make "prob (sentence :beg :who [s age in] :num "years #end)] while [match [^beg was #end] :prob] [make "prob (sentence :beg "is :end)] while [match [^beg will be #end] :prob] [make "prob (sentence :beg "is :end)] while [match [^beg !who:personp is now #end] :prob] ~ [make "prob (sentence :beg :who [s age now] :end)] while [match [^beg !num years from now #end] :prob] ~ [make "prob (sentence :beg "in :num "years :end)] make "prob ageify :prob ifelse match [^ !who:personp ^end s age #] :prob ~ [make "subj sentence :who :end] [make "subj "someone] make "prob agepron :prob make "end :prob make "ages [] while [match [^ !who:personp ^beg age #end] :end] ~ [push "ages (sentence "and :who :beg "age)] make "ages butfirst reduce "sentence remdup :ages while [match [^beg their ages #end] :prob] [make "prob (sentence :beg :ages :end)] make "simsen map [agesen ?] bracket :prob end to ageify :sent if emptyp :sent [output []] if not personp first :sent [output fput first :sent ageify butfirst :sent] catch "error [if equalp first butfirst :sent "s [output fput first :sent ageify butfirst :sent]] output (sentence first :sent [s age] ageify butfirst :sent) end to agepron :sent if emptyp :sent [output []] if not pronoun first :sent [output fput first :sent agepron butfirst :sent] if posspro first :sent [output (sentence :subj "s agepron butfirst :sent)] output (sentence :subj [s age] agepron butfirst :sent) end to agesen :sent local [when rest num] make "when [] if match [in !num years #rest] :sent ~ [make "when sentence "pluss :num make "sent :rest] if match [!num years ago #rest] :sent ~ [make "when sentence "minuss :num make "sent :rest] output agewhen :sent end to agewhen :sent if emptyp :sent [output []] if not equalp first :sent "age [output fput first :sent agewhen butfirst :sent] if match [in !num years #rest] butfirst :sent ~ [output (sentence [age pluss] :num agewhen :rest)] if match [!num years ago #rest] butfirst :sent ~ [output (sentence [age minuss] :num agewhen :rest)] if equalp "now first butfirst :sent ~ [output sentence "age agewhen butfirst butfirst :sent] output (sentence "age :when agewhen butfirst :sent) end ;; Translation from sentences into equations to senform :sent make "lasteqn senform1 :sent output :lasteqn end to senform1 :sent local [one two verb1 verb2 stuff1 stuff2 factor] if emptyp :sent [output []] if match [^ what are ^one and ^two !:dlm] :sent ~ [output fput (qset :one) (senform (sentence [what are] :two "?))] if match [^ what !:in [is are] #one !:dlm] :sent ~ [output (list qset :one)] if match [^ howm !one is #two !:dlm] :sent ~ [push "aunits (list :one) output (list qset :two)] if match [^ howm ^one do ^two have !:dlm] :sent ~ [output (list qset (sentence [the number of] :one :two "have))] if match [^ howm ^one does ^two have !:dlm] :sent ~ [output (list qset (sentence [the number of] :one :two "has))] if match [^ find ^one and #two] :sent ~ [output fput (qset :one) (senform sentence "find :two)] if match [^ find #one !:dlm] :sent [output (list qset :one)] make "sent filter [not article ?] :sent if match [^one ismulby #two] :sent ~ [push "ref (list "product opform :one opform :two) output []] if match [^one isdivby #two] :sent ~ [push "ref (list "quotient opform :one opform :two) output []] if match [^one is increased by #two] :sent ~ [push "ref (list "sum opform :one opform :two) output []] if match [^one is #two] :sent ~ [output (list (list "equal opform :one opform :two))] if match [^one !verb1:verb ^factor as many ^stuff1 as ^two !verb2:verb ^stuff2 !:dlm] ~ :sent ~ [if emptyp :stuff2 [make "stuff2 :stuff1] output (list (list "equal ~ opform (sentence [the number of] :stuff1 :one :verb1) ~ opform (sentence :factor [the number of] :stuff2 :two :verb2)))] if match [^one !verb1:verb !factor:numberp #stuff1 !:dlm] :sent ~ [output (list (list "equal ~ opform (sentence [the number of] :stuff1 :one :verb1) ~ opform (list :factor)))] say [This sentence form is not recognized:] :sent throw "error end to qset :sent localmake "opform opform filter [not article ?] :sent if not operatorp first :opform ~ [queue "wanted :opform queue "ans list :opform oprem :sent output []] localmake "gensym gensym queue "wanted :gensym queue "ans list :gensym oprem :sent output (list "equal :gensym opform (filter [not article ?] :sent)) end to oprem :sent output map [ifelse equalp ? "numof ["of] [?]] :sent end to opform :expr local [left right op] if match [^left !op:op2 #right] :expr [output optest :op :left :right] if match [^left !op:op1 #right] :expr [output optest :op :left :right] if match [^left !op:op0 #right] :expr [output optest :op :left :right] if match [#left !:dlm] :expr [make "expr :left] output nmtest filter [not article ?] :expr end to optest :op :left :right output run (list (word "tst. :op) :left :right) end to tst.numof :left :right if numberp last :left [output (list "product opform :left opform :right)] output opform (sentence :left "of :right) end to tst.divby :left :right output (list "quotient opform :left opform :right) end to tst.tothepower :left :right output (list "expt opform :left opform :right) end to expt :num :pow if :pow < 1 [output 1] output :num * expt :num :pow - 1 end to tst.per :left :right output (list "quotient ~ opform :left ~ opform (ifelse numberp first :right [:right] [fput 1 :right])) end to tst.lessthan :left :right output opdiff opform :right opform :left end to opdiff :left :right output (list "sum :left (list "minus :right)) end to tst.minus :left :right if emptyp :left [output list "minus opform :right] output opdiff opform :left opform :right end to tst.minuss :left :right output tst.minus :left :right end to tst.sum :left :right local [one two three] if match [^one and ^two and #three] :right ~ [output (list "sum opform :one opform (sentence "sum :two "and :three))] if match [^one and #two] :right ~ [output (list "sum opform :one opform :two)] say [sum used wrong:] :right throw "error end to tst.squared :left :right output list "square opform :left end to tst.difference :left :right local [one two] if match [between ^one and #two] :right [output opdiff opform :one opform :two] say [Incorrect use of difference:] :right throw "error end to tst.plus :left :right output (list "sum opform :left opform :right) end to tst.pluss :left :right output tst.plus :left :right end to square :x output :x * :x end to tst.square :left :right output list "square opform :right end to tst.percent :left :right if not numberp last :left ~ [say [Incorrect use of percent:] :left throw "error] output opform (sentence butlast :left ((last :left) / 100) :right) end to tst.perless :left :right if not numberp last :left ~ [say [Incorrect use of percent:] :left throw "error] output (list "product ~ (opform sentence butlast :left ((100 - (last :left)) / 100)) ~ opform :right) end to tst.times :left :right if emptyp :left [say [Incorrect use of times:] :right throw "error] output (list "product opform :left opform :right) end to nmtest :expr if match [& !:numberp #] :expr [say [argument error:] :expr throw "error] if and (equalp first :expr 1) (1 < count :expr) ~ [make "expr (sentence 1 plural (first butfirst :expr) (butfirst butfirst :expr))] if and (numberp first :expr) (1 < count :expr) ~ [push "units (list first butfirst :expr) ~ output (list "product (first :expr) (opform butfirst :expr))] if numberp first :expr [output first :expr] if memberp "this :expr [output this :expr] if not memberp :expr :var [push "var :expr] output :expr end to this :expr if not emptyp :ref [output pop "ref] if not emptyp :lasteqn [output first butfirst last :lasteqn] if equalp first :expr "this [make "expr butfirst :expr] push "var :expr output :expr end ;; Solving the equations to trysolve :shelf :wanted :units :aunits local "solution make "solution solve :wanted :shelf (ifelse emptyp :aunits [:units] [:aunits]) output pranswers :ans :solution end to solve :wanted :eqt :terms output solve.reduce solver :wanted :terms [] [] "insufficient end to solve.reduce :soln if emptyp :soln [output []] if wordp :soln [output :soln] if emptyp butfirst :soln [output :soln] local "part make "part solve.reduce butfirst :soln output fput (list (first first :soln) (subord last first :soln :part)) :part end to solver :wanted :terms :alis :failed :err local [one result restwant] if emptyp :wanted [output :err] make "one solve1 (first :wanted) ~ (sentence butfirst :wanted :failed :terms) ~ :alis :eqt [] "insufficient if wordp :one ~ [output solver (butfirst :wanted) :terms :alis (fput first :wanted :failed) :one] make "restwant (sentence :failed butfirst :wanted) if emptyp :restwant [output :one] make "result solver :restwant :terms :one [] "insufficient if listp :result [output :result] output solver (butfirst :wanted) :terms :alis (fput first :wanted :failed) :one end to solve1 :x :terms :alis :eqns :failed :err local [thiseq vars extras xterms others result] if emptyp :eqns [output :err] make "thiseq subord (first :eqns) :alis make "vars varterms :thiseq if not memberp :x :vars ~ [output solve1 :x :terms :alis (butfirst :eqns) (fput first :eqns :failed) :err] make "xterms fput :x :terms make "extras setminus :vars :xterms make "eqt remove (first :eqns) :eqt if not emptyp :extras ~ [make "others solver :extras :xterms :alis [] "insufficient ifelse wordp :others [make "eqt sentence :failed :eqns output solve1 :x :terms :alis (butfirst :eqns) (fput first :eqns :failed) :others] [make "alis :others make "thiseq subord (first :eqns) :alis]] make "result solveq :x :thiseq if listp :result [output lput :result :alis] make "eqt sentence :failed :eqns output solve1 :x :terms :alis (butfirst :eqns) (fput first :eqns :failed) :result end to solveq :var :eqn local [left right] make "left first butfirst :eqn ifelse occvar :var :left ~ [make "right last :eqn] [make "right :left make "left last :eqn] output solveq1 :left :right "true end to solveq1 :left :right :bothtest if :bothtest [if occvar :var :right [output solveqboth :left :right]] if equalp :left :var [output list :var :right] if wordp :left [output "unsolvable] local "oper make "oper first :left if memberp :oper [sum product minus quotient] [output run (list word "solveq. :oper)] output "unsolvable end to solveqboth :left :right if not equalp first :right "sum [output solveq1 (subterm :left :right) 0 "false] output solveq.rplus :left butfirst :right [] end to solveq.rplus :left :right :newright if emptyp :right [output solveq1 :left (simone "sum :newright) "false] if occvar :var first :right ~ [output solveq.rplus (subterm :left first :right) butfirst :right :newright] output solveq.rplus :left butfirst :right (fput first :right :newright) end to solveq.sum if emptyp butfirst butfirst :left [output solveq1 first butfirst :left :right "true] output solveq.sum1 butfirst :left :right [] end to solveq.sum1 :left :right :newleft if emptyp :left [output solveq.sum2] if occvar :var first :left ~ [output solveq.sum1 butfirst :left :right fput first :left :newleft] output solveq.sum1 butfirst :left (subterm :right first :left) :newleft end to solveq.sum2 if emptyp butfirst :newleft [output solveq1 first :newleft :right "true] localmake "factor factor :newleft :var if equalp first :factor "unknown [output "unsolvable] if equalp last :factor 0 [output "unsolvable] output solveq1 first :factor (divterm :right last :factor) "true end to solveq.minus output solveq1 (first butfirst :left) (minusin :right) "false end to solveq.product output solveq.product1 :left :right end to solveq.product1 :left :right if emptyp butfirst butfirst :left [output solveq1 (first butfirst :left) :right "true] if not occvar :var first butfirst :left ~ [output solveq.product1 (fput "product butfirst butfirst :left) (divterm :right first butfirst :left)] localmake "rest simone "product butfirst butfirst :left if occvar :var :rest [output "unsolvable] output solveq1 (first butfirst :left) (divterm :right :rest) "false end to solveq.quotient if occvar :var first butfirst :left ~ [output solveq1 (first butfirst :left) (simtimes list :right last :left) "true] output solveq1 (simtimes list :right last :left) (first butfirst :left) "true end to denom :fract :addends make "addends simplus :addends localmake "den last :fract if not equalp first :addends "quotient ~ [output simdiv list (simone "sum (remop "sum list (distribtimes (list :addends) :den) first butfirst :fract)) :den] if equalp :den last :addends ~ [output simdiv (simplus list (first butfirst :fract) (first butfirst :addends)) :den] localmake "lowterms simdiv list :den last :addends output simdiv list (simplus (simtimes list first butfirst :fract last :lowterms) (simtimes list first butfirst :addends first butfirst :lowterms)) ~ (simtimes list first butfirst :lowterms last :addends) end to distribtimes :trms :multiplier output simplus map [simtimes (list ? :multiplier)] :trms end to distribx :expr local [oper args] if emptyp :expr [output :expr] make "oper first :expr if not operatorp :oper [output :expr] make "args map [distribx ?] butfirst :expr if reduce "and map [numberp ?] :args [output run (sentence [(] :oper :args [)])] if equalp :oper "sum [output simplus :args] if equalp :oper "minus [output minusin first :args] if equalp :oper "product [output simtimes :args] if equalp :oper "quotient [output simdiv :args] output fput :oper :args end to divterm :dividend :divisor if equalp :dividend 0 [output 0] output simdiv list :dividend :divisor end to factor :exprs :var local "trms make "trms map [factor1 :var ?] :exprs if memberp "unknown :trms [output fput "unknown :exprs] output list :var simplus :trms end to factor1 :var :expr localmake "negvar minusin :var if equalp :var :expr [output 1] if equalp :negvar :expr [output -1] if emptyp :expr [output "unknown] if equalp first :expr "product [output factor2 butfirst :expr] if not equalp first :expr "quotient [output "unknown] localmake "dividend first butfirst :expr if equalp :var :dividend [output (list "quotient 1 last :expr)] if not equalp first :dividend "product [output "unknown] localmake "result factor2 butfirst :dividend if equalp :result "unknown [output "unknown] output (list "quotient :result last :expr) end to factor2 :trms if memberp :var :trms [output simone "product (remove :var :trms)] if memberp :negvar :trms [output minusin simone "product (remove :negvar :trms)] output "unknown end to maybeadd :num :rest if equalp :num 0 [output :rest] output fput :num :rest end to maybemul :num :rest if equalp :num 1 [output :rest] output fput :num :rest end to minusin :expr if emptyp :expr [output -1] if equalp first :expr "sum [output fput "sum map [minusin ?] butfirst :expr] if equalp first :expr "minus [output last :expr] if memberp first :expr [product quotient] ~ [output fput first :expr (fput (minusin first butfirst :expr) butfirst butfirst :expr)] if numberp :expr [output minus :expr] output list "minus :expr end to occvar :var :expr if emptyp :expr [output "false] if wordp :expr [output equalp :var :expr] if operatorp first :expr [output not emptyp find [occvar :var ?] butfirst :expr] output equalp :var :expr end to remfactor :num :den foreach butfirst :num [remfactor1 ?] output (list "quotient (simone "product butfirst :num) (simone "product butfirst :den)) end to remfactor1 :expr local "neg if memberp :expr :den ~ [make "num remove :expr :num make "den remove :expr :den stop] make "neg minusin :expr if not memberp :neg :den [stop] make "num remove :expr :num make "den minusin remove :neg :den end to remop :oper :exprs output map.se [ifelse equalp first ? :oper [butfirst ?] [(list ?)]] :exprs end to simdiv :list local [num den numop denop] make "num first :list make "den last :list if equalp :num :den [output 1] if numberp :den [output simtimes (list (quotient 1 :den) :num)] make "numop first :num make "denop first :den if equalp :numop "quotient ~ [output simdiv list (first butfirst :num) (simtimes list last :num :den)] if equalp :denop "quotient ~ [output simdiv list (simtimes list :num last :den) (first butfirst :den)] if and equalp :numop "product equalp :denop "product [output remfactor :num :den] if and equalp :numop "product memberp :den :num [output remove :den :num] output fput "quotient :list end to simone :oper :trms if emptyp :trms [output ifelse equalp :oper "product [1] [0]] if emptyp butfirst :trms [output first :trms] output fput :oper :trms end to simplus :exprs make "exprs remop "sum :exprs localmake "factor [unknown] catch "simplus ~ [foreach :terms ~ [make "factor (factor :exprs ?) ~ if not equalp first :factor "unknown [throw "simplus]]] if not equalp first :factor "unknown [output fput "product remop "product :factor] localmake "nums 0 localmake "nonnums [] localmake "quick [] catch "simplus [simplus1 :exprs] if not emptyp :quick [output :quick] if not equalp :nums 0 [push "nonnums :nums] output simone "sum :nonnums end to simplus1 :exprs if emptyp :exprs [stop] simplus2 first :exprs simplus1 butfirst :exprs end to simplus2 :pos local "neg make "neg minusin :pos if numberp :pos [make "nums sum :pos :nums stop] if memberp :neg butfirst :exprs [make "exprs remove :neg :exprs stop] if equalp first :pos "quotient ~ [make "quick (denom :pos (maybeadd :nums sentence :nonnums butfirst :exprs)) ~ throw "simplus] push "nonnums :pos end to simtimes :exprs local [nums nonnums quick] make "nums 1 make "nonnums [] make "quick [] catch "simtimes [foreach remop "product :exprs [simtimes1 ?]] if not emptyp :quick [output :quick] if equalp :nums 0 [output 0] if not equalp :nums 1 [push "nonnums :nums] output simone "product :nonnums end to simtimes1 :expr if equalp :expr 0 [make "nums 0 throw "simtimes] if numberp :expr [make "nums product :expr :nums stop] if equalp first :expr "sum ~ [make "quick distribtimes (butfirst :expr) (simone "product maybemul :nums sentence :nonnums ?rest) throw "simtimes] if equalp first :expr "quotient ~ [make "quick simdiv (list (simtimes (list (first butfirst :expr) (simone "product maybemul :nums sentence :nonnums ?rest))) (last :expr)) throw "simtimes] push "nonnums :expr end to subord :expr :alist output distribx subord1 :expr :alist end to subord1 :expr :alist if emptyp :alist [output :expr] output subord (substop (last first :alist) (first first :alist) :expr) ~ (butfirst :alist) end to substop :val :var :expr if emptyp :expr [output []] if equalp :expr :var [output :val] if not operatorp first :expr [output :expr] output fput first :expr map [substop :val :var ?] butfirst :expr end to subterm :minuend :subtrahend if equalp :minuend 0 [output minusin :subtrahend] if equalp :minuend :subtrahend [output 0] output simplus (list :minuend minusin :subtrahend) end to varterms :expr if emptyp :expr [output []] if numberp :expr [output []] if wordp :expr [output (list :expr)] if operatorp first :expr [output map.se [varterms ?] butfirst :expr] output (list :expr) end ;; Printing the solutions to pranswers :ans :solution print [] if equalp :solution "unsolvable ~ [print [Unable to solve this set of equations.] output "false] if equalp :solution "insufficient ~ [print [The equations were insufficient to find a solution.] output "false] localmake "gotall "true foreach :ans [if prans ? :solution [make "gotall "false]] if not :gotall [print [] print [Unable to solve this set of equations.]] output :gotall end to prans :ans :solution localmake "result find [equalp first ? first :ans] :solution if emptyp :result [output "true] print (sentence cap last :ans "is unitstring last :result) print [] output "false end to unitstring :expr if numberp :expr [output roundoff :expr] if equalp first :expr "product ~ [output sentence (unitstring first butfirst :expr) (reduce "sentence butfirst butfirst :expr)] if (and (listp :expr) (not numberp first :expr) (not operatorp first :expr)) ~ [output (sentence 1 (singular first :expr) (butfirst :expr))] output :expr end to roundoff :num if (abs (:num - round :num)) < 0.0001 [output round :num] output :num end to abs :num output ifelse (:num < 0) [-:num] [:num] end ;; Using known relationships to geteqns :vars output map.se [gprop varkey ? "eqns] :vars end to varkey :var local "word if match [number of !word #] :var [output :word] output first :var end ;; Assuming equality of similar variables to vartest :vars if emptyp :vars [output []] local [var beg end] make "var first :vars output (sentence (ifelse match [^beg !:pronoun #end] :var [vartest1 :var (sentence :beg "& :end) butfirst :vars] [[]]) (vartest1 :var (sentence "# :var "#) butfirst :vars) (vartest butfirst :vars)) end to vartest1 :target :pat :vars output map [varequal :target ?] filter [match :pat ?] :vars end to varequal :target :var print [] print [Assuming that] print (sentence (list :target) [is equal to] (list :var)) output (list "equal :target :var) end ;; Optional substitutions to tryidiom make "prob (sentence :beg last :idiom :end) while [match (sentence "^beg first :idiom "#end) :prob] ~ [make "prob (sentence :beg last :idiom :end)] say [The problem with an idiomatic substitution is] :prob student1 :prob (remove :idiom :idioms) end ;; Utility procedures to qword :word output memberp :word [find what howm how] end to dlm :word output memberp :word [. ? |;|] end to article :word output memberp :word [a an the] end to verb :word output memberp :word [have has get gets weigh weighs] end to personp :word output memberp :word [Mary Ann Bill Tom Sally Frank father uncle] end to pronoun :word output memberp :word [he she it him her they them his her its] end to posspro :word output memberp :word [his her its] end to op0 :word output memberp :word [pluss minuss squared tothepower per sum difference numof] end to op1 :word output memberp :word [times divby square] end to op2 :word output memberp :word [plus minus lessthan percent perless] end to operatorp :word output memberp :word [sum minus product quotient expt square equal] end to plural :word localmake "plural gprop :word "plural if not emptyp :plural [output :plural] if not emptyp gprop :word "sing [output :word] if equalp last :word "s [output :word] output word :word "s end to singular :word localmake "sing gprop :word "sing if not emptyp :sing [output :sing] if not emptyp gprop :word "plural [output :word] if equalp last :word "s [output butlast :word] output :word end to setminus :big :little output filter [not memberp ? :little] :big end to say :herald :text print [] print :herald print [] print :text print [] end to lsay :herald :text print [] print :herald print [] foreach :text [print cap ? print []] end to cap :sent if emptyp :sent [output []] output sentence (word uppercase first first :sent butfirst first :sent) ~ butfirst :sent end ;; The pattern matcher to match :pat :sen if prematch :pat :sen [output rmatch :pat :sen] output "false end to prematch :pat :sen if emptyp :pat [output "true] if listp first :pat [output prematch butfirst :pat :sen] if memberp first first :pat [! @ # ^ & ?] [output prematch butfirst :pat :sen] if emptyp :sen [output "false] localmake "rest member first :pat :sen if not emptyp :rest [output prematch butfirst :pat :rest] output "false end to rmatch :pat :sen local [special.var special.pred special.buffer in.list] if or wordp :pat wordp :sen [output "false] if emptyp :pat [output emptyp :sen] if listp first :pat [output special fput "!: :pat :sen] if memberp first first :pat [? # ! & @ ^] [output special :pat :sen] if emptyp :sen [output "false] if equalp first :pat first :sen [output rmatch butfirst :pat butfirst :sen] output "false end to special :pat :sen set.special parse.special butfirst first :pat " output run word "match first first :pat end to parse.special :word :var if emptyp :word [output list :var "always] if equalp first :word ": [output list :var butfirst :word] output parse.special butfirst :word word :var first :word end to set.special :list make "special.var first :list make "special.pred last :list if emptyp :special.var [make "special.var "special.buffer] if memberp :special.pred [in anyof] [set.in] if not emptyp :special.pred [stop] make "special.pred first butfirst :pat make "pat fput first :pat butfirst butfirst :pat end to set.in make "in.list first butfirst :pat make "pat fput first :pat butfirst butfirst :pat end to match! if emptyp :sen [output "false] if not try.pred [output "false] make :special.var first :sen output rmatch butfirst :pat butfirst :sen end to match? make :special.var [] if emptyp :sen [output rmatch butfirst :pat :sen] if not try.pred [output rmatch butfirst :pat :sen] make :special.var first :sen if rmatch butfirst :pat butfirst :sen [output "true] make :special.var [] output rmatch butfirst :pat :sen end to match# make :special.var [] output #test #gather :sen end to #gather :sen if emptyp :sen [output :sen] if not try.pred [output :sen] make :special.var lput first :sen thing :special.var output #gather butfirst :sen end to #test :sen if rmatch butfirst :pat :sen [output "true] if emptyp thing :special.var [output "false] output #test2 fput last thing :special.var :sen end to #test2 :sen make :special.var butlast thing :special.var output #test :sen end to match& output &test match# end to &test :tf if emptyp thing :special.var [output "false] output :tf end to match^ make :special.var [] output ^test :sen end to ^test :sen if rmatch butfirst :pat :sen [output "true] if emptyp :sen [output "false] if not try.pred [output "false] make :special.var lput first :sen thing :special.var output ^test butfirst :sen end to match@ make :special.var :sen output @test [] end to @test :sen if @try.pred [if rmatch butfirst :pat :sen [output "true]] if emptyp thing :special.var [output "false] output @test2 fput last thing :special.var :sen end to @test2 :sen make :special.var butlast thing :special.var output @test :sen end to try.pred if listp :special.pred [output rmatch :special.pred first :sen] output run list :special.pred quoted first :sen end to quoted :thing if listp :thing [output :thing] output word "" :thing end to @try.pred if listp :special.pred [output rmatch :special.pred thing :special.var] output run list :special.pred thing :special.var end to always :x output "true end to in :word output memberp :word :in.list end to anyof :sen output anyof1 :sen :in.list end to anyof1 :sen :pats if emptyp :pats [output "false] if rmatch first :pats :sen [output "true] output anyof1 :sen butfirst :pats end ;; Sample word problems make "ann [Mary is twice as old as Ann was when Mary was as old as Ann is now. If Mary is 24 years old, how old is Ann?] make "guns [The number of soldiers the Russians have is one half of the number of guns they have. They have 7000 guns. How many soldiers do they have?] make "jet [The distance from New York to Los Angeles is 3000 miles. If the average speed of a jet plane is 600 miles per hour, find the time it takes to travel from New York to Los Angeles by jet.] make "nums [A number is multiplied by 6 . This product is increased by 44 . This result is 68 . Find the number.] make "radio [The price of a radio is $69.70. If this price is 15 percent less than the marked price, find the marked price.] make "sally [The sum of Sally's share of some money and Frank's share is $4.50. Sally's share is twice Frank's. Find Frank's and Sally's share.] make "ship [The gross weight of a ship is 20000 tons. If its net weight is 15000 tons, what is the weight of the ships cargo?] make "span [If 1 span is 9 inches, and 1 fathom is 6 feet, how many spans is 1 fathom?] make "sumtwo [The sum of two numbers is 96, and one number is 16 larger than the other number. Find the two numbers.] make "tom [If the number of customers Tom gets is twice the square of 20 per cent of the number of advertisements he runs, and the number of advertisements he runs is 45, what is the number of customers Tom gets?] make "uncle [Bill's father's uncle is twice as old as Bill's father. 2 years from now Bill's father will be 3 times as old as Bill. The sum of their ages is 92 . Find Bill's age.] ;; Initial data base pprop "distance "eqns ~ [[equal [distance] [product [speed] [time]]] [equal [distance] [product [gas consumtion] [number of gallons of gas used]]]] pprop "feet "eqns ~ [[equal [product 1 [feet]] [product 12 [inches]]] [equal [product 1 [yards]] [product 3 [feet]]]] pprop "feet "sing "foot pprop "foot "plural "feet pprop "gallons "eqns ~ [[equal [distance] [product [gas consumtion] [number of gallons of gas used]]]] pprop "gas "eqns ~ [[equal [distance] [product [gas consumtion] [number of gallons of gas used]]]] pprop "inch "plural "inches pprop "inches "eqns [[equal [product 1 [feet]] [product 12 [inches]]]] pprop "people "sing "person pprop "person "plural "people pprop "speed "eqns [[equal [distance] [product [speed] [time]]]] pprop "time "eqns [[equal [distance] [product [speed] [time]]]] pprop "yards "eqns [[equal [product 1 [yards]] [product 3 [feet]]]] ucblogo-5.5/csls/tower0100644000161300001330000000202206135446674012772 0ustar bhdoeprogram tower; {This program solves the 5-disk tower of hanoi problem.} procedure hanoi(number:integer;from,onto,other:char); {Recursive procedure that solves a subproblem of the original problem, moving some number of disks, not necessarily 5. To move n disks, it must get the topmost n-1 out of the way, move the nth to the target stack, then move the n-1 to the target stack.} procedure movedisk(number:integer;from,onto:char); {This procedure moves one single disk. It assumes that the move is legal, i.e., the disk is at the top of its stack and the target stack has no smaller disks already. Procedure hanoi is responsible for making sure that's all true.} begin {movedisk} writeln('Move disk ',number:1,' from ',from,' to ',onto) end; {movedisk} begin {hanoi} if number <> 0 then begin hanoi(number-1,from,other,onto); movedisk(number,from,onto); hanoi(number-1,other,onto,from) end end; {hanoi} begin {main program} hanoi(5,'a','b','c') end. ucblogo-5.5/csls/ttt0100644000161300001330000000703606005724400012435 0ustar bhdoe;; Overall orchestration to ttt local [me you position] draw.board init if equalp :me "x [meplay 5] forever [ if already.wonp :me [print [I win!] stop] if tiedp [print [Tie game!] stop] youplay getmove ;; ask person for move if already.wonp :you [print [You win!] stop] if tiedp [print [Tie game!] stop] meplay pickmove make.triples ;; compute program's move ] end to make.triples output map "substitute.triple [123 456 789 147 258 369 159 357] end to substitute.triple :combination output map [item ? :position] :combination end to already.wonp :player output memberp (word :player :player :player) (make.triples) end to tiedp output not reduce "or map.se "numberp arraytolist :position end to youplay :square draw :you :square setitem :square :position :you end to meplay :square draw :me :square setitem :square :position :me end ;; Initialization to draw.board splitscreen clearscreen hideturtle drawline [-20 -50] 0 120 drawline [20 -50] 0 120 drawline [-60 -10] 90 120 drawline [-60 30] 90 120 end to drawline :pos :head :len penup setpos :pos setheading :head pendown forward :len end to init make "position {1 2 3 4 5 6 7 8 9} print [Do you want to play first (X)] type [or second (O)? Type X or O:] choose print [For each move, type a digit 1-9.] end to choose local "side forever [ make "side readchar pr :side if equalp :side "x [choosex stop] if equalp :side "o [chooseo stop] type [Huh? Type X or O:] ] end to chooseo make "me "x make "you "o end to choosex make "me "o make "you "x end ;; Get opponent's moves to getmove local "square forever [ type [Your move:] make "square readchar print :square if numberp :square ~ [if and (:square > 0) (:square < 10) [if freep :square [output :square]]] print [not a valid move.] ] end to freep :square output numberp item :square :position end ;; Compute program's moves to pickmove :triples local "try make "try find.win :me if not emptyp :try [output :try] make "try find.win :you if not emptyp :try [output :try] make "try find.fork if not emptyp :try [output :try] make "try find.advance if not emptyp :try [output :try] output find [memberp ? :position] [5 1 3 7 9 2 4 6 8] end to find.win :who output filter "numberp find "win.nowp :triples end to win.nowp :triple output equalp (filter [not numberp ?] :triple) (word :who :who) end to find.fork local "singles make "singles singles :me if emptyp :singles [output []] output repeated.number reduce "word :singles end to singles :who output filter [singlep ? :who] :triples end to singlep :triple :who output equalp (filter [not numberp ?] :triple) :who end to repeated.number :squares output find [memberp ? ?rest] filter "numberp :squares end to find.advance output best.move filter "numberp find [singlep ? :me] :triples end to best.move :my.single local "your.singles if emptyp :my.single [output []] make "your.singles singles :you if emptyp :your.singles [output first :my.single] ifelse (count filter [? = first :my.single] reduce "word :your.singles) > 1 [ output first :my.single ] [ output last :my.single ] end ;; Drawing moves on screen to draw :who :square move :square ifelse :who = "x [drawx] [drawo] end to move :square penup setpos thing word "box :square end to drawo pendown arc 360 18 end to drawx setheading 45 pendown repeat 4 [forward 25.5 back 25.5 right 90] end make "box1 [-40 50] make "box2 [0 50] make "box3 [40 50] make "box4 [-40 10] make "box5 [0 10] make "box6 [40 10] make "box7 [-40 -30] make "box8 [0 -30] make "box9 [40 -30] ucblogo-5.5/csls/streams0100644000161300001330000000407110274277362013311 0ustar bhdoe; Implementation of SICP streams (lazy-evaluation lists) in Logo. ; Since we don't have special forms, we put the second argument to STREAM ; in a (quoted) list. ; Since we don't have lexical scope, we use substitution (`) into saved ; expressions. to stream :car :delayed.cdr output fput :car (list "*delayed* :delayed.cdr) end to head :stream output first :stream end to tail :stream if emptyp bf :stream [output []] if not equalp first bf :stream "*delayed* [output bf :stream] localmake "result run last :stream .setbf :stream :result output :result end ; higher order functions for streams ; Remember that if the functional argument uses local variables, it has to ; be backquoted. to stream.map :fun [:streams] 2 if emptyp first :streams [output []] output stream apply :fun firsts :streams ~ `[(apply "stream.map fput ,[quoted :fun] (map "tail ,[:streams]))] end to stream.filter :fun :stream if emptyp :stream [output []] if invoke :fun head :stream ~ [output stream head :stream `[stream.filter ,[quoted :fun] tail ,[:stream]]] output stream.filter :fun tail :stream end to flatten :stream.of.streams if emptyp :stream.of.streams [output []] output flatten1 head :stream.of.streams :stream.of.streams end to flatten1 :stream :delayed.more.streams if emptyp :stream [output flatten tail :delayed.more.streams] output stream (head :stream) ~ `[flatten1 tail ,[:stream] ,[:delayed.more.streams]] end ; helper for debugging to show.stream :stream [:num 10] show show.stream1 :stream :num end to show.stream1 :stream :num if emptyp :stream [output []] if equalp :num 0 [output [...]] output fput head :stream (show.stream1 tail :stream :num-1) end ; examples to integers.from :n output stream :n `[integers.from ,[:n+1]] end make "integers integers.from 1 to sieve :stream output stream (head :stream) ~ `[sieve stream.filter [not divisiblep ? ,[head :stream]] tail ,[:stream]] end to divisiblep :big :small output 0 = remainder :big :small end make "primes sieve tail :integers ucblogo-5.5/csls/mines0100644000161300001330000003375610275755723012765 0ustar bhdoe; Minesweeper game ; Mouse clicks call HIT procedure ; Main data structure: array of arrays, e.g., ; (ITEM (ITEM STATUS 3) 5) for row 3 column 5. ; Values are: HIDDEN (tan square), ; FLAGGED (flagged as a mine), ; SHOWN (open, non-mine, shows number of mined neighbors), ; BORDER (just outside of actual playing field). ; Notice that a FLAGGED square might not really be a mine. ; (Player can make mistakes!) ; Actual mines are listed in MINES (list of [row col] lists). cslsload "buttons to mines if :LogoPlatform = "Windows [maximize.window "true] localmake "inference "false localmake "newnmines 100 localmake "newsize 20 localmake "halfsize 10 localmake "squaresize 2*:halfsize localmake "maxxmax :halfsize*20 localmake "maxymax :halfsize*20 localmake "sizechoice 3 localmake "hardchoice 2 localmake "sizes [10 15 20] localmake "hardness [18 21 28] localmake "windows ifelse :LogoPlatform="Windows [16] [0] catch "quit [forever [catch "newgame [setup :newnmines :newsize :newsize]]] cs ct setpc 7 st end ; ------------------------ Initial setup --------------------------------- to setup :nmines :rows :columns cs ct wait 0 ht localmake "mines [] ; list of [row col] lists localmake "statuses (array :rows+2 -1) ; status of each square localmake "xmax :halfsize*:columns localmake "ymax :halfsize*:rows localmake "opening "true localmake "playing "true ; false only at end of game for [i -1 :rows] [setitem :i :statuses (array :columns+2 -1)] putmines :nmines ; Choose mined squares randomly. setbg 0 setup.buttons make "nhidden :rows * :columns borderrow -1 :columns borderrow :rows :columns ; mark nonexistent squares just outside field as BORDER ; to simplify how-many-of-my-neighbors computations bordersides :rows-1 hint ; open some safe squares so we don't have to guess blindly localmake "prevmines -1 pu setxy :maxxmax-100-2*:windows :maxymax+14 setpc 7 label [Mines left:] showminesleft action.loop end to putmines :num ; Choose random square, and make it a mine unless it already was one. if :num = 0 [stop] localmake "row random :rows localmake "col random :columns if member? (list :row :col) :mines [putmines :num stop] make "mines fput (list :row :col) :mines putmines :num-1 end to setup.buttons init.buttons setbutton (list -:maxxmax :maxymax+10) [60 20] [throw "newgame] ~ "false 0 "|NEW GAME| "G setbutton (list 80-:maxxmax :maxymax+10) [40 20] [throw "quit] ~ "false 0 "QUIT "Q caption (list 160-:maxxmax-:windows :maxymax+10) [60 20] "infer: drawinferbuttons caption (list -:maxxmax -(:maxymax+30)) [60 20] "size: caption (list 160-:maxxmax-:windows -(:maxymax+30)) [80 20] "difficulty: drawsizebuttons setbutton (list -:xmax -:ymax) (list 2*:xmax 2*:ymax) ~ [hit :mousepos showminesleft] "false 9 "|| [] ; Entire board is one big button. showboard "false ; input is TRUE to uncover entire board at end of game pu end to drawinferbuttons rebutton (list 200-:maxxmax :maxymax+10) [20 20] ~ [make "inference "true drawinferbuttons] ~ :inference 0 "Y "Y rebutton (list 230-:maxxmax :maxymax+10) [20 20] ~ [make "inference "false drawinferbuttons] ~ not :inference 0 "N "N end to drawsizebuttons make "newsize item :sizechoice :sizes make "newnmines int (item :hardchoice :hardness)*:newsize*:newsize/100 rebutton (list 40-:maxxmax -(:maxymax+30)) [20 20] ~ [make "sizechoice 1 drawsizebuttons] ~ :sizechoice=1 0 "S "S rebutton (list 70-:maxxmax -(:maxymax+30)) [20 20] ~ [make "sizechoice 2 drawsizebuttons] ~ :sizechoice=2 0 "M "M rebutton (list 100-:maxxmax -(:maxymax+30)) [20 20] ~ [make "sizechoice 3 drawsizebuttons] ~ :sizechoice=3 0 "L "L rebutton (list 230-:maxxmax -(:maxymax+30)) [20 20] ~ [make "hardchoice 1 drawsizebuttons] ~ :hardchoice=1 0 "1 "1 rebutton (list 260-:maxxmax -(:maxymax+30)) [20 20] ~ [make "hardchoice 2 drawsizebuttons] ~ :hardchoice=2 0 "2 "2 rebutton (list 290-:maxxmax -(:maxymax+30)) [20 20] ~ [make "hardchoice 3 drawsizebuttons] ~ :hardchoice=3 0 "3 "3 end to showminesleft if :prevmines=:nmines [stop] setpensize [2 2] penerase if :prevmines > 99 [pu seth 0 setxy :maxxmax-30 :maxymax+14 invoke word "draw int :prevmines/100 7] if :prevmines > 9 [pu seth 0 setxy :maxxmax-19 :maxymax+14 invoke word "draw int (remainder :prevmines 100)/10 7] if :prevmines > -1 [pu seth 0 setxy :maxxmax-8 :maxymax+14 invoke word "draw remainder :prevmines 10 7] penpaint if :nmines > 99 [pu seth 0 setxy :maxxmax-30 :maxymax+14 invoke word "draw int :nmines/100 7] if :nmines > 9 [pu seth 0 setxy :maxxmax-19 :maxymax+14 invoke word "draw int (remainder :nmines 100)/10 7] if :nmines > -1 [pu seth 0 setxy :maxxmax-8 :maxymax+14 invoke word "draw remainder :nmines 10 7] make "prevmines :nmines pu seth 0 setpensize [1 1] end ; --------------------------- Mark border squares ------------------------- to borderrow :row :col ; Mark all squares on this row (including -1 and :columns) as border setstatus :row :col "border if :col < 0 [stop] borderrow :row :col-1 end to bordersides :row ; Mark squares -1 and :columns on all rows as border if :row < 0 [stop] setstatus :row -1 "border setstatus :row :columns "border bordersides :row-1 end ; ---------------------- Initial and final display of entire board -------- to showboard :over ; Input is FALSE during setup, TRUE when a mine is uncovered and game ends. setpc 7 for [y -:ymax :ymax :squaresize] [pu setxy -:xmax :y pd setxy :xmax :y] for [x -:xmax :xmax :squaresize] [pu setxy :x -:ymax pd setxy :x :ymax] pu turtlerows :rows-1 end to turtlerows :row if :row < 0 [stop] turtlerow :columns-1 turtlerows :row-1 end to turtlerow :col if :col < 0 [stop] ifelse :over [ ; game over, only hidden squares need be displayed if "hidden = status :row :col [onesquare] if and ("flagged = status :row :col) (not member? (list :row :col) :mines) [ ; but indicate mistakenly flagged ones setx (:col*:squaresize)-:xmax sety (:row*:squaresize)-:ymax setpensize [3 3] setpc 4 ; draw red X over mine symbol pd setxy xcor+:squaresize ycor+:squaresize pu setx xcor-:squaresize pd setxy xcor+:squaresize ycor-:squaresize pu setpensize [1 1] setpc 7 ] ] [ ; game starting, mark each square as hidden setstatus :row :col "hidden ] turtlerow :col - 1 end to onesquare action.once setx (:col*:squaresize)-:xmax sety (:row*:squaresize)-:ymax ifelse member? (list :row :col) :mines [ setpc 2 ; thick green border pu setxy xcor+1 ycor+1 pd repeat 4 [fd :squaresize-2 rt 90] pu setxy xcor+1 ycor+1 pd repeat 4 [fd :squaresize-4 rt 90] setpc 13 ; purple for undetected mine pu setxy xcor+3 ycor+3 fill ] [ setpc 11 ; grey in aqua border for empty pu setxy xcor+1 ycor+1 pd repeat 4 [fd :squaresize-2 rt 90] setpc 15 pu setxy xcor+3 ycor+3 fill ] end ; ---------------- Start game by uncovering a few safe squares -------------- to hint [:tries 30] [:inference "true] if :tries=0 [stop] ; limit number of attempts localmake "ohidden :nhidden localmake "ry random :rows localmake "rx random :columns if and equalp status :ry :rx "hidden not member? (list :ry :rx) :mines [ catch "error [hitsquare :ry :rx] if (:ohidden - :nhidden) > 5 [stop] ; stop when at least 5 neighbors were opened ] (hint :tries-1) end ; -------- Main player activity, mouse clicks on minefield squares ----- to hit :pos ; Convert mouse (pixel) coordinate to column and row numbers ; (square is :squaresize x :squaresize pixels) if not :playing [stop] localmake "opening equalp :button 1 ; true to open, false to flag catch "error [hitsquare (int (((last :pos) + :ymax) / :squaresize)) (int (((first :pos) + :xmax) / :squaresize))] end to hitsquare :row :col ; Called on player mouse click and automatic opening of neighbors ; when infering. if :nhidden = 0 [stop] ; No hidden squares, game is over. if (or (:row<0) (:row>=:rows) (:col<0) (:col>=:columns)) [stop] penup setx (:col*:squaresize)-:xmax ; Move turtle over chosen square sety (:row*:squaresize)-:ymax localmake "status status :row :col localmake "near neighbors :row :col "minecheck if not equal? :status "shown [ ; Clicking on hidden or flagged square. if not :opening [showflag stop] ; FLAG mode. (Below is OPEN mode.) if :status = "flagged [showflag stop] ; Can't open flagged square. setstatus :row :col "shown ; This square is now shown. if member? (list :row :col) :mines [lose stop] ; Oops! setpc 11 ; aqua border pu setxy xcor+1 ycor+1 pd repeat 4 [fd :squaresize-2 rt 90] pu setxy xcor+6 ycor+3 setpc 15 ; grey fill fill setpensize [2 2] seth 0 pu if :near>0 word "draw :near ; Run procedure to draw digit pu setpensize [1 1] seth 0 make "nhidden :nhidden - 1 ; Keep track of number of squares still hidden. if :nhidden = 0 [win stop] ; If all squares shown or flagged, we win! if and (not equal? :near 0) (not :inference) [stop] ; Finished if no automatic inference ] ; Automatic inference section: localmake "hnear neighbors :row :col "hiddencheck localmake "fnear neighbors :row :col "flaggedcheck ifelse :fnear = :near [ ; If number of neighboring mines equals localmake "opening "true ; number of flagged neighbors, hitfriends :row :col ; all hidden neighbors must be safe ; (unless player has flagged wrongly!) ] [ if (:hnear + :fnear) = :near [ ; If number of neighboring mines equals localmake "opening "false ; number of non-shown (hidden or flagged) hitfriends :row :col ; neighbors, all hidden neighbors must be ; mines. ] ] end ; --------------- Automatic inference to speed up game ------------------ ; Either OPEN or FLAG all eight immediate neighbors unless already open or ; flagged. Note mutual recursion: HITSQUARE calls HITFRIENDS to do inference; ; HITFRIENDS calls HITSQUARE for each inferred opening/flagging. to hitfriends :row :col hitfriendsrow :row-1 :col hitfriendsrow :row :col hitfriendsrow :row+1 :col end to hitfriendsrow :row :col hitfriend :row :col-1 hitfriend :row :col hitfriend :row :col+1 end to hitfriend :row :col if "hidden = status :row :col [hitsquare :row :col] end ; Here's where we count the neighbors that have some property ; (being truly mined, being flagged as mined, or being hidden). ; Third input is a procedure that takes ROW and COL inputs, ; returning 1 if property is satisfied, 0 if not. to neighbors :row :col :check output (nrow :row-1 :col) + (nrow :row :col) + (nrow :row+1 :col) end to nrow :row :col output (invoke :check :row :col-1) + (invoke :check :row :col) + ~ (invoke :check :row :col+1) end ; Here are the three property-checking procedures. to minecheck :row :col output ifelse member? (list :row :col) :mines [1] [0] end to hiddencheck :row :col output ifelse "hidden = status :row :col [1] [0] end to flaggedcheck :row :col output ifelse "flagged = status :row :col [1] [0] end ; --------------------- Flag mode (user says where mines are) -------------- to showflag if :nhidden = 0 [stop] ; Game is over, no action allowed. localmake "flagged status :row :col ifelse :flagged = "hidden [ ; Square was hidden, so flag it. if :nmines = 0 [stop] ; But don't allow more flags than actual mines. setstatus :row :col "flagged setpc 2 ; Green background pu setxy xcor+6 ycor+3 fill drawflag ; with purple flag make "nmines :nmines-1 make "nhidden :nhidden-1 ] [ if not equal? :flagged "flagged [stop] ; Square was shown, can't flag it. setstatus :row :col "hidden setpc 2 ; First make it all green pu setxy xcor+6 ycor+3 fill setpc 9 ; Square was flagged, unflag (hide) it. fill make "nmines :nmines + 1 make "nhidden :nhidden + 1 ] if :nhidden = 0 [win] ; Flagged last mine, so win. end to drawflag setpc 13 ; purple for flag setpensize [2 2] pd fd 5 repeat 4 [fd 5 rt 90] pu setxy xcor+3 ycor+3 fill end ; ------------ Notify user when game is won or lost ------------------- to win make "playing "false make "nhidden 0 print [You win!!!!] pu setxy :xmax+3 0 ; flash screen green repeat 5 [action.once setpc 2 fill wait 2 action.once setpc 0 fill wait 2] end to lose make "playing "false setpc 13 ; Show which mine was hit pu setxy xcor+3 ycor+3 fill setpc 6 ; Yellow square on purple setpensize [3 3] pd repeat 4 [fd :squaresize-6 rt 90] setpensize [1 1] make "nhidden 0 print [You lose!!!!] pu setxy :xmax+3 0 ; flash screen red repeat 5 [action.once setpc 4 fill wait 2 action.once setpc 0 fill wait 2] showboard "true end ; --------------- data abstraction for statuses array ------------- to status :row :col output item :col (item :row :statuses) end to setstatus :row :col :value setitem :col (item :row :statuses) :value end ; -------------------- draw digits ---------------------- to draw1 [:color 4] setpc :color ; red pd rt 90 fd 6 bk 3 lt 90 fd 12 lt 90+45 fd 4 end to draw2 [:color 13] setpc :color ; purple pu setxy xcor-1 ycor+2 pd rt 90 fd 6 bk 6 lt 45 fd 8 rt 45 pu bk 3 pd arc -180 3 end to draw3 [:color 0] setpc :color ; black pu fd 12 rt 90 pd fd 6 rt 90+45 fd 7 pu lt 45 fd 3 pd arc -130 3 end to draw4 [:color 8] setpc :color ; brown pu fd 6 pd fd 6 bk 6 rt 90 fd 6 bk 3 lt 90 fd 6 bk 12 end to draw5 [:color 10] setpc :color ; forest pu fd 12 pd rt 90 fd 6 bk 6 rt 90 fd 5 pu fd 3 pd arc -180 3 end to draw6 [:color 12] setpc :color ; salmon pu fd 7 rt 90 fd 1 pd repeat 270 [fd 0.07 rt 1] repeat 45 [fd 0.3 rt 2] end to draw7 [:color 1] setpc :color ; blue pu fd 11 rt 90 pd fd 6 rt 90+30 fd 9 end to draw8 [:color 5] setpc :color ; magenta pu fd 3 rt 90 fd 2 pd arc 359 3 pu lt 90 fd 6 pd arc 359 3 end to draw9 [:color 7] setpc :color pu fd 12 rt 90 fd 6 rt 90 ; like 6 but upside down pu fd 7 rt 90 fd 1 pd repeat 270 [fd 0.07 rt 1] repeat 45 [fd 0.3 rt 2] end to draw0 [:color 7] setpc :color pu fd 6 pd repeat 90 [fd (2-repcount/90)*6/150 rt 1] repeat 90 [fd (1+repcount/90)*6/150 rt 1] repeat 90 [fd (2-repcount/90)*6/150 rt 1] repeat 90 [fd (1+repcount/90)*6/150 rt 1] end ucblogo-5.5/csls/dotgame0100644000161300001330000002075710275755723013267 0ustar bhdoe;;; Connect-the-dots game to dotgame :size ; Connect-the-dots game. Input is the number of dots on each side. if :LogoPlatform = "Windows [maximize.window "true] ht cs setpc 7 setpensize [6 6] localmake "offset (:size-1)*20 pu setpos list -:offset -:offset board :size localmake "lines ~ se (crossmap [list (list ?1 ?2) (list ?1 1+?2)] (iseq 0 :size-1) (iseq 0 :size-2)) ~ (crossmap [list (list ?1 ?2) (list 1+?1 ?2)] (iseq 0 :size-2) (iseq 0 :size-1)) localmake "computer 0 localmake "person 0 localmake "numboxes (:size-1)*(:size-1) localmake "boxlists (array 5 0) localmake "oldmove [] for [i 1 4] [setitem :i :boxlists []] setitem 0 :boxlists ~ (crossmap [list ?1 ?2] (iseq 0 :size-2) (iseq 0 :size-2)) localmake "boxes (array :size-1 0) for [i 0 :size-2] [setitem :i :boxes (array :size-1 0)] CATCH "WIN [FOREVER [PERSONMOVE COMMOVE]] ; play the game! if not emptyp :oldmove [ ; make the last move white setpc 7 pu setpos map [40*? - :offset] first :oldmove pd setpos map [40*? - :offset] last :oldmove ] if computer > :person ~ [print (se [you lost] :computer "to :person)] if :computer < :person ~ [print (se [you won] :person "to :computer)] if :computer = :person [print (se [tie game])] setpensize [1 1] end ; --------------- Initial board display ------------------------- to board :num repeat :num [dots :num] end to dots :num pd repeat :num [fd 0 pu rt 90 fd 40 lt 90 pd] pu lt 90 fd 40 * :num rt 90 fd 40 end ; -------------- Human player's move --------------------- to personmove ; Read a mouse click, turn it into a move if legal. localmake "move gmove if not legal? :move [print [Not a legal move! Try again.] personmove stop] drawline :move 6 localmake "direction reverse (map "difference (last :move) (first :move)) localmake "found "false fillboxes 6 "person if :found [personmove] end to gmove while [not buttonp] [] while [buttonp] [] output findline (map [? + :offset] mousepos) end to findline :pos ; Find the nearest vertical or horizontal line to the mouse click. localmake "xrem remainder (first :pos)+10 40 localmake "yrem remainder (last :pos)+10 40 localmake "xpos (first :pos)+10-:xrem localmake "ypos (last :pos)+10-:yrem if :xrem > :yrem ~ [output list (list :xpos/40 :ypos/40) (list :xpos/40+1 :ypos/40)] output list (list :xpos/40 :ypos/40) (list :xpos/40 :ypos/40+1) end to legal? :move ; Output true if this is an undrawn line segment connecting two dots. output memberp :move :lines end ; ----------------- Computer's move ---------------------- to commove ; The computer chooses a move, does the housekeeping for it. ; Strategy: complete boxes if possible, otherwise pick a move that doesn't ; let the opponent complete a box. ifelse not emptyp (item 3 :boxlists) [ localmake "move lastline first (item 3 :boxlists) ] [ localmake "goodlines filter "lineokay? :lines ifelse not emptyp :goodlines [ localmake "move pick :goodlines ] [ localmake "cohorts [] makecohorts :lines localmake "move lastline first smallest :cohorts ] ] drawline :move 4 localmake "direction reverse (map "difference (last :move) (first :move)) localmake "found "false fillboxes 4 "computer if :found [commove] end to lineokay? :move ; Output true if this move won't let the opponent complete a box. localmake "direction reverse (map "difference (last :move) (first :move)) output and (boxokay? first :move) ~ (boxokay? (map "difference (first :move) :direction)) end to boxokay? :box ; Output true if this box has fewer than 2 edges already drawn. if or ((first :box) < 0) ((last :box) < 0) [output "true] if or ((first :box) > (:size-2)) ((last :box) > (:size-2)) [output "true] localmake "count item (last :box) item (first :box) :boxes if emptyp :count [make "count 0] output :count<2 end to lastline :box ; Box has three lines drawn; find the missing one for us to draw. if memberp (list :box (map "sum :box [0 1])) :lines [ output (list :box (map "sum :box [0 1]))] if memberp (list :box (map "sum :box [1 0])) :lines [ output (list :box (map "sum :box [1 0]))] if memberp (list (map "sum :box [0 1]) (map "sum :box [1 1])) :lines [ output (list (map "sum :box [0 1]) (map "sum :box [1 1]))] if memberp (list (map "sum :box [1 0]) (map "sum :box [1 1])) :lines [ output (list (map "sum :box [1 0]) (map "sum :box [1 1]))] output [] ; box was full already (from makecohort) end to makecohorts :lines ; Partition the available boxes into chains, to look for the smallest. ; Note, the partition is not necessarily optimal -- this algorithm needs work. ; It's important that LINES be a local variable here, so that we can "draw" ; lines hypothetically that we're not really going to draw on the board. while [not emptyp :lines] [ localmake "cohort [] makecohort first :lines push "cohorts :cohort ] end to makecohort :line ; Group all the boxes in a chain that starts with this line. ; Mark the line as drawn (locally to caller), then look in both directions ; for completable boxes. make "lines remove :line :lines localmake "direction reverse (map "difference (last :line) (first :line)) makecohort1 (map "difference (first :line) :direction) makecohort1 first :line end to makecohort1 :box ; Examine one of the boxes adjoining the line just hypothetically drawn. ; It has 0, 1, or 2 undrawn sides. (If 3 or 4, wouldn't have gotten here.) ; 0 sides -> count the box if not already, but no further lines in the chain. ; 1 side -> count the box, continue the chain with its last side. ; 2 sides -> the box isn't ready to complete, so it's not in this chain. if or ((first :box) < 0) ((last :box) < 0) [stop] if or ((first :box) > (:size-2)) ((last :box) > (:size-2)) [stop] localmake "togo filter [memberp (list (map "sum :box first ?) (map "sum :box last ?)) :lines] ~ [[[0 0] [0 1]] [[0 0] [1 0]] [[1 0] [1 1]] [[0 1] [1 1]]] if (count :togo)=2 [stop] if not memberp :box :cohort [push "cohort :box] if emptyp :togo [stop] localmake "line (list (map "sum :box first first :togo) (map "sum :box last first :togo)) makecohort :line end to smallest :cohorts [:sofar []] [:minsize :numboxes+1] if emptyp :cohorts [output :sofar] if (count first :cohorts) < :minsize ~ [output (smallest bf :cohorts first :cohorts count first :cohorts)] output (smallest bf :cohorts :sofar :minsize) end ; ----------- Common procedures for person and computer moves -------- to drawline :move :color ; Actually draw the selected move on the screen. if not emptyp :oldmove [ setpc 7 pu setpos map [40*? - :offset] first :oldmove pd setpos map [40*? - :offset] last :oldmove ] setpc :color pu setpos map [40*? - :offset] first :move pd setpos map [40*? - :offset] last :move make "oldmove :move end to fillboxes :color :owner ; Implicit inputs (inherited from caller): ; :move is the move someone just made. ; :direction is [1 0] for vertical move, [0 1] for horizontal. ; Note that the line is drawn, check the two boxes (maybe) on either side, ; color them and count them for the appropriate player, see if game over. make "lines remove :move :lines if boxbefore? :move [fillbox (map "difference (first :move) :direction)] if boxafter? :move [fillbox first :move] testwin end to boxafter? :move ; Output true if the box above or to the right of the move is now complete. output (increment first :move)=4 end to boxbefore? :move ; Output true if the box below or to the left of the move is now complete. localmake "p3 (map "difference (first :move) :direction) output (increment :p3)=4 end to increment :box ; If this isn't a box at all (might be if the move was on a border), ; just output []. Otherwise, increment the number in the :boxes array, ; and move this box from one of the :boxlists to the next higher one. ; Output the new count of number of lines drawn in this box. if or ((first :box) < 0) ((last :box) < 0) [output []] if or ((first :box) > (:size-2)) ((last :box) > (:size-2)) [output []] localmake "count item (last :box) item (first :box) :boxes if emptyp :count [make "count 0] setitem (last :box) item (first :box) :boxes :count+1 setitem :count :boxlists (remove :box item :count :boxlists) setitem :count+1 :boxlists (fput :box item :count+1 :boxlists) output :count+1 end to fillbox :box ; Color in a completed box, increase the box count of its owner, and ; flag that a box was completed. pu setpos (map [40*? + 10 - :offset] :box) setpc :color fill make :owner (thing :owner)+1 make "found "true end ; ------------------- Endgame processing -------------------- to testwin if :computer+:person = :numboxes [throw "win] end ucblogo-5.5/csls/master0100644000161300001330000002451110275755736013136 0ustar bhdoe; [Mastermind game] cslsload "buttons cslsload "streams to master [:numsquares 4] [:dup.ok "false] [:mysecret "true] ; Mastermind game program. ; Program is controlled by mouse clicks or keystrokes. if :LogoPlatform = "Windows [maximize.window "true] localmake "colors "ROYGBV localmake "colornums [[R 4] [O 14] [Y 6] [G 2] [B 1] [V 13]] localmake "exact "true local [numguesses numcolors column guess gotnum winloop permuting] local [perms oldcount newcount guess.exact guess.inexact guess.word] catch "quit [forever [ catch "master [ make "numguesses 0 make "numcolors 0 make "column 0 make "winloop "false initdraw ; Clear screen, draw color palette ifelse :mysecret [ ifelse :dup.ok ; Choose secret permutation [make "secret (choose.dup :numsquares :colors)] [make "secret (choose.nodup :numsquares :colors)] newguess ; Display first guess frame action.loop ; Read keyboard characters or mouse clicks ] [ catch "win [ ; User's secret, program has to guess. ifelse :dup.ok [ make "permuting "false ; Lots of cases with dups okay, so make "perms (list copies :numsquares "x) make "newcount 0 ; find colors systematically first. catch "perm [ for [i 1 6] [ ; Learn how many red, then orange, etc. make "oldcount :newcount doguess subst :i "x head :perms make "newcount :guess.exact + :guess.inexact make "perms flatten stream.map `[insert ,[:newcount-:oldcount] ,:i ?] :perms make "perms stream.filter `[okay? ? ,:guess.exact ,:guess.inexact ,:guess.word] :perms check.consistency :perms if equalp :newcount :numsquares [throw "perm] ] check.consistency [] ; Tried all colors, user lied. ] make "permuting "true ] [ make "perms perms "123456 :numsquares ; not :dup.ok make "permuting equalp :numsquares 6 ] forever [ ; common portion doguess head :perms if equalp :numsquares :guess.exact + :guess.inexact ~ [make "permuting "true] make "perms stream.filter `[okay? ? ,:guess.exact ,:guess.inexact ,:guess.word] :perms check.consistency :perms ] ; Can't get here; either doguess finds a winner or ; check.consistency complains. ] ; We get here on throw "win from doguess. move [15 12] setpc 7 label "WIN! ct print (sentence [I win in] :numguesses "turns.) make "winloop "true action.loop ] ]]] cs ct setpc 7 st end ;;; ================== LOGIC FOR MY GUESSES (USER SECRET) ================= to doguess :guessword ; Present computer's guess to user and ask about matches. newguess ; Draw frame for guess. make "guess.word :guessword ; Remember my colors. foreach :guessword [apply "putguess item ? :colornums] ; Show colors. askexact ; Ask user for exact matches. make "gotnum "false catch "ready [action.loop] ifelse :guess.exact < :numsquares [ ; Not all colors are exact. ifelse :permuting [ ; If we know all the colors, make "exact "false ; compute how many are inexact getnum :numsquares-:guess.exact ; without asking. ] [ askinexact ; Otherwise, ask for inexact. make "gotnum "false catch "ready [action.loop] if :guess.exact + :guess.inexact > :numsquares ~ [check.consistency []] ; Quick error message if too many matches. ] ] [ throw "win ; All colors are exact, we win. ] end to subst :new :old :word ; For dups-okay guessing: Substitute the next trial color for ; all unknown squares in a partial permutation. output map [ifelse equalp ? :old [:new] [?]] :word end to copies :num :letter output cascade :num [word ? :letter] " end to insert :num :new :word ; For dups-okay guessing: We've learned that there are :NUM instances ; of color :NEW in the secret combination, so stick that many of them into ; a still-possible partial permutation, in every possible size=:NUM ; subset of the unknown slots. ; The result is a *stream* of possible (partial) permutations. if :num=0 [output (list :word)] ; No slots needed, just one result. if emptyp :word [output []] ; Not enough slots, no results! if equalp first :word "x ; Else combine results of choosing or ~ [op flatten ; not choosing to replace into this X. stream insert :num-1 :new word :new butfirst :word `[(list stream.map [word "x ?] insert ,:num ",:new bf ",:word )]] output stream.map `[word ",[first :word] ?] insert :num :new butfirst :word end to check.consistency :str ; If the stream of still-possible permutations is empty, then ; the user has lied to us. if emptyp :str [ct print [Error -- inconsistent answers!] repeat 2 [setbg 4 setbg 0] type [Click or type anything to restart.] waitforclick throw "master] end to perms :word :num ; Output the stream of permutations of :NUM letters chosen from :WORD. if :num=0 [output (list "|| )] if emptyp :word [output []] ; Can't happen (would mean :num>count :word). output flatten stream.map ~ `[[letter] stream.map `[word ,:letter ?] perms remonce :letter ,:word ,[:num-1]] ~ :word end to okay? :perm :guess.exact :guess.inexact :guess.word output and (equalp :guess.exact exact :perm :guess.word) ~ (equalp :guess.inexact inexact :perm :guess.word) end to askexact ct type "|How many EXACT matches? | make "exact "true end to askinexact ct type "|How many INEXACT matches? | make "exact "false end ;;; ================== LOGIC FOR USER GUESSES (MY SECRET) ================= to choose.dup :number :colors if :number = 0 [output "] output word (pick :colors) (choose.nodup :number-1 :colors) end to choose.nodup :number :colors if :number = 0 [output "] make "color pick :colors output word :color (choose.nodup :number-1 remonce :color :colors) end ;;;;; ================ Used by both kinds of logic ====================== to exact :secret :guess if empty? :secret [output 0] output ehelp + (exact butfirst :secret butfirst :guess) end to ehelp ifelse equal? (first :secret) (first :guess) [output 1] [output 0] end to inexact :secret :guess output (anymatch :secret :guess) - (exact :secret :guess) end to anymatch :secret :guess if empty? :secret [output 0] if member? first :secret :guess ~ [output 1 + anymatch (butfirst :secret) (remonce first :secret :guess)] output anymatch butfirst :secret :guess end to remonce :this :those if empty? :those [output "] if equal? :this first :those [output butfirst :those] output word (first :those) (remonce :this butfirst :those) end ;;;;; =================== USER INTERFACE (DRAWING) ======================= to initdraw ct init.buttons ifelse :mysecret ~ [colorchart 6 "ROYGBV [4 14 6 2 1 13] 150 setbutton [-240 -30] [25 25] [clear] "false 0 "erase "DEL] ~ [numchart 0 150] setbutton [-240 -60] [25 25] [if not :winloop [guess]] "true 0 "OK "RET setbutton [-240 -90] [25 25] [throw "master] "false 0 [new game] "N setbutton [-240 -120] [25 25] [throw "quit] "false 0 "quit "Q setbutton [-240 -170] [40 25] [make "mysecret "true throw "master] ~ :mysecret 0 [I guess] [] setbutton [-240 -200] [40 25] [make "mysecret "false throw "master] ~ (not :mysecret) 0 [Logo guess] [] caption [-240 206] [65 29] [Number |of colors:|] numsquares -170 2 6 caption [0 206] [65 29] [Duplicates allowed:] setbutton [70 210] [25 25] [make "dup.ok "true throw "master] ~ :dup.ok 0 "yes [] setbutton [100 210] [25 25] [make "dup.ok "false throw "master] ~ (not :dup.ok) 0 "no [] end to numsquares :xcor :num :last if :num > :last [stop] setbutton (list :xcor 210) [25 25] `[make "numsquares ,:num throw "master] ~ (:num = :numsquares) 0 :num [] numsquares :xcor+30 :num+1 :last end to colorchart :num :names :colors :ycor if :num = 0 [stop] setbutton (list -240 :ycor) [25 25] ~ `[putguess ",[first :names] ,[first :colors]] "false ~ (first :colors) [] (first :names) colorchart :num-1 bf :names bf :colors :ycor-30 end to numchart :num :ycor if :num > :numsquares [stop] setbutton (list -240 :ycor) [25 25] ~ `[if not :winloop [getnum ,:num]] "false 0 :num :num numchart :num+1 :ycor-30 end to move :start ; Move the turtle to the given coordinates ; relative to the lower left corner of the first empty square ; in the current frame. ; Depends on :COLUMN (0 or 1 for >14 guesses), :NUMGUESSES, and :NUMCOLORS ; Note, since :NUMGUESSES starts at 1, ; first frame is at [-180 170] not [-180 200]. pu setpos (list (-180 + (first :start) + 220*:column + 25*(:numcolors-1)) (200 + (last :start) - 30*(:numguesses - 14*:column))) pd end ; ----------------------------------------------- to newguess ; Called from MASTER for first guess frame, ; then from GUESS for later guess frames (my secret), ; or from DOGUESS (user's secret). make "numguesses :numguesses+1 if :numguesses > 14 [make "column 1] make "numcolors 1 move [0 0] drawframe make "guess " end to drawframe setpc 7 seth 0 repeat :numsquares [square 25 rt 90 fd 25 lt 90] end to square :side repeat 4 [fd :side rt 90] end ;;;;; =================== USER INTERFACE (READING) ======================= to waitforclick ; Wait for any key or mouse click, then return, ignoring which/where. if buttonp [while [buttonp] [] stop] if keyp [ignore rc stop] waitforclick end ; ----------- Procedures to carry out user commands --------------- to getnum :num [:cursor cursor] ; Called for digit key or mouse click on digit button. make ifelse :exact ["guess.exact] ["guess.inexact] :num move list ifelse :exact [15] [40] 12 setpc 7 label :num type :num setcursor :cursor make "gotnum "true end to putguess :colorletter :colornumber ; Called from mouse click in color palette; ; first input is a letter for :GUESS (e.g. R for red), ; second input is a Logo color number for SETPC (e.g. 4 for red). if :numcolors < 1 [stop] if :numcolors > :numsquares [stop] if not :dup.ok [if member? :colorletter :guess [stop]] make "guess word :guess :colorletter move [10 10] setpc :colornumber fill make "numcolors :numcolors+1 end to clear ; Called by clicking ERASE button if :numcolors < 2 [stop] make "guess butlast :guess make "numcolors :numcolors-1 move [10 10] setpc 0 fill end to guess ; Called by clicking GUESS button. if not :mysecret [if :gotnum [ct wait 0 throw "ready] stop] if not (:numcolors > :numsquares) [stop] ifelse equal? :guess :secret [ move [15 12] setpc 7 label "WIN! print (sentence [You win in] :numguesses "turns.) ] [ move [15 12] setpc 7 label exact :secret :guess move [40 12] setpc 7 label inexact :secret :guess newguess ] end ucblogo-5.5/csls/buttons0100644000161300001330000001260410275737531013332 0ustar bhdoe;;; Primitive GUI for Logo games. ;;; Displays buttons, then accepts mouseclicks or keystrokes ;;; to control actions. ;;; To clear the screen and all the remembered buttons: ;;; init.buttons ;;; To install a button: ;;; SETBUTTON [150 130] [40 25] [make "mysecret "true throw "newgame] ~ ;;; :mysecret 0 [Logo guess] [] ;;; ;;; Inputs are: ;;; 1. Position of lower left corner of button ;;; 2. Size [x y] of button ;;; 3. Action to take if button pressed ;;; 4. TRUE if box should be drawn thick, FALSE if thin ;;; 5. Color to fill box (0 if no fill) ;;; 6. Text caption inside button (a word or a two-word list for ;;; a two-line caption) or empty list for no caption ;;; 7. Equivalent keystroke (empty list if no equivalent keystroke) ;;; (DEL means char 8 or 127; RET means char 10 or 13) ;;; (Keystroke inside list, e.g., [X], means don't draw it.) ;;; REBUTTON (same inputs as SETBUTTON) looks for existing matching button ;;; and, if found, just redraws border (possibly changing thickness). ;;; To display a descriptive caption (e.g., for a group of buttons) ;;; without making a button: ;;; CAPTION [150 130] [40 25] [Number |of boxes:|] ;;; CENTER.CAPTION [150 130] [40 25] [Number |of boxes:|] ;;; ;;; Inputs are position, size, caption. ;;; CENTER.CAPTION centers the text within the box; CAPTION puts it ;;; at the left edge of the box. ;;; To loop reading keystrokes or mouseclicks and taking actions as set: ;;; ACTION.LOOP ;;; Within an action, :CHAR is the character typed (or zero if the action ;;; was triggered by a mouse click), :BUTTON is the mouse button pressed ;;; (or zero if the action was triggered by a keystroke), and :MOUSEPOS is ;;; the mouse position (or unspecified for a keystroke). Actions triggered ;;; by a mouse click happen when the mouse button is released. ; ----------------------------- ;;; IMPORTANT: Here is how we know the size of a text character as ;;; drawn by the LABEL command. Change these numbers if necessary: make "labelcharsize ifelse equalp :LogoPlatform "Windows [[8 13]] [[6 11]] ; ----------------------------- to init.buttons cs ht make "buttons [] end ; ----------------------------- to setbutton :corner :size :action :thickp :fillcolor :caption :key center.caption :corner :size :caption pu setpos :corner seth 0 pd setpensize ifelse :thickp [[3 3]] [[1 1]] setpc 7 apply "button.rectangle :size setpensize [1 1] if not equalp :fillcolor 0 [ button.offset :corner 5 5 setpc :fillcolor fill setpc 7 ] if (and (not listp :key) (not emptyp :key) (not equalp :key :caption)) [ caption (list (sum first :corner first :size 4) last :corner) ~ (list (first :labelcharsize) (last :size)) ~ :key ] if and (listp :key) (not emptyp :key) [make "key first :key] push "buttons (list :corner :size :key :action) end to rebutton :corner :size :action :thickp :fillcolor :caption :key localmake "thekey :key if and listp :key not emptyp :key [make "thekey first :key] localmake "test (list :corner :size :thekey :action) localmake "button find [equalp ? :test] :buttons if emptyp :button ~ [setbutton :corner :size :action :thickp :fillcolor :caption :key stop] penup setpos :corner seth 0 setpc 7 penerase setpensize [3 3] apply "button.rectangle :size penpaint setpensize ifelse :thickp [[3 3]] [[1 1]] apply "button.rectangle :size setpensize [1 1] end to button.offset :corner :dx :dy penup setxy (first :corner)+:dx (last :corner)+:dy end to button.rectangle :x :y repeat 2 [fd :y rt 90 fd :x rt 90] end ; ----------------------------- to caption :corner :size :caption if emptyp :caption [stop] localmake "halfx (first :labelcharsize)/2 localmake "y (last :labelcharsize) setpc 7 ifelse listp :caption [ button.offset :corner 0 ((14-:y)+((last :size)-25)/3) label last :caption button.offset :corner 0 ((14-:y)+:y+2*((last :size)-25)/3) label first :caption ] [ button.offset :corner 0 ((17-:y)+((last :size)-17)/2) label :caption ] end to center.caption :corner :size :caption if emptyp :caption [stop] localmake "halfx (first :labelcharsize)/2 localmake "y (last :labelcharsize) setpc 7 ifelse listp :caption [ button.offset :corner (1+(first :size)/2-:halfx*(count last :caption)) ~ ((14-:y)+((last :size)-25)/3) label last :caption button.offset :corner (1+(first :size)/2-:halfx*(count first :caption)) ~ ((14-:y)+:y+2*((last :size)-25)/3) label first :caption ] [ button.offset :corner (1+(first :size)/2-:halfx*(count :caption)) ~ ((17-:y)+((last :size)-17)/2) label :caption ] end ; ----------------------------- to action.loop forever [action.once] end to action.once if keyp [button.readkey] if buttonp [button.mouseclick] end to button.readkey [:char rc] [:button 0] foreach :buttons [ localmake "key item 3 ? ifelse equalp :key "DEL [ if memberp (ascii :char) [8 127] [run last ? stop] ] [ ifelse equalp :key "RET [ if memberp (ascii :char) [10 13] [run last ? stop] ] [ if equalp :char :key [run last ? stop] ] ] ] end to button.mouseclick [:mousepos mousepos] [:button button] [:char 0] while [buttonp] [] ; wait for release of button foreach :buttons [ if apply "button.inrange ? [run last ? stop] ] end to button.inrange :corner :size :key :action (foreach :mousepos :corner :size [ if ?1 < ?2 [output "false] if ?1 > (?2 + ?3) [output "false] ]) output "true end ucblogo-5.5/macterm.h0100644000161300001330000001060307672425024012541 0ustar bhdoe/* * macterm.h mac-specific graphics macros mak * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include extern WindowPtr graphics_window, listener_window; /* mak */ #define GR_SIZE 30000 #define prepare_to_draw GetPort(&savePort); SetPort(graphics_window) #define done_drawing SetPort(savePort) #define prepare_to_draw_turtle nop() #define done_drawing_turtle nop() #define screen_left 1 #define screen_right (graphics_window->portRect.right - 1) #define screen_top 1 #define screen_bottom (graphics_window->portRect.bottom - 1) #define screen_height (1 + screen_bottom - screen_top) #define screen_width (1 + screen_right - screen_left) #define screen_x_center (screen_left + (screen_width)/2) #define screen_y_center (screen_top + (screen_height)/2) #define turtle_left_max ((screen_left) - (screen_x_center)) #define turtle_right_max ((screen_right) - (screen_x_center)) #define turtle_top_max ((screen_y_center) - (screen_top)) #define turtle_bottom_max ((screen_y_center) - (screen_bottom)) #define screen_x_coord ((screen_x_center) + turtle_x) #define screen_y_coord ((screen_y_center) - turtle_y) #define turtle_height 18 #define turtle_half_bottom 6.0 #define turtle_side 19.0 #define clear_screen erase_screen() #define line_to(x,y) LineTo(x,y) #define move_to(x,y) MoveTo(x,y) #define draw_string(s) DrawString(s) #define set_pen_vis(v) graphics_window->pnVis = v #define set_pen_mode(m) graphics_window->pnMode = m #define set_pen_color(c) mac_set_pc(c) #define set_back_ground(c) mac_set_bg(c); #define set_pen_width(w) graphics_window->pnSize.h = w #define set_pen_height(h) graphics_window->pnSize.v = h #define set_pen_x(x) graphics_window->pnLoc.h = x #define set_pen_y(y) graphics_window->pnLoc.v = y /* pen_info is a stucture type with fields for the various pen characteristics including the location, size, color, mode (e.g. XOR or COPY), pattern, visibility (0 = visible) */ typedef struct { PenState ps; int vis; long color; } pen_info; #define p_info_x(p) p.ps.pnLoc.h #define p_info_y(p) p.ps.pnLoc.v #define pen_width graphics_window->pnSize.h #define pen_height graphics_window->pnSize.v #define pen_mode graphics_window->pnMode #define pen_vis graphics_window->pnVis #define pen_x graphics_window->pnLoc.h #define pen_y graphics_window->pnLoc.v #define get_node_pen_pattern Get_node_pen_pattern() #define pen_reverse graphics_window->pnMode = patXor #define pen_erase graphics_window->pnMode = patBic #define pen_down graphics_window->pnMode = patCopy #define button Button() #define mouse_x mickey_x() #define mouse_y mickey_y() #define full_screen f_screen() #define split_screen s_screen() #define text_screen t_screen() #define max(x,y) ((x > y) ? x : y) /* colors #define blackColor 33 #define whiteColor 30 #define redColor 205 #define greenColor 341 #define blueColor 409 #define cyanColor 273 #define magentaColor 137 #define yellowColor 69 */ extern GrafPtr savePort; extern int x_coord, y_coord, x_max, y_max, tty_charmode; extern char so_arr[], se_arr[]; extern void save_pen(), restore_pen(), plain_xor_pen(), set_pen_pattern(); extern void set_list_pen_pattern(), get_pen_pattern(), erase_screen(); extern void t_screen(), s_screen(), f_screen(), tone(), logofill(), nop(); extern FIXNUM mickey_x(), mickey_y(); extern NODE *Get_node_pen_pattern(); extern void c_to_pascal_string(), pascal_to_c_string(); extern FIXNUM pen_color, back_ground; extern void mac_set_pc(), mac_set_bg(); extern void get_palette(int slot, unsigned int *r, unsigned int *g, unsigned int *b); extern void set_palette(int slot, unsigned int r, unsigned int g, unsigned int b); ucblogo-5.5/main.c0100644000161300001330000001230410271252313012014 0ustar bhdoe/* * main.c logo main procedure module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef WIN32 #include #include /* needed? */ #endif #include "logo.h" #include "globals.h" #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif #ifdef __RZTC__ #include #define SIGQUIT SIGTERM #include #endif #ifndef TIOCSTI #include jmp_buf iblk_buf; #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef mac #include #endif NODE *current_line = NIL; NODE **bottom_stack; /*GC*/ void unblock_input(void) { if (input_blocking) { input_blocking = 0; #ifdef mac csetmode(C_ECHO, stdin); fflush(stdin); #endif #ifdef TIOCSTI ioctl(0,TIOCSTI,"\n"); #else longjmp(iblk_buf,1); #endif } } extern int in_eval_save; #ifdef SIG_TAKES_ARG #define sig_arg 0 RETSIGTYPE logo_stop(int sig) #else #define sig_arg RETSIGTYPE logo_stop() #endif { if (inside_gc || in_eval_save) { int_during_gc = 1; } else { charmode_off(); to_pending = 0; err_logo(STOP_ERROR,NIL); #ifdef __RZTC__ if (!input_blocking) #endif signal(SIGINT, logo_stop); unblock_input(); } SIGRET } #ifdef SIG_TAKES_ARG #define sig_arg 0 RETSIGTYPE logo_pause(int sig) #else #define sig_arg RETSIGTYPE logo_pause() #endif { if (inside_gc || in_eval_save) { int_during_gc = 2; } else { charmode_off(); to_pending = 0; #ifdef bsd sigsetmask(0); #else #if !defined(mac) && !defined(_MSC_VER) signal(SIGQUIT, logo_pause); #endif #endif lpause(NIL); } SIGRET } #ifdef SIG_TAKES_ARG #define sig_arg 0 RETSIGTYPE mouse_down(int sig) #else #define sig_arg RETSIGTYPE mouse_down() #endif { NODE *line; if (inside_gc || in_eval_save) { if (int_during_gc == 0) int_during_gc = 3; } else { line = valnode__caseobj(Buttonact); if (line != UNBOUND) eval_driver(line); } SIGRET } RETSIGTYPE (*intfuns[])() = {0, logo_stop, logo_pause, mouse_down}; void delayed_int() { #ifdef SIG_TAKES_ARG (void)(*intfuns[int_during_gc])(0); #else (void)(*intfuns[int_during_gc])(); #endif } #if defined(__RZTC__) && !defined(WIN32) /* sowings */ void _far _cdecl do_ctrl_c(void) { ctrl_c_count++; } #endif #ifdef HAVE_WX int start (int argc,char ** argv) { #else int main(int argc, char *argv[]) { #endif NODE *exec_list = NIL; #ifdef SYMANTEC_C extern void (*openproc)(void); extern void __open_std(void); openproc = &__open_std; #endif #ifdef mac init_mac_memory(); #endif bottom_stack = &exec_list; /*GC*/ #ifndef HAVE_WX #ifdef x_window x_window_init(argc, argv); #endif #endif (void)addseg(); term_init(); init(); math_init(); #ifdef ibm signal(SIGINT, SIG_IGN); #if defined(__RZTC__) && !defined(WIN32) /* sowings */ _controlc_handler = do_ctrl_c; controlc_open(); #endif #else /* !ibm */ signal(SIGINT, logo_stop); #endif /* ibm */ #ifdef mac signal(SIGQUIT, SIG_IGN); #else /* !mac */ signal(SIGQUIT, logo_pause); #endif /* SIGQUITs never happen on the IBM */ if (argc < 2) { #ifndef WIN32 if (isatty(1)) #endif { lcleartext(NIL); ndprintf(stdout, message_texts[WELCOME_TO], "5.5"); new_line(stdout); } } setvalnode__caseobj(LogoVersion, make_floatnode(5.5)); setflag__caseobj(LogoVersion, VAL_BURIED); silent_load(Startup, NULL); /* load startup.lg */ argv++; while (--argc > 0 && NOT_THROWING) { silent_load(NIL,*argv++); } for (;;) { if (NOT_THROWING) { check_reserve_tank(); current_line = reader(stdin,"? "); #ifdef __RZTC__ (void)feof(stdin); if (!in_graphics_mode) printf(" \b"); fflush(stdout); #endif #ifndef WIN32 if (feof(stdin) && !isatty(0)) lbye(NIL); #endif #ifdef __RZTC__ if (feof(stdin)) clearerr(stdin); #endif if (NOT_THROWING) { exec_list = parser(current_line, TRUE); if (exec_list != NIL) eval_driver(exec_list); } } if (stopping_flag == THROWING) { if (isName(throw_node, Name_error)) { err_print(NULL); } else if (isName(throw_node, Name_system)) break; else if (!isName(throw_node, Name_toplevel)) { err_logo(NO_CATCH_TAG, throw_node); err_print(NULL); } stopping_flag = RUN; } if (stopping_flag == STOP || stopping_flag == OUTPUT) { /* ndprintf(stdout, "%t\n", message_texts[CANT_STOP]); */ stopping_flag = RUN; } } prepare_to_exit(TRUE); return 0; } ucblogo-5.5/math.c0100644000161300001330000004044110137260754012035 0ustar bhdoe/* * math.c logo math functions module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "logo.h" #include "globals.h" #include #include #include #define isdigit(dig) (dig >= '0' && dig <= '9') int numberp(NODE *snd) { int dl,dr, pcnt, plen; char *p; if (is_number(snd)) return(1); snd = cnv_node_to_strnode(snd); if (snd == UNBOUND) return(0); p = getstrptr(snd); plen = getstrlen(snd); pcnt = dl = dr = 0; if (plen >= MAX_NUMBER) { return(0); } if (pcnt < plen && *p == '-') p++, pcnt++; while (pcnt < plen && isdigit(*p)) p++, pcnt++, dl++; if (pcnt < plen && *p == '.') { p++, pcnt++; while (pcnt < plen && isdigit(*p)) p++, pcnt++, dr++; } if (pcnt < plen && (dl || dr) && (*p == 'E' || *p == 'e')) { p++, pcnt++; if (pcnt < plen && (*p == '+' || *p == '-')) p++, pcnt++; while (pcnt < plen && isdigit(*p)) p++, pcnt++, dr++; } if ((dl == 0 && dr == 0) || pcnt != plen) return (0); else return (dr + 1); } NODE *lrandom(NODE *arg) { NODE *val; long r, base, range; val = pos_int_arg(arg); if (NOT_THROWING) { if (cdr(arg)==0) { /* (random 10) => (0, 10) */ base = 0; range = getint(val); } else { /* (random 3 10) => (3, 8) */ base = getint(val); val = pos_int_arg(arg); if (NOT_THROWING) { /* (random 0 9) <=> (random 10) */ range = getint(val); range = range + 1 - base; } } } if (NOT_THROWING) { #ifdef HAVE_SRANDOM r = (range <= 0 ? 0 : random() % range); #else r = (((long)rand()) << 15) | rand(); r = (range <= 0 ? 0 : r % range); #endif r += base; val = newnode(INT); setint(val, (FIXNUM)r); return(val); } else return(UNBOUND); } NODE *lrerandom(NODE *arg) { int seed=1; if (arg != NIL) { seed = int_arg(arg); } if (NOT_THROWING) { #ifdef HAVE_SRANDOM srandom((int)seed); #else srand((int)seed); #endif } return(UNBOUND); } jmp_buf oflo_buf; BOOLEAN handling_oflo = FALSE; #ifdef SIG_TAKES_ARG #define sig_arg 0 RETSIGTYPE handle_oflo(int sig) { #else #define sig_arg RETSIGTYPE handle_oflo() { #endif signal(SIGFPE, handle_oflo); if (handling_oflo) longjmp(oflo_buf,1); SIGRET } void math_init() { signal(SIGFPE, handle_oflo); } #ifdef HAVE_MATHERR int matherr(struct exception *x) { if (x->type == UNDERFLOW) return(1); longjmp(oflo_buf,1); } #endif #ifdef mac FLONUM degrad = 0.017453292520; #else FLONUM degrad = 3.141592653589793227020265931059839203954/180.0; #endif #if defined(mac)||defined(ibm) #define errchk(x) {errno = 0; x; if (errno) err_logo(BAD_DATA_UNREC,arg);} #include #else #define errchk(x) x #endif NODE *binary(NODE *args, char fcn) { NODE *arg, *val; BOOLEAN imode; FIXNUM iarg = 0, ival = 0, oval, nval; FLONUM farg = 0.0, fval = 0.0; int sign, wantint=0; /* Force imode, arg and fval into the stack because otherwise they may be clobbered during setjmp/longjmp. Especially on Sparc. */ (void)&imode; (void)&arg; (void)&fval; /* if (fcn == '%' || fcn == 'm') arg = integer_arg(args); else */ arg = numeric_arg(args); args = cdr(args); if (stopping_flag == THROWING) return UNBOUND; if (nodetype(arg) == INT) { imode = TRUE; ival = getint(arg); } else { imode = FALSE; fval = getfloat(arg); } if (args == NIL) { /* one argument supplied */ if (imode) switch(fcn) { case '-': ival = -ival; break; case '~': ival = ~ival; break; case 's': case 'c': case 't': case 'S': case 'C': case 'T': case 'q': case 'e': case 'g': case 'n': case '/': imode = FALSE; fval = (FLONUM)ival; break; } if (imode == FALSE) { if (!setjmp(oflo_buf)) { switch(fcn) { case '-': fval = -fval; break; case '/': if (fval == 0.0) err_logo(BAD_DATA_UNREC,arg); else fval = 1/fval; break; case '~': err_logo(BAD_DATA_UNREC,arg); break; case 'c': fval = 90.0 - fval; case 's': /* Kahan sez we can't just multiply any old * angle by degrad, but have to get into the * range 0-45 first */ sign = (fval < 0.0); if (sign) fval = -fval; #ifndef HAVE_DREM fval = fmod(fval,360.0); #else fval = drem(fval,360.0); #endif if (fval > 180.0) { fval -= 180.0; sign = !sign; } if (fval > 90.0) fval = 180.0 - fval; if (fval > 45.0) fval = cos((90.0-fval)*degrad); else fval = sin(fval*degrad); if (sign) fval = -fval; break; case 't': fval = atan(fval)/degrad; break; case 'S': fval = sin(fval); break; case 'C': fval = cos(fval); break; case 'T': fval = atan(fval); break; case 'q': errchk(fval = sqrt(fval)); break; case 'e': errchk(fval = exp(fval)); break; case 'g': errchk(fval = log10(fval)); break; case 'n': errchk(fval = log(fval)); break; case 'r': fval += (fval < 0 ? -0.5 : 0.5); case 'i': handling_oflo = TRUE; if (fval > (FLONUM)MAXLOGOINT || fval < -(FLONUM)MAXLOGOINT) handle_oflo(sig_arg); ival = (FIXNUM)fval; imode = TRUE; handling_oflo = FALSE; break; } } else { /* overflow */ if (fcn == 'r' || fcn == 'i') { if (fval < 0.0) fval = ceil(fval); else fval = floor(fval); } else err_logo(BAD_DATA_UNREC,arg); } } /* end float case */ } /* end monadic */ while (args != NIL && NOT_THROWING) { /* if (fcn == '%' || fcn == 'm') arg = integer_arg(args); else */ arg = numeric_arg(args); args = cdr(args); if (stopping_flag == THROWING) return UNBOUND; if (nodetype(arg) == INT) { if (imode) iarg = getint(arg); else farg = (FLONUM)getint(arg); } else { if (imode) { fval = (FLONUM)ival; imode = FALSE; } farg = getfloat(arg); } if (imode) { oval = ival; handling_oflo = TRUE; if (setjmp(oflo_buf) == 0) { switch(fcn) { case '-': iarg = -iarg; case '+': if (iarg < 0) { nval = ival + iarg; if (nval >= ival) { imode = FALSE; fcn = '+'; fval = (FLONUM)ival; farg = (FLONUM)iarg; } else ival = nval; } else { nval = ival + iarg; if (nval < ival) { imode = FALSE; fcn = '+'; fval = (FLONUM)ival; farg = (FLONUM)iarg; } else ival = nval; } break; case '/': if (iarg == 0) err_logo(BAD_DATA_UNREC,arg); else if (ival % iarg != 0) { imode = FALSE; fval = (FLONUM)ival; farg = (FLONUM)iarg; } else ival /= iarg; break; case '%': if (iarg == 0) err_logo(BAD_DATA_UNREC,arg); else ival %= iarg; break; case 'm': if (iarg == 0) err_logo(BAD_DATA_UNREC,arg); else ival %= iarg; if ((ival < 0) != (iarg < 0)) ival += iarg; break; case '&': ival &= iarg; break; case '|': ival |= iarg; break; case '^': ival ^= iarg; break; case 'a': case 'l': if (iarg < 0) { if (fcn == 'a') ival >>= -iarg; else ival = (unsigned)ival >> -iarg; } else ival <<= iarg; break; case '*': if (ival < SAFEINT && ival > -SAFEINT && iarg < SAFEINT && iarg > -SAFEINT) { ival *= iarg; break; } wantint++; default: /* math library */ imode = FALSE; fval = (FLONUM)ival; farg = (FLONUM)iarg; } } else { /* integer overflow detected */ imode = FALSE; fval = (FLONUM)oval; farg = (FLONUM)iarg; } handling_oflo = FALSE; } if (imode == FALSE) { handling_oflo = TRUE; if (setjmp(oflo_buf) == 0) { switch(fcn) { case '+': fval += farg; break; case '-': fval -= farg; break; case '*': fval *= farg; if (wantint) { wantint = 0; if (fval <= MAXLOGOINT && fval >= -MAXLOGOINT) { imode = TRUE; ival = (FIXNUM)fval; } } break; case '/': if (farg == 0.0) err_logo(BAD_DATA_UNREC,arg); else fval /= farg; break; case 't': errchk(fval = atan2(farg,fval)/degrad); break; case 'T': errchk(fval = atan2(farg,fval)); break; case 'p': errchk(fval = pow(fval,farg)); break; case '%': if (farg == 0.0) err_logo(BAD_DATA_UNREC,arg); else errchk(fval = fmod(fval,farg)); break; case 'm': if (farg == 0.0) err_logo(BAD_DATA_UNREC,arg); else errchk(fval = fmod(fval,farg)); if ((fval < 0.0) != (farg < 0.0)) fval += farg; break; default: /* logical op */ if (nodetype(arg) == INT) err_logo(BAD_DATA_UNREC, make_floatnode(fval)); else err_logo(BAD_DATA_UNREC,arg); } } else { /* floating overflow detected */ err_logo(BAD_DATA_UNREC,arg); } handling_oflo = FALSE; } /* end floating point */ } /* end dyadic */ if (NOT_THROWING) { if (imode) { val = newnode(INT); setint(val, ival); } else { val = newnode(FLOATT); setfloat(val, fval); } return(val); } return(UNBOUND); } NODE *ladd(NODE *args) { if (args == NIL) return make_intnode(0L); return(binary(args, '+')); } NODE *lsub(NODE *args) { return(binary(args, '-')); } NODE *lmul(NODE *args) { if (args == NIL) return make_intnode(1L); return(binary(args, '*')); } NODE *ldivide(NODE *args) { return(binary(args, '/')); } NODE *lremainder(NODE *args) { return(binary(args, '%')); } NODE *lmodulo(NODE *args) { return(binary(args, 'm')); } NODE *lbitand(NODE *args) { if (args == NIL) return make_intnode(-1); return(binary(args, '&')); } NODE *lbitor(NODE *args) { if (args == NIL) return make_intnode(0); return(binary(args, '|')); } NODE *lbitxor(NODE *args) { if (args == NIL) return make_intnode(0); return(binary(args, '^')); } NODE *lashift(NODE *args) { return(binary(args, 'a')); } NODE *llshift(NODE *args) { return(binary(args, 'l')); } NODE *lbitnot(NODE *args) { return(binary(args, '~')); } NODE *lsin(NODE *args) { return(binary(args, 's')); } NODE *lcos(NODE *args) { return(binary(args, 'c')); } NODE *latan(NODE *args) { return(binary(args, 't')); } NODE *lradsin(NODE *args) { return(binary(args, 'S')); } NODE *lradcos(NODE *args) { return(binary(args, 'C')); } NODE *lradatan(NODE *args) { return(binary(args, 'T')); } NODE *lsqrt(NODE *args) { return(binary(args, 'q')); } NODE *linteg(NODE *args) { return(binary(args, 'i')); } NODE *lroundx(NODE *args) { /* There's an lround in */ return(binary(args, 'r')); } NODE *lexp(NODE *args) { return(binary(args, 'e')); } NODE *llog10(NODE *args) { return(binary(args, 'g')); } NODE *lln(NODE *args) { return(binary(args, 'n')); } NODE *lpower(NODE *args) { return(binary(args, 'p')); } int compare_numnodes(NODE *n1, NODE *n2) { FLONUM f; FIXNUM i; if (nodetype(n1) == INT) { if (nodetype(n2) == INT) { i = getint(n1) - getint(n2); return (i == 0L ? 0 : (i > 0L ? 1 : -1)); } else { f = (FLONUM)getint(n1) - getfloat(n2); return(f == 0.0 ? 0 : (f > 0.0 ? 1 : -1)); } } else { if (nodetype(n2) == INT) { f = getfloat(n1) - (FLONUM)getint(n2); return(f == 0.0 ? 0 : (f > 0.0 ? 1 : -1)); } else { f = getfloat(n1) - getfloat(n2); return(f == 0.0 ? 0 : (f > 0.0 ? 1 : -1)); } } } NODE *torf(BOOLEAN tf) { return (tf ? TrueName() : FalseName()); } NODE *llessp(NODE *args) { NODE *n1, *n2; n1 = numeric_arg(args); n2 = numeric_arg(cdr(args)); if (NOT_THROWING) { return torf(compare_numnodes(n1, n2) < 0); } return(UNBOUND); } NODE *llessequalp(NODE *args) { NODE *n1, *n2; n1 = numeric_arg(args); n2 = numeric_arg(cdr(args)); if (NOT_THROWING) { return torf(compare_numnodes(n1, n2) <= 0); } return(UNBOUND); } NODE *lgreaterp(NODE *args) { NODE *n1, *n2; n1 = numeric_arg(args); n2 = numeric_arg(cdr(args)); if (NOT_THROWING) { return torf(compare_numnodes(n1, n2) > 0); } return(UNBOUND); } NODE *lgreaterequalp(NODE *args) { NODE *n1, *n2; n1 = numeric_arg(args); n2 = numeric_arg(cdr(args)); if (NOT_THROWING) { return torf(compare_numnodes(n1, n2) >= 0); } return(UNBOUND); } int compare_node(NODE *n1, NODE *n2, BOOLEAN ignorecase) { NODE *a1 = NIL, *a2 = NIL, *nn1 = NIL, *nn2 = NIL; int icmp = 0, cmp_len; NODETYPES nt1, nt2; if (n1 == n2) return 0; nt1 = nodetype(n1); nt2 = nodetype(n2); if (!(nt1 & NT_WORD) || !(nt2 & NT_WORD)) return -9999; if (nt1==QUOTE && is_list(node__quote(n1))) return -9999; if (nt2==QUOTE && is_list(node__quote(n2))) return -9999; if (nt1 == CASEOBJ && nt2 == CASEOBJ && ignorecase && (object__caseobj(n1) == object__caseobj(n2))) return 0; if ((nt1 & NT_NUMBER) && (nt2 & NT_NUMBER)) return compare_numnodes(n1, n2); if (nt1 & NT_NUMBER) { nn2 = cnv_node_to_numnode(n2); if (nn2 != UNBOUND) { icmp = compare_numnodes(n1, nn2); return icmp; } } if (nt2 & NT_NUMBER) { nn1 = cnv_node_to_numnode(n1); if (nn1 != UNBOUND) { icmp = compare_numnodes(nn1, n2); return icmp; } } a1 = cnv_node_to_strnode(n1); a2 = cnv_node_to_strnode(n2); nt1 = nodetype(a1); nt2 = nodetype(a2); if (nt1 == STRING && nt2 == STRING) { if (getstrptr(a1) == getstrptr(a2)) icmp = getstrlen(a1) - getstrlen(a2); else { cmp_len = (getstrlen(a1) > getstrlen(a2)) ? getstrlen(a2) : getstrlen(a1); if (ignorecase) icmp = low_strncmp(getstrptr(a1), getstrptr(a2), cmp_len); else icmp = strncmp(getstrptr(a1), getstrptr(a2), cmp_len); if (icmp == 0) icmp = getstrlen(a1) - getstrlen(a2); } } else if (nt1 & NT_BACKSL || nt2 & NT_BACKSL) { if (getstrptr(a1) == getstrptr(a2)) icmp = getstrlen(a1) - getstrlen(a2); else { cmp_len = (getstrlen(a1) > getstrlen(a2)) ? getstrlen(a2) : getstrlen(a1); if (ignorecase) icmp = noparitylow_strncmp(getstrptr(a1), getstrptr(a2), cmp_len); else icmp = noparity_strncmp(getstrptr(a1), getstrptr(a2), cmp_len); if (icmp == 0) icmp = getstrlen(a1) - getstrlen(a2); } } else err_logo(FATAL, NIL); return(icmp); } BOOLEAN equalp_help(NODE *arg1, NODE *arg2, BOOLEAN ignc) { if (is_list(arg1)) { if (!is_list(arg2)) return FALSE; while (arg1 != NIL && arg2 != NIL) { if (!equalp_help(car(arg1), car(arg2), ignc)) return FALSE; arg1 = cdr(arg1); arg2 = cdr(arg2); if (check_throwing) break; } return (arg1 == NIL && arg2 == NIL); } else if (is_list(arg2)) return FALSE; else if (nodetype(arg1) == ARRAY) { if (nodetype(arg2) != ARRAY) return FALSE; return (arg1 == arg2); } else if (nodetype(arg2) == ARRAY) return FALSE; else return (!compare_node(arg1, arg2, ignc)); } NODE *lequalp(NODE *args) { NODE *arg1, *arg2; BOOLEAN val; arg1 = car(args); arg2 = cadr(args); if (varTrue(Caseignoredp)) val = equalp_help(arg1, arg2, TRUE); else val = equalp_help(arg1, arg2, FALSE); return(torf(val)); } NODE *lnotequalp(NODE *args) { NODE *arg1, *arg2; BOOLEAN val; arg1 = car(args); arg2 = cadr(args); if (varTrue(Caseignoredp)) val = equalp_help(arg1, arg2, TRUE); else val = equalp_help(arg1, arg2, FALSE); return(torf(!val)); } NODE *l_eq(NODE *args) { return torf(car(args) == cadr(args)); } NODE *lbeforep(NODE *args) { NODE *arg1, *arg2; int val; arg1 = string_arg(args); arg2 = string_arg(cdr(args)); if (varTrue(Caseignoredp)) val = compare_node(arg1, arg2, TRUE); else val = compare_node(arg1, arg2, FALSE); return (val < 0 ? TrueName() : FalseName()); } ucblogo-5.5/mem.c0100644000161300001330000004630010216225572011657 0ustar bhdoe/* * mem.c logo memory management module dvb 6/28/88 * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" extern NODE *stack, *numstack, *exp, *val, *parm, *catch_tag, *arg; /* #ifdef ibm */ /* #ifndef __RZTC__ */ /* #include */ /* #endif */ /* #endif */ #ifdef PUNY #define GCMAX 1000 #else #ifdef THINK_C #define GCMAX 8000 #else #ifdef __RZTC__ #define GCMAX 3000 #else #define GCMAX 16000 #endif #endif #endif #ifdef THINK_C extern NODE *gcstack[]; #else NODE *gcstack[GCMAX]; #endif NODE **mark_gcstack = gcstack; NODE **gctop = gcstack; NODE **gcbottom = gcstack; long int mem_nodes = 0, mem_max = 0; /* for Logo NODES primitive */ /* GC heuristic parameters. These parameters can be modified to fine tune the performance of the GC program. The values below are a good set of default parameters that should work well for most data */ /* Number of times to collect at the current GC state before going to the next state. Basically the number of times a given generation is collected before its members are moved to an older generation */ #define gc_age_threshold 4 FIXNUM seg_size = SEG_SIZE; /* A new segment of nodes is added if fewer than freed_threshold nodes are freed in one GC run */ #define freed_threshold ((long int)(seg_size * 0.4)) NODE *free_list = NIL; /* global ptr to free node list */ struct segment *segment_list = NULL; /* global ptr to segment list */ long int mem_allocated = 0, mem_freed = 0; /* The number of generations */ #define NUM_GENS 4 /* ptr to list of Nodes in the same generation */ NODE *generation[NUM_GENS] = {NIL}; /* ptr to list of nodes that point to younger nodes */ NODE *oldyoungs = NIL; long int current_gc = 0; long int gc_stack_malloced = 0; long int gc_stack_size = GCMAX; long int gc_overflow_flag = 0; NODE *reserve_tank = NIL; BOOLEAN inside_gc = 0, int_during_gc = 0; int next_gen_gc = 0, max_gen = 0; int mark_gen_gc; /* #define GC_DEBUG 1 /* */ #ifdef GC_DEBUG long int num_examined; #endif NODE *lsetsegsz(NODE *args) { NODE *num = pos_int_arg(args); if (NOT_THROWING) seg_size = getint(num); return UNBOUND; } BOOLEAN addseg(void) { long int p; struct segment *newseg; if ((newseg = (struct segment *)malloc(sizeof(struct segment) + seg_size*sizeof(struct logo_node))) != NULL) { newseg->next = segment_list; newseg->size = seg_size; segment_list = newseg; for (p = 0; p < seg_size; p++) { newseg->nodes[p].next = free_list; free_list = &newseg->nodes[p]; settype(&newseg->nodes[p], NTFREE); } return 1; } else return 0; } #ifdef THINK_C #pragma options(!global_optimizer) #endif #ifdef WIN32 #pragma optimize("",off) #endif /* Think C tries to load ptr_val->node_type early if optimized */ BOOLEAN valid_pointer (volatile NODE *ptr_val) { struct segment* current_seg; unsigned long int ptr = (unsigned long int)ptr_val; FIXNUM size; if (ptr_val == NIL) return 0; for (current_seg = segment_list; current_seg != NULL; current_seg = current_seg->next) { size = current_seg->size; if ((ptr >= (unsigned long int)¤t_seg->nodes[0]) && (ptr <= (unsigned long int)¤t_seg->nodes[size-1]) && ((ptr - (unsigned long int)¤t_seg->nodes[0])% (sizeof(struct logo_node)) == 0)) return (ptr_val->node_type != NTFREE); } return 0; } #ifdef THINK_C #pragma options(global_optimizer) #endif #ifdef WIN32 /* #pragma optimize("",on) */ #endif NODETYPES nodetype(NODE *nd) { if (nd == NIL) return (PNIL); return(nd->node_type); } void check_oldyoung(NODE *old, NODE *new) { if (valid_pointer(new) && (new->my_gen < old->my_gen) && old->oldyoung_next == NIL) { old->oldyoung_next = oldyoungs; oldyoungs = old; } } void check_valid_oldyoung(NODE *old, NODE *new) { if (new == NIL) return; if ((new->my_gen < old->my_gen) && old->oldyoung_next == NIL) { old->oldyoung_next = oldyoungs; oldyoungs = old; } } /* setcar/cdr/object should be called only when the new pointee is really * a node. Otherwise just directly assign to the field (e.g. for CONTs). */ void setobject(NODE *nd, NODE *newobj) { nd->n_obj = newobj; check_valid_oldyoung(nd, newobj); } void setcar(NODE *nd, NODE *newcar) { nd->n_car = newcar; check_valid_oldyoung(nd, newcar); } void setcdr(NODE *nd, NODE *newcdr) { nd->n_cdr = newcdr; check_valid_oldyoung(nd, newcdr); } #ifdef THINK_C #pragma options(honor_register) #endif #ifdef WIN32 #pragma optimize("",off) #endif void do_gc(BOOLEAN full) { register NODE *pa, *pb, *pc, *pd, *pe; /* get registers onto stack */ register int aa, bb, cc, dd, ee; int_during_gc = 0; inside_gc++; gc(full); inside_gc = 0; if (int_during_gc != 0) { delayed_int(); } } NODE *newnode(NODETYPES type) { register NODE *newnd; static NODE phony; while ((newnd = free_list) == NIL && NOT_THROWING) { do_gc(FALSE); } if (newnd != NIL) { free_list = newnd->next; newnd->n_car = NIL; newnd->n_cdr = NIL; newnd->n_obj = NIL; newnd->my_gen = 0; newnd->gen_age = gc_age_threshold; newnd->mark_gc = 0; newnd->next = generation[0]; generation[0] = newnd; newnd->oldyoung_next = NIL; settype(newnd, type); mem_nodes++; if (mem_nodes > mem_max) mem_max = mem_nodes; return(newnd); } else return &phony; } #ifdef THINK_C #pragma options(!honor_register) #endif #ifdef WIN32 /* #pragma optimize("",on) */ #endif NODE *cons(NODE *x, NODE *y) { NODE *val = newnode(CONS); /* New node can't possibly point to younger one, so no need to check */ val->n_car = x; val->n_cdr = y; return(val); } #define mmark(child) {if ((child)->my_gen < nd->my_gen) \ {mark(child); got_young++;}} NODE **inter_gen_mark (NODE **prev) { /* Mark/traverse pointers to younger generations only */ NODE* nd = *prev; NODE** array_ptr; NODE* tmp_node; int loop; int got_young = 0; if (nd->my_gen <= mark_gen_gc) return &(nd->oldyoung_next); switch (nodetype(nd)) { case CONS: case CASEOBJ: case RUN_PARSE: case QUOTE: case COLON: case TREE: case LINE: case LOCALSAVE: if (valid_pointer(nd->n_car)) mmark(nd->n_car); if (valid_pointer(nd->n_obj)) mmark(nd->n_obj); case CONT: if (valid_pointer(nd->n_cdr)) mmark(nd->n_cdr); break; case STACK: if (valid_pointer(nd->n_cdr)) mmark(nd->n_cdr); array_ptr = (NODE **)car(nd); loop = num_saved_nodes; while (--loop >= 0) { tmp_node = *array_ptr++; if (valid_pointer(tmp_node)) mmark(tmp_node); } break; case ARRAY: array_ptr = getarrptr(nd); loop = getarrdim(nd); while (--loop >= 0) { tmp_node = *array_ptr++; if (valid_pointer(tmp_node)) mmark(tmp_node); } break; } if (!got_young) { /* nd no longer points to younger */ *prev = nd->oldyoung_next; nd->oldyoung_next = NIL; return prev; } return &(nd->oldyoung_next); } void gc_inc () { NODE **new_gcstack; long int loop; if (gc_overflow_flag == 1) return; if (gctop == &mark_gcstack[gc_stack_size-1]) gctop = mark_gcstack; else gctop++; if (gctop == gcbottom) { /* gc STACK overflow */ #ifdef GC_DEBUG printf("\nAllocating new GC stack\n"); if (dribblestream != NULL) fprintf(dribblestream,"\nAllocating new GC stack\n"); #endif if ((new_gcstack = (NODE**) malloc ((size_t) sizeof(NODE *) * (gc_stack_size + GCMAX))) == NULL) { /* no room to increse GC Stack */ ndprintf(stdout, "\n%t\n", message_texts[CANT_GC]); ndprintf(stdout, "%t\n", message_texts[EXIT_NOW]); gc_overflow_flag = 1; } else { /* transfer old stack to new stack */ new_gcstack[0] = *gcbottom; if (gcbottom == &mark_gcstack[gc_stack_size-1]) gcbottom = mark_gcstack; else gcbottom++; for (loop = 1 ; gcbottom != gctop ; loop++) { new_gcstack[loop] = *gcbottom; if (gcbottom == &mark_gcstack[gc_stack_size-1]) gcbottom = mark_gcstack; else gcbottom++; } gc_stack_size = gc_stack_size + GCMAX; if (gc_stack_malloced == 1) free(mark_gcstack); gc_stack_malloced = 1; mark_gcstack = new_gcstack; gctop = &mark_gcstack[loop]; gcbottom = mark_gcstack; } } } /* Iterative mark procedure */ void mark(NODE* nd) { int loop; NODE** array_ptr; if (gc_overflow_flag == 1) return; if (!valid_pointer(nd)) return; /* NIL pointer */ if (nd->my_gen > mark_gen_gc) return; /* I'm too old */ if (nd->mark_gc == current_gc) return; /* I'm already marked */ *gctop = nd; gc_inc(); while (gcbottom != gctop) { nd = *gcbottom; if ((valid_pointer(nd)) && (nd->my_gen <= mark_gen_gc) && (nd->mark_gc != current_gc)) { if (nd->mark_gc == -1) { nd->mark_gc = 0; /* this is a caseobj during gctwa */ goto no_mark; /* so don't really mark yet */ } nd->mark_gc = current_gc; #ifdef GC_DEBUG num_examined++; #endif switch (nodetype(nd)) { case CONS: case CASEOBJ: case RUN_PARSE: case QUOTE: case COLON: case TREE: case LINE: case LOCALSAVE: *gctop = nd->n_car; gc_inc(); *gctop = nd->n_obj; gc_inc(); case CONT: *gctop = nd->n_cdr; gc_inc(); break; case STACK: *gctop = nd->n_cdr; gc_inc(); array_ptr = (NODE **)car(nd); loop = num_saved_nodes; while (--loop >= 0) { *gctop = *array_ptr++; gc_inc(); } break; case ARRAY: array_ptr = getarrptr(nd); loop = getarrdim(nd); while (--loop >= 0) { *gctop = *array_ptr++; gc_inc(); } break; } } no_mark: if (gcbottom == &mark_gcstack[gc_stack_size-1]) gcbottom = mark_gcstack; else gcbottom++; } } void gc(BOOLEAN no_error) { NODE *top; NODE **top_stack; NODE *nd, *tmpnd; long int num_freed = 0; NODE **tmp_ptr, **prev; long int freed_sofar = 0; NODE** array_ptr; NODE* tmp_node; NODE *obj, *caselist; int anygood; int i; short int loop; int gen_gc; /* deepest generation to garbage collect */ int gctwa; /* garbage collect truly worthless atoms */ if (gc_overflow_flag == 1) { if (!addseg()) { err_logo(OUT_OF_MEM, NIL); if (free_list == NIL) err_logo(OUT_OF_MEM_UNREC, NIL); } return; } check_throwing; top_stack = ⊤ mark_gen_gc = gen_gc = (no_error ? max_gen : next_gen_gc); gctwa = (gen_gc == max_gen && max_gen > 1) || no_error; if (gctwa) { /* Every caseobj must be marked twice to count */ for (loop = 0; loop < HASH_LEN ; loop++) { for (nd = hash_table[loop]; nd != NIL; nd = cdr(nd)) { tmpnd = caselist__object(car(nd)); while (tmpnd != NIL) { (car(tmpnd))->mark_gc = -1; tmpnd = cdr(tmpnd); } } } } re_mark: current_gc++; #ifdef GC_DEBUG printf("gen = %d\n", gen_gc); if (dribblestream != NULL) fprintf(dribblestream,"gen = %d\n", gen_gc); num_examined = 0; #endif /* Begin Mark Phase */ /* Check globals for NODE pointers */ mark(Regs_Node); mark(stack); mark(numstack); mark(exp); mark(val); mark(parm); mark(catch_tag); mark(arg); mark(var_stack); mark(last_call); mark(output_node); mark(output_unode); mark(throw_node); mark(err_mesg); mark(current_line); /* mark(fun); mark(ufun); mark(last_ufun); mark(this_line); mark(last_line); mark(var); mark(didnt_output_name); mark(didnt_get_output); mark(qm_list); */ mark(file_list); mark(reader_name); mark(writer_name); mark(file_prefix); mark(the_generation); mark(Not_Enough_Node); mark(Unbound); mark(Listvalue); mark(Dotsvalue); mark(cnt_list); mark(cnt_last); mark(deepend_proc_name); #ifdef GC_DEBUG printf("globals %ld + ", num_examined); if (dribblestream != NULL) fprintf(dribblestream,"globals %ld + ", num_examined); num_examined = 0; #endif for (loop = 0; loop < HASH_LEN ; loop++) mark(hash_table[loop]); #ifdef GC_DEBUG printf("oblist %ld + ", num_examined); if (dribblestream != NULL) fprintf(dribblestream,"oblist %ld + ", num_examined); num_examined = 0; #endif /* Check Stack for NODE pointers */ if (top_stack < bottom_stack) { /* check direction stack grows */ for (tmp_ptr = top_stack; tmp_ptr <= bottom_stack; #if defined(THINK_C) || defined(__RZTC__) tmp_ptr = (NODE **)(((unsigned long int)tmp_ptr)+2) #else tmp_ptr++ #endif ) { if (valid_pointer(*tmp_ptr)) { mark(*tmp_ptr); } } } else { for (tmp_ptr = top_stack; tmp_ptr >= bottom_stack; #if defined(THINK_C) || defined(__RZTC__) tmp_ptr = (NODE **)(((unsigned long int)tmp_ptr)-2) #else tmp_ptr-- #endif ) { if (valid_pointer(*tmp_ptr)) { mark(*tmp_ptr); } } } #ifdef GC_DEBUG printf("stack %ld + ", num_examined); if (dribblestream != NULL) fprintf(dribblestream,"stack %ld + ", num_examined); num_examined = 0; #endif /* check pointers from old generations to young */ for (prev = &oldyoungs; *prev != Unbound; prev = inter_gen_mark(prev)) ; #ifdef GC_DEBUG printf("inter_gen %ld marked\n", num_examined); if (dribblestream != NULL) fprintf(dribblestream,"inter_gen %ld marked\n", num_examined); num_examined = 0; #endif if (gc_overflow_flag) return; if (gctwa) { #ifdef GC_DEBUG printf("GCTWA: "); if (dribblestream != NULL) fprintf(dribblestream,"GCTWA: "); num_examined = 0; #endif for (loop = 0; loop < HASH_LEN ; loop++) { tmpnd = NIL; for (nd = hash_table[loop]; nd != NIL; nd = cdr(nd)) { obj = car(nd); if (procnode__object(obj) == UNDEFINED && valnode__object(obj) == UNBOUND && plist__object(obj) == NIL && !flag__object(obj, PERMANENT)) { #ifdef GC_DEBUG num_examined++; #endif anygood = 0; for (caselist = caselist__object(obj); caselist != NIL; caselist = cdr(caselist)) { if ((car(caselist))->mark_gc == current_gc) { anygood = 1; break; } } if (anygood) { /* someone points here, don't gctwa */ tmpnd = nd; } else { /* do gctwa */ if (tmpnd == NIL) hash_table[loop] = cdr(hash_table[loop]); else setcdr(tmpnd, cdr(nd)); } } else /* has a value, don't gctwa */ tmpnd = nd; } } #ifdef GC_DEBUG printf("%ld collected\n", num_examined); if (dribblestream != NULL) fprintf(dribblestream,"%ld collected\n", num_examined); num_examined = 0; #endif gctwa = 0; goto re_mark; } /* Begin Sweep Phase */ for (loop = gen_gc; loop >= 0; loop--) { tmp_ptr = &generation[loop]; for (nd = generation[loop]; nd != NIL; nd = *tmp_ptr) { if (nd->mark_gc == current_gc) { if (--(nd->gen_age) == 0 && loop < NUM_GENS-1) { /* promote to next gen */ *tmp_ptr = nd->next; nd->next = generation[loop+1]; generation[loop+1] = nd; nd->my_gen = loop+1; if (max_gen == loop) max_gen++; nd->gen_age = gc_age_threshold; switch (nodetype(nd)) { case CONS: case CASEOBJ: case RUN_PARSE: case QUOTE: case COLON: case TREE: case LINE: case LOCALSAVE: check_oldyoung(nd, nd->n_car); check_oldyoung(nd, nd->n_obj); case CONT: check_oldyoung(nd, nd->n_cdr); break; case STACK: check_oldyoung(nd, nd->n_cdr); array_ptr = (NODE **)car(nd); i = num_saved_nodes; while (--i >= 0) { tmp_node = *array_ptr++; check_oldyoung(nd, tmp_node); } break; case ARRAY: array_ptr = getarrptr(nd); i = getarrdim(nd); while (--i >= 0) { tmp_node = *array_ptr++; check_oldyoung(nd, tmp_node); } break; } } else { /* keep in this gen */ tmp_ptr = &(nd->next); } } else { /* free */ num_freed++; mem_nodes--; *tmp_ptr = nd->next; if (nd->oldyoung_next != NIL) { for (prev = &oldyoungs; *prev != nd; prev = &((*prev)->oldyoung_next)) ; *prev = nd->oldyoung_next; nd->oldyoung_next = NIL; } switch (nodetype(nd)) { case ARRAY: free((char *)getarrptr(nd)); break; case STACK: free((char *)car(nd)); break; case STRING: case BACKSLASH_STRING: case VBAR_STRING: if (getstrhead(nd) != NULL && decstrrefcnt(getstrhead(nd)) == 0) free(getstrhead(nd)); break; } settype (nd, NTFREE); nd->next = free_list; free_list = nd; } } #ifdef GC_DEBUG printf("%ld + ", num_freed - freed_sofar); if (dribblestream != NULL) fprintf(dribblestream,"%ld + ", num_freed - freed_sofar); #endif freed_sofar = num_freed; } #ifdef GC_DEBUG printf("= %ld freed\n", num_freed); if (dribblestream != NULL) fprintf(dribblestream,"= %ld freed\n", num_freed); #endif if (num_freed > freed_threshold) next_gen_gc = 0; else if (gen_gc < max_gen) next_gen_gc = gen_gc+1; else next_gen_gc = 0; if (num_freed < freed_threshold) { if (!addseg() && num_freed < 50 && gen_gc == max_gen && !no_error) { err_logo(OUT_OF_MEM, NIL); if (free_list == NIL) err_logo(OUT_OF_MEM_UNREC, NIL); } #ifdef __RZTC__ (void)addseg(); #endif } #ifdef GC_DEBUG /* getchar(); */ #endif } #ifdef GC_DEBUG void prname(NODE *foo) { ndprintf(stdout, "%s ", car(foo)); if (dribblestream != NULL) fprintf(dribblestream, "%s ", car(foo)); } #endif NODE *lgc(NODE *args) { do_gc(args != NIL); return UNBOUND; } NODE *lnodes(NODE *args) { long int temp_max, temp_nodes; #ifdef GC_DEBUG /* map_oblist(&prname); */ #endif do_gc(TRUE); /* get real in-use figures */ temp_max = mem_max; temp_nodes = mem_nodes; mem_max = mem_nodes; return cons(make_intnode(temp_nodes), cons(make_intnode(temp_max), NIL)); } void fill_reserve_tank(void) { NODE *newnd, *p = NIL; int i = 50; while (--i >= 0) { /* make pairs not in any generation */ if ((newnd = free_list) == NIL) break; free_list = newnd->next; settype(newnd, CONS); newnd->n_car = NIL; newnd->n_cdr = p; newnd->n_obj = NIL; newnd->next = NIL; newnd->oldyoung_next = NIL; p = newnd; } reserve_tank = p; } void use_reserve_tank(void) { NODE *nd = reserve_tank; reserve_tank = NIL; for ( ; nd != NIL; nd = cdr(nd) ) { settype(nd, NTFREE); nd->next = free_list; free_list = nd; } } void check_reserve_tank(void) { if (reserve_tank == NIL) fill_reserve_tank(); } ucblogo-5.5/nographics.c0100644000161300001330000000026210274565220013234 0ustar bhdoe /* A dummy graphics implementation for Unix */ #ifdef X_DISPLAY_MISSING int pw, ph, pc, pm, pv, px, py, bg; char *LogoPlatformName="Unix-Nographics"; void nop() { } #endif ucblogo-5.5/nographics.h0100644000161300001330000000472207550417002013243 0ustar bhdoe /* A dummy graphics header file for computers without graphics */ #define GR_SIZE 1 #define prepare_to_draw nop() #define done_drawing nop() #define prepare_to_draw_turtle nop() #define done_drawing_turtle nop() #define screen_left 1 #define screen_right 100 #define screen_top 1 #define screen_bottom 100 #define screen_height (1 + screen_bottom - screen_top) #define screen_width (1 + screen_right - screen_left) #define screen_x_center (screen_left + (screen_width)/2) #define screen_y_center (screen_top + (screen_height)/2) #define turtle_left_max ((screen_left) - (screen_x_center)) #define turtle_right_max ((screen_right) - (screen_x_center)) #define turtle_top_max ((screen_y_center) - (screen_top)) #define turtle_bottom_max ((screen_y_center) - (screen_bottom)) #define screen_x_coord ((screen_x_center) + turtle_x) #define screen_y_coord ((screen_y_center) - turtle_y) #define turtle_height 18 #define turtle_half_bottom 6.0 #define turtle_side 19.0 #define clear_screen nop() #define line_to(x,y) nop() #define move_to(x,y) nop() #define draw_string(s) nop() #define set_pen_vis(v) nop() #define set_pen_mode(m) nop() #define set_pen_color(c) nop() #define set_pen_width(w) nop() #define set_pen_height(h) nop() #define set_pen_x(x) nop() #define set_pen_y(y) nop() #define set_back_ground(c) nop() /* pen_info is a stucture type with fields for the various pen characteristics including the location, size, color, mode (e.g. XOR or COPY), pattern, visibility (0 = visible) */ typedef struct { int dummy; } pen_info; #define p_info_x(p) p.dummy #define p_info_y(p) p.dummy #define pen_width pw #define pen_height ph #define pen_color pc #define pen_mode pm #define pen_vis pv #define pen_x px #define pen_y py #define get_node_pen_pattern make_intnode(0) #define back_ground bg #define pen_reverse nop() #define pen_erase nop() #define pen_down nop() #define button FALSE #define mouse_x 0 #define mouse_y 0 #define full_screen nop() #define split_screen nop() #define text_screen nop() #define save_pen(p) nop() #define restore_pen(p) nop() #define plain_xor_pen() nop() #define label(s) nop() #define tone(p,d) nop() #define get_pen_pattern(p) nop() #define set_pen_pattern(p) nop() #define fmod(x,y) x #define set_list_pen_pattern(p) nop() #define prepare_to_draw_turtle nop(); #define done_drawing_turtle nop(); extern int pw, ph, pc, pm, pv, px, py, bg; extern void nop(); #define logofill nop #define set_palette nop #define get_palette nop #define erase_screen nop ucblogo-5.5/paren.c0100644000161300001330000002634310275714064012217 0ustar bhdoe/* * paren.c logo parenthesizing module dko * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" #include NODE *the_generation; /* Set the line pointer for a tree. */ void make_line(NODE *tree, NODE *line) { setobject(tree, line); settype(tree, LINE); } void untreeify(NODE *node) { settreepair__tree(node, NIL); settype(node, CONS); } void untreeify_line(NODE *line) { if (line != NIL && is_list(line)) { untreeify_line(car(line)); untreeify_line(cdr(line)); untreeify(line); } } void untreeify_body(NODE *body) { NODE *body_ptr; for (body_ptr = body; body_ptr != NIL; body_ptr = cdr(body_ptr)) { untreeify_line(car(body_ptr)); } untreeify(body); } void untreeify_proc(NODE *tproc) { untreeify_body(bodylist__procnode(tproc)); } /* Treeify a body by appending the trees of the lines. */ void make_tree_from_body(NODE *body) { NODE *body_ptr, *end_ptr = NIL, *tree = NIL; if (body == NIL || (is_tree(body) && generation__tree(body) == the_generation)) return; if (is_tree(body)) untreeify_body(body); for (body_ptr = body; body_ptr != NIL; body_ptr = cdr(body_ptr)) { tree = car(body_ptr); if (tree == NIL) continue; /* skip blank line */ this_line = tree; make_tree(tree); if (is_tree(tree)) { tree = tree__tree(tree); make_line(tree, car(body_ptr)); if (end_ptr == NIL) settree__tree(body, tree); else setcdr(end_ptr, tree); if (generation__tree(car(body_ptr)) == UNBOUND) setgeneration__tree(body, UNBOUND); /* untreeify(car(body_ptr)); */ while (cdr(tree) != NIL) tree = cdr(tree); end_ptr = tree; } else { /* error while treeifying */ untreeify(body); return; } } settype(body, TREE); } NODE *tree_dk_how; /* Treeify a list of tokens (runparsed or not). */ void make_tree(NODE *list) { NODE *tree = NIL; NODE *paren_line(NODE *); if (list == NIL || (is_tree(list) && generation__tree(list) == the_generation)) return; if (!runparsed(list)) make_runparse(list); tree_dk_how = NIL; tree = paren_line(parsed__runparse(list)); if (tree != NIL && tree != UNBOUND) { settype(list, TREE); settree__tree(list, tree); if (tree_dk_how != NIL || stopping_flag==THROWING) setgeneration__tree(list, UNBOUND); } } NODE *gather_args(NODE *, NODE *, NODE **, BOOLEAN, NODE **); NODE *paren_infix(NODE *, NODE **, int, BOOLEAN); NODE *gather_some_args(int, int, NODE **, BOOLEAN, NODE **); /* Fully parenthesize a complete line, i.e. transform it from a flat list * to a tree. */ NODE *paren_line(NODE *line) { NODE *retval = NIL; NODE *paren_expr(NODE **expr, BOOLEAN inparen); NODE *paren_infix(NODE *left, NODE **rest, int old_pri, BOOLEAN inparen); if (line == NIL) return line; retval = paren_expr(&line, FALSE); if (NOT_THROWING && retval != UNBOUND) { retval = paren_infix(retval, &line, -1, FALSE); retval = cons(retval, paren_line(line)); } return retval; } /* See if an unknown procedure name starts with SET */ int is_setter(NODE *name) { NODE *string = cnv_node_to_strnode(name); if (getstrlen(string) < 4) return FALSE; return !low_strncmp(getstrptr(string), "set", 3); } /* Check for FD100, give warning, insert space */ NODE *missing_alphabetic, *missing_numeric; int missing_space(NODE *name) { NODE *str = strnode__caseobj(name); char *s = getstrptr(str); FIXNUM len = getstrlen(str); char *t; char ch; char alpha[100], numer[100]; int i; NODE *first; t = s+len-1; ch = *t; if (!isdigit(ch)) return 0; i = 1; while ((t>s) && (isdigit(*--t))) i++; if (t<=s) return 0; strncpy(numer,t+1,i); numer[i] = '\0'; strncpy(alpha,s,len-i); alpha[len-i] = '\0'; first = intern(make_strnode(alpha, 0, len-i, STRING, strnzcpy)); if (procnode__caseobj(first) == UNDEFINED && NOT_THROWING) silent_load(first, NULL); /* try ./.lg */ if (procnode__caseobj(first) == UNDEFINED && NOT_THROWING) silent_load(first, logolib); /* try / */ if (procnode__caseobj(first) == UNDEFINED) return 0; missing_alphabetic = first; missing_numeric = make_intnode(atoi(numer)); err_logo(MISSING_SPACE, cons_list(0, cons_list(0, missing_alphabetic, missing_numeric, END_OF_LIST), name, END_OF_LIST)); return 1; } /* Parenthesize an expression. Set expr to the node after the first full * expression. */ NODE *paren_expr(NODE **expr, BOOLEAN inparen) { NODE *first = NIL, *tree = NIL, *pproc, *retval; NODE **ifnode = (NODE **)NIL; if (*expr == NIL) { if (inparen) err_logo(PAREN_MISMATCH, NIL); return *expr; } first = car(*expr); pop(*expr); if (nodetype(first) == CASEOBJ && !numberp(first)) { if (first == Left_Paren) { tree = paren_expr(expr, TRUE); tree = paren_infix(tree, expr, -1, TRUE); if (*expr == NIL) err_logo(PAREN_MISMATCH, NIL); else if (car(*expr) != Right_Paren) { int parens; tree_dk_how=UNBOUND; /* throw the rest away */ for (parens = 0; *expr; pop(*expr)) { if (car(*expr) == Left_Paren) parens++; else if (car(*expr) == Right_Paren) if (parens-- == 0) { pop(*expr); break; } } first = car(tree); tree = cons(Not_Enough_Node, NIL); /* tell eval */ err_logo(TOO_MUCH, first); } else pop(*expr); retval = tree; } else if (first == Right_Paren) { err_logo(UNEXPECTED_PAREN, NIL); if (inparen) push(first, *expr); retval = NIL; } else if (first == Minus_Sign) { push(Minus_Tight, *expr); retval = paren_infix(make_intnode((FIXNUM) 0), expr, -1, inparen); } else { /* it must be a procedure */ if (procnode__caseobj(first) == UNDEFINED && NOT_THROWING && first != Null_Word) silent_load(first, NULL); /* try ./.lg */ if (procnode__caseobj(first) == UNDEFINED && NOT_THROWING && first != Null_Word) silent_load(first, logolib); /* try / */ pproc = procnode__caseobj(first); if (pproc == UNDEFINED) { if (missing_space(first)) { push(missing_numeric, *expr); first = missing_alphabetic; pproc = procnode__caseobj(first); retval = gather_args(first, pproc, expr, inparen, ifnode); if (retval != UNBOUND) { retval = cons(first, retval); } } else if (is_setter(first)) { retval = gather_some_args(0, 1, expr, inparen, ifnode); if (retval != UNBOUND) { retval = cons(first, retval); } } else { retval = cons(first, NIL); tree_dk_how = first; } } else if (nodetype(pproc) == INFIX && NOT_THROWING) { err_logo(NOT_ENOUGH, first); retval = cons(first, NIL); } else { /* Kludge follows to turn IF to IFELSE sometimes. */ if (isName(first, Name_if)) { ifnode = &first; } retval = gather_args(first, pproc, expr, inparen, ifnode); if (retval != UNBOUND) { retval = cons(first, retval); } } } } else if (is_list(first)) { /* quoted list */ retval = make_quote(first); } else { return first; } return retval; } /* Gather the correct number of arguments to proc into a list. Set args to * immediately after the last arg. */ NODE *gather_args(NODE *newfun, NODE *pproc, NODE **args, BOOLEAN inparen, NODE **ifnode) { int min, max; NODE /* *oldfun, */ *result; if (nodetype(pproc) == CONS) { min = (inparen ? getint(minargs__procnode(pproc)) : getint(dfltargs__procnode(pproc))); max = (inparen ? getint(maxargs__procnode(pproc)) : getint(dfltargs__procnode(pproc))); } else { /* primitive */ min = (inparen ? getprimmin(pproc) : getprimdflt(pproc)); if (min < 0) { /* special form */ result = *args; *args = NIL; return result; /* oldfun = fun; fun = newfun; result = (*getprimfun(pproc))(*args); fun = oldfun; return result; */ } /* Kludge follows to allow EDIT and CO without input without paren */ if (getprimmin(pproc) == OK_NO_ARG) min = 0; max = (inparen ? getprimmax(pproc) : getprimdflt(pproc)); } return gather_some_args(min, max, args, inparen, ifnode); } /* Make a list of the next n expressions, where n is between min and max. * Set args to immediately after the last expression. */ NODE *gather_some_args(int min, int max, NODE **args, BOOLEAN inparen, NODE **ifnode) { NODE *paren_infix(NODE *left, NODE **rest, int old_pri, BOOLEAN inparen); if (*args == NIL || car(*args) == Right_Paren || (nodetype(car(*args)) == CASEOBJ && nodetype(procnode__caseobj(car(*args))) == INFIX)) { if (min > 0) return cons(Not_Enough_Node, NIL); } else if (max == 0) { if (ifnode != (NODE **)NIL && is_list(car(*args))) { /* if -> ifelse kludge */ NODE *retval; err_logo(IF_WARNING, NIL); *ifnode = theName(Name_ifelse); retval = paren_expr(args, FALSE); retval = paren_infix(retval, args, -1, inparen); return cons(retval, gather_some_args(min, max, args, inparen, (NODE **)NIL)); } } else { if (max < 0) max = 0; /* negative max means unlimited */ if (car(*args) != Right_Paren && (nodetype(car(*args)) != CASEOBJ || nodetype(procnode__caseobj(car(*args))) != INFIX)) { NODE *retval = paren_expr(args, FALSE); retval = paren_infix(retval, args, -1, inparen); return cons(retval, gather_some_args(min - 1, max - 1, args, inparen, ifnode)); } } return NIL; } /* Calculate the priority of a procedure. */ int priority(NODE *proc_obj) { NODE *pproc; if (proc_obj == Minus_Tight) return PREFIX_PRIORITY+4; if (nodetype(proc_obj) != CASEOBJ || (pproc = procnode__caseobj(proc_obj)) == UNDEFINED || nodetype(pproc) != INFIX) return 0; return getprimpri(pproc); } /* Parenthesize an infix expression. left_arg is the expression on the left * (already parenthesized), and rest is a pointer to the list starting with the * infix procedure, if it's there. Set rest to after the right end of the * infix expression. */ NODE *paren_infix(NODE *left_arg, NODE **rest, int old_pri, BOOLEAN inparen) { NODE *infix_proc, *retval; int pri; if (*rest == NIL || !(pri = priority(infix_proc = car(*rest))) || pri <= old_pri) return left_arg; pop(*rest); retval = paren_expr(rest, inparen); retval = paren_infix(retval, rest, pri, inparen); retval = cons_list(0,infix_proc, left_arg, retval, END_OF_LIST); return paren_infix(retval, rest, old_pri, inparen); } ucblogo-5.5/print.c0100644000161300001330000002172407666723026012254 0ustar bhdoe/* * print.c logo printing module dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "logo.h" #include "globals.h" #include int print_stringlen; char *print_stringptr; int force_printwidth = -1, force_printdepth = -1; int x_margin=0, y_margin=0; void real_print_node(FILE *, NODE *, int, int); #ifdef mac BOOLEAN boldmode = 0; #endif void update_coords(char ch) { int i; #ifdef ibm #if !defined(__RZTC__) && !defined(_MSC_VER) && !defined(WIN32) check_scroll(); #endif #endif if (ch == '\n') { x_coord = 0; y_coord++; for (i = 0; i < x_margin; i++) print_char(stdout,' '); } else if (ch == '\b') { if (x_coord > 0) --x_coord; } else if (ch == '\t') { x_coord &= ~07; x_coord += 8; #ifdef WIN32 } else if (ch == '\1' || ch == '\2') { #endif } else if (ch != '\007') x_coord++; if (x_coord > x_max) { y_coord += x_coord/x_max; x_coord %= x_max; } if (y_coord > y_max) y_coord = y_max; } void print_char(FILE *strm, char ch) { if (strm != NULL) { if (interactive && strm==stdout) { #ifdef mac if (boldmode) { if (ch == '\2') boldmode = 0; else ch = ch | 0200; /* Not so good in Europe */ } else if (ch == '\1') boldmode = 1; #endif #ifdef ibm if (ch == '\1') ibm_bold_mode(); if (ch == '\2') ibm_plain_mode(); #if defined(__RZTC__) && !defined(WIN32) /* sowings */ ztc_put_char(ch); #elif defined(TURBO_C) if (in_graphics_mode && ibm_screen_top == 0) lsplitscreen(); if (ch == '\n' || in_graphics_mode) rd_putc(ch, strm); else if (ch != '\1' && ch != '\2') rd_putc(ch, stdout); /* takes advantage of bold attribute */ #else /* WIN32 */ if (ch != '\1' && ch != '\2') rd_putc(ch, strm); #endif /* ibm */ #else /* Unix */ rd_putc(ch, strm); #endif } else /* printing to stream but not screen */ rd_putc(ch, strm); if (strm == stdout) { if (dribblestream != NULL) rd_putc(ch, dribblestream); update_coords(ch); } } else { /* printing to string */ if (--print_stringlen > 0) *print_stringptr++ = ch; } } void print_space(FILE *strm) { print_char(strm,' '); } /*VARARGS2*/ void ndprintf(FILE *strm, char *fmt, ...) { va_list ap; NODE *nd, *ahead_node = UNBOUND, *next_ahead_node = UNBOUND; char *cp; char ch; va_start(ap,fmt); while ((ch = *fmt++) != '\0') { if (ch == '%') { ahead_node = next_ahead_node; next_ahead_node = UNBOUND; ch = *fmt++; if (ch == '+') { /* swap arg order in error message */ next_ahead_node = va_arg(ap,NODE *); ch = *fmt++; } if (ch == 's') { /* show */ if (ahead_node != UNBOUND) { nd = ahead_node; ahead_node = UNBOUND; } else nd = va_arg(ap,NODE *); print_node(strm, nd); } else if (ch == 'p') { /* print */ if (ahead_node != UNBOUND) { nd = ahead_node; ahead_node = UNBOUND; } else nd = va_arg(ap,NODE *); if (is_list(nd)) print_help(strm,nd); else print_node(strm,nd); } else if (ch == 't') { /* text */ cp = va_arg(ap,char *); while ((ch = *cp++) != '\0') print_char(strm,ch); } else { print_char(strm,'%'); print_char(strm,ch); } } else if (ch == '\\') { ch = *fmt++; if (ch == 'n') { print_char(strm, '\n'); } else { print_char(strm, '\\'); print_char(strm, ch); } } else print_char(strm,ch); } /* if (!strm) print_char(strm,'\0'); */ if (!strm) *print_stringptr = '\0'; va_end(ap); force_printwidth = force_printdepth = -1; } void dbprint(NODE *data) { ndprintf(stdout, "%p\n", data); } void real_print_help(FILE *strm, NODE *ndlist, int depth, int width) { NODE *arg = NIL; int wid = width; while (ndlist != NIL) { if (!is_list(ndlist)) { ndprintf(strm, " . %s", ndlist); return; } arg = car(ndlist); ndlist = cdr(ndlist); if (check_throwing) break; real_print_node(strm, arg, depth, width); if (ndlist != NIL) { print_space(strm); if (--wid == 0) { ndprintf(strm, "..."); break; } } } } void real_print_node(FILE *strm, NODE *nd, int depth, int width) { int i; char *cp; NODETYPES ndty; BOOLEAN print_backslashes = (varTrue(Fullprintp)); if (depth == 0) { ndprintf(strm, "..."); return; } if (nd == NIL) { print_char(strm,'['); print_char(strm,']'); } else if (nd == UNBOUND) { ndprintf(strm, "%s", theName(Name_nothing)); } else if ((unsigned int)nd < 200) { /* for debugging */ char num[] = "{small} "; sprintf(&num[7],"%d",nd); ndprintf(strm,num); } else if ((ndty = nodetype(nd)) & NT_PRIM) { ndprintf(strm, "PRIM"); } else if (ndty == CONT) { ndprintf(strm, "[ %s]", cons(make_intnode((FIXNUM)car(nd)), cdr(nd))); } else if (ndty & NT_LIST) { print_char(strm,'['); real_print_help(strm, nd, depth-1, width); print_char(strm,']'); } else if (ndty == ARRAY) { int i = 0, dim = getarrdim(nd), wid; NODE **pp = getarrptr(nd); if (width < 0) wid = dim; else wid = (dim > width ? width : dim); print_char(strm,'{'); while (i < wid) { real_print_node(strm,*pp++,depth-1,width); if (++i < dim) print_space(strm); } if (wid < dim) ndprintf(strm, "..."); print_char(strm,'}'); if (print_backslashes && (getarrorg(nd) != 1)) { char org[] = "@ "; sprintf(&org[1],"%d",getarrorg(nd)); ndprintf(strm,org); } } else if (ndty == QUOTE) { print_char(strm, '\"'); print_node(strm, car(nd)); } else if (ndty == COLON) { print_char(strm, ':'); print_node(strm, car(nd)); #ifdef OBJECTS } else if (ndty == OBJECT) { NODE *old_obj = current_object; NODE *printform; current_object = nd; /* printform = val_eval_driver(cons(theName(Name_representation), NIL)); */ printform = lrepresentation(NIL); current_object = old_obj; real_print_node(strm, printform, depth, width); #endif } else if (print_backslashes && (nd == Null_Word)) { ndprintf(strm, "||"); } else { int wid, dots=0; nd = cnv_node_to_strnode(nd); cp = getstrptr(nd); if (width < 0) wid = getstrlen(nd); else { wid = (width < 10 ? 10 : width); wid = (wid < getstrlen(nd) ? wid : getstrlen(nd)); } if (wid < getstrlen(nd)) dots++; if (!backslashed(nd)) for (i = 0; i < wid; i++) { print_char(strm,*cp++); } else if (print_backslashes == FALSE) { for (i = 0; i < wid; i++) { print_char(strm,clearparity(*cp++)); } } else { for (i = 0; i < wid; i++) { if (getparity(cp[i])) break; } if (i < wid) { /* word was in vbars */ if (strchr("\":", *cp)) { print_char(strm, *cp++); wid--; } print_char(strm,'|'); for (i = 0; i < wid; i++) { print_char(strm,clearparity(*cp++)); } print_char(strm,'|'); } else for (i = 0; i < wid; i++) { if (strchr(special_chars,(int)*cp)) { print_char(strm,'\\'); } print_char(strm,*cp++); } }; if (dots) ndprintf(strm, "..."); } } int find_limit(NODE *nd, int forced) { int val = -1; if (forced >= 0) return forced; if (nd == NIL) return(-1); nd = cnv_node_to_numnode(valnode__caseobj(nd)); if (nodetype(nd) == INT) val = getint(nd); return(val); } void print_help(FILE *strm, NODE *nd) { real_print_help(strm, nd, find_limit(Printdepthlimit, force_printdepth), find_limit(Printwidthlimit, force_printwidth)); } void print_node(FILE *strm, NODE *nd) { real_print_node(strm, nd, find_limit(Printdepthlimit, force_printdepth), find_limit(Printwidthlimit, force_printwidth)); } void print_nobrak(FILE *strm, NODE *nd) { if (is_list(nd)) print_help(strm, nd); else print_node(strm, nd); } void new_line(FILE *strm) { print_char(strm,'\n'); } NODE *lshow(NODE *args) { print_help(writestream, args); new_line(writestream); return(UNBOUND); } void type_help(NODE *args, int sp) { NODE *arg = NIL; while (args != NIL) { arg = car(args); args = cdr(args); if (is_list(arg)) print_help(writestream, arg); else print_node(writestream, arg); if (sp && (args != NIL)) { print_space(writestream); } } } NODE *ltype(NODE *args) { type_help(args,0); return(UNBOUND); } NODE *lprint(NODE *args) { type_help(args,1); new_line(writestream); return(UNBOUND); } ucblogo-5.5/term.c0100644000161300001330000001450010270277024012044 0ustar bhdoe/* * term.c terminal cursor control dvb * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "logo.h" #include "globals.h" #ifdef HAVE_UNISTD_H #include #endif #ifdef mac #include #endif #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif #undef TRUE #undef FALSE #ifdef HAVE_TERMCAP_H #include #else #ifdef HAVE_TERMLIB_H #include #else #ifdef HAVE_CURSES_H #include #endif #endif #endif #undef TRUE #undef FALSE #define FALSE 0 #define TRUE 1 int x_coord, y_coord, x_max, y_max; char PC; char *BC; char *UP; short ospeed; char bp[1024]; char cl_arr[40]; char cm_arr[40]; char so_arr[40]; char se_arr[40]; #ifdef HAVE_TERMIO_H struct termio tty_cooked, tty_cbreak; #else #ifdef HAVE_SGTTY_H struct sgttyb tty_cooked, tty_cbreak; #endif #endif int interactive, tty_charmode; extern char **environ, *tgoto(), *tgetstr(); char *termcap_ptr; int termcap_putter(char ch) { *termcap_ptr++ = ch; return 0; } #ifdef unix void termcap_getter(char *cap, char *buf) { char temp[40]; char *str; char *temp_ptr = temp; termcap_ptr = buf; str=tgetstr(cap,&temp_ptr); /* if (str == NULL) str = temp; */ tputs(str,1,termcap_putter); } #endif void term_init(void) { #ifdef unix char *emacs; /* emacs change */ int term_sg; #endif #ifdef WIN32 interactive = 1; #else interactive = isatty(0); #endif #ifdef mac term_init_mac(); return; #else #ifdef ibm #ifndef WIN32 term_init_ibm(); #endif /* WIN32 */ #else if (interactive) { #ifdef HAVE_TERMIO_H ioctl(0,TCGETA,(char *)(&tty_cooked)); tty_cbreak = tty_cooked; tty_cbreak.c_cc[VMIN] = '\01'; tty_cbreak.c_cc[VTIME] = '\0'; tty_cbreak.c_lflag &= ~(ECHO|ICANON); #else ioctl(0,TIOCGETP,(char *)(&tty_cooked)); tty_cbreak = tty_cooked; tty_cbreak.sg_flags |= CBREAK; tty_cbreak.sg_flags &= ~ECHO; #endif } tty_charmode = 0; tgetent(bp, getenv("TERM")); /* emacs changes */ emacs = getenv("EMACS"); /* check if started from emacs */ if (!emacs || *emacs != 't') { /* read from termcap */ x_max = tgetnum("co"); y_max = tgetnum("li"); } else { /* read environment variables */ emacs = getenv("COLUMNS"); if (!emacs) x_max = 0; else x_max = atoi(emacs); emacs = getenv("LINES"); if (!emacs) y_max = 0; else y_max = atoi(emacs); } /* end emacs changes */ if (x_max <= 0) x_max = 80; if (y_max <= 0) y_max = 24; term_sg = tgetnum("sg"); x_coord = y_coord = 0; termcap_getter("cm", cm_arr); termcap_getter("cl", cl_arr); if (term_sg <= 0) { termcap_getter("so", so_arr); termcap_getter("se", se_arr); } else /* don't mess with stupid standout modes */ so_arr[0] = se_arr[0] = '\0'; #endif #endif } void charmode_on() { #ifdef unix if ((readstream == stdin) && interactive && !tty_charmode) { #ifdef HAVE_TERMIO_H ioctl(0,TCSETA,(char *)(&tty_cbreak)); #else /* !HAVE_TERMIO_H */ ioctl(0,TIOCSETP,(char *)(&tty_cbreak)); #endif /* HAVE_TERMIO_H */ tty_charmode++; } #endif /* unix */ #ifdef WIN32 win32_charmode_on(); #endif } void charmode_off() { #ifdef unix if (tty_charmode) { #ifdef HAVE_TERMIO_H ioctl(0,TCSETA,(char *)(&tty_cooked)); #else /* !HAVE_TERMIO_H */ ioctl(0,TIOCSETP,(char *)(&tty_cooked)); #endif /* HAVE_TERMIO_H */ tty_charmode = 0; } #endif /* unix */ #ifdef WIN32 win32_charmode_off(); #endif } NODE *lcleartext(NODE *args) { #ifdef mac cgotoxy(x_margin + 1, y_margin + 1, stdout); ccleos(stdout); #else #ifdef ibm #ifndef WIN32 /* sowings */ ibm_clear_text(); ibm_gotoxy(x_margin, y_margin); #else /* WIN32 */ win32_clear_text(); #endif /* WIN32 || !Win32 */ #else /* !ibm */ printf("%s", cl_arr); printf("%s", tgoto(cm_arr, x_margin, y_margin)); #endif /* ibm */ #endif /* mac */ #ifdef WIN32 win32_update_text(); #else fflush(stdout); /* do it now! */ #endif #if defined(__RZTC__) zflush(); #endif x_coord = x_margin; y_coord = y_margin; return(UNBOUND); } NODE *lcursor(NODE *args) { return(cons(make_intnode((FIXNUM)(x_coord-x_margin)), cons(make_intnode((FIXNUM)(y_coord-y_margin)), NIL))); } NODE *lsetcursor(NODE *args) { #ifdef WIN32 return (win32_lsetcursor(args)); #else /* !win32 */ NODE *arg; arg = pos_int_vector_arg(args); if (NOT_THROWING) { x_coord = x_margin + getint(car(arg)); y_coord = y_margin + getint(cadr(arg)); while ((x_coord >= x_max || y_coord >= y_max) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); if (NOT_THROWING) { arg = pos_int_vector_arg(args); x_coord = x_margin + getint(car(arg)); y_coord = y_margin + getint(cadr(arg)); } } } if (NOT_THROWING) { #ifdef mac mac_gotoxy(x_coord, y_coord); #else #ifdef ibm ibm_gotoxy(x_coord, y_coord); #else printf("%s", tgoto(cm_arr, x_coord, y_coord)); #endif #endif fflush(stdout); #ifdef __RZTC__ zflush(); #endif } return(UNBOUND); #endif /* !win32 (for non-windows version of this code) */ } NODE *lsetmargins(NODE *args) { NODE *arg; arg = pos_int_vector_arg(args); if (NOT_THROWING) { x_margin = getint(car(arg)); y_margin = getint(cadr(arg)); lcleartext(NIL); } return(UNBOUND); } NODE *lstandout(NODE *args) { char textbuf[300]; char fmtbuf[100]; sprintf(fmtbuf,"%s%%p%s",so_arr,se_arr); print_stringptr = textbuf; print_stringlen = 300; ndprintf((FILE *)NULL,fmtbuf,car(args)); *print_stringptr = '\0'; return(make_strnode(textbuf,NULL,(int)strlen(textbuf),STRING,strnzcpy)); } ucblogo-5.5/win32trm.c0100644000161300001330000011551310275756235012603 0ustar bhdoe/* -*-C-*- * win32trm.c -- Module to provide Win32 API compliant graphics routines * * Copyright (C) 1996 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "logo.h" #include "globals.h" #include "win32trm.h" #include "ucbwlogo/resource.h" // #define WIN32_S LRESULT CALLBACK ParentWindowFunc(HWND, UINT, WPARAM, LPARAM); char szWinName[] = "UCBLogo"; char szGraphWinName[] = "UCBLogoGraph"; char szConWinName[] = "UCBLogoConsole"; char *LogoPlatformName="Windows"; pen_info turtlePen; HBRUSH hbrush, textbrush; HBITMAP hbitG, hbitmG, hbitC, hbitmC; RECT allRect; HDC GraphDC, memGraphDC, ConDC, memConDC; HWND hGraphWnd, hConWnd, hMainWnd; /* color and palette related information */ static COLORREF palette[266]; FIXNUM back_ground, pen_color, old_pen_color; int maxX, maxY, greeted = 0; int pre_turtle_pen_mode; long Xsofar, Ysofar; int w_button = 0; FIXNUM mouse_x = 0, mouse_y = 0; BOOLEAN in_erase_mode, update_pos, seen_once = FALSE; int in_graphics_mode, in_splitscreen; static char **win32_lines; // for recording what should appear in the text win static char input_lines[2][200]; char *read_line, buffered_char; int cur_line = 0, cur_index = 0, read_index, hpos = 0, margin, cur_len; int char_mode = 0, input_line = 0, input_index = 0; int line_avail = FALSE, char_avail = FALSE; char *winPasteText = NULL, *winPastePtr = NULL; char *myScreen = NULL; int maxXChar, maxYChar; /* Default font behavior set here: OEM_FIXED_FONT, ANSI_FIXED_FONT, or default */ BOOLEAN oemfont = FALSE; BOOLEAN ansifont = TRUE; #ifdef WIN32_DEBUG void WinDebug(char *s) { ndprintf("%t", s); } #endif int win32_screen_right(void) { RECT r; GetClientRect(hMainWnd, &r); return (int) r.right; } int win32_screen_bottom(void) { RECT r; GetClientRect(hMainWnd, &r); return (int) r.bottom; } void moveto(int x, int y) { /* no invalidation of the rectangle, etc needs to be done. */ turtlePen.h = x; turtlePen.v = y; MoveCursor(x, y); } void lineto(int x, int y) { turtlePen.h = x; turtlePen.v = y; LineTo(memGraphDC, x, y); LineTo(GraphDC, x, y); /* Good old Windows does us the favor of leaving out the endpoint, so we have to beat it up */ LineTo(memGraphDC, x, y+1); LineTo(GraphDC, x, y+1); MoveCursor(x, y); } void win32_go_away(void) { int i; if (read_line != NULL) free(read_line); for (i = 0; i < NUM_LINES; i++) if (win32_lines[i] != NULL) free(win32_lines[i]); if (win32_lines != NULL) free(win32_lines); DeleteDC(memConDC); DeleteDC(memGraphDC); DeleteDC(GraphDC); DeleteDC(ConDC); DeleteObject(turtlePen.hpen); DeleteObject(hbrush); DeleteObject(textbrush); DeleteObject(hbitC); DeleteObject(hbitmC); DeleteObject(hbitG); DeleteObject(hbitmG); exit(0); } void win32_update_text(void) { RECT r; GetClientRect(hConWnd, &r); BitBlt(ConDC, 0, 0, r.right, r.bottom, memConDC, 0, 0, SRCCOPY); } void win32_repaint_screen(void) { PostMessage(hMainWnd, WM_SETFOCUS, 0, 0); } void win32_advance_line(void) { TEXTMETRIC tm; RECT r, inv, foo; int xpos, ypos; GetClientRect(hConWnd, &r); GetTextMetrics(memConDC, &tm); xpos = (tm.tmAveCharWidth * x_coord); ypos = ((tm.tmHeight + tm.tmExternalLeading) * y_coord); if ((ypos + 2 * (tm.tmHeight + tm.tmExternalLeading)) >= r.bottom) { memmove(myScreen, myScreen+maxXChar, maxXChar*(maxYChar-1)); ScrollDC(ConDC, 0, - (tm.tmHeight + tm.tmExternalLeading), &r, &r, NULL, &inv); FillRect(ConDC, &inv, textbrush); foo.left = 0; foo.right = Xsofar; foo.top = 0; foo.bottom = Ysofar; ScrollDC(memConDC, 0, - (tm.tmHeight + tm.tmExternalLeading), &foo, &foo, NULL, &inv); FillRect(memConDC, &inv, textbrush); } } void draw_string(char *str) { TEXTMETRIC tm; int x, y; GetTextMetrics(memGraphDC, &tm); x = turtlePen.h; y = turtlePen.v; TextOut(memGraphDC, x, y - tm.tmHeight, str, strlen(str)); TextOut(GraphDC, x, y - tm.tmHeight, str, strlen(str)); /* restore position */ moveto(x, y); } char *eight_dot_three_helper(char *in) { static char out[20]; char *filename, *extension; filename = strtok(in, "."); extension = strtok(NULL, "."); if (extension) sprintf(out, "%.8s.%.3s", filename, extension); else sprintf(out, "%.8s", filename); return out; } char *eight_dot_three(char *in) { static char out[100]; char *last, *last_sep, *fear; int index; if (last_sep = strrchr(in, '\\')) { index = last_sep - in; index++; strncpy(out, in, index); out[index] = '\0'; last = (char *)malloc((strlen(in) - index + 3) * sizeof(char)); strncpy(last, &in[index], strlen(in) - index); last[strlen(in) - index] = '\0'; } else if (last_sep = strrchr(in, ':')) { index = last_sep - in; index++; strncpy(out, in, index); out[index] = '\0'; last = (char *)malloc((strlen(in) - index + 3) * sizeof(char)); strncpy(last, &in[index], strlen(in) - index); last[strlen(in) - index] = '\0'; } for (fear = last; *fear != '\0'; fear++) if (*fear == '?') *fear = 'Q'; fear = eight_dot_three_helper(last); strcat(out, fear); free(last); return out; } void MoveCursor(int newx, int newy) { MoveToEx(memGraphDC, newx, newy, NULL); MoveToEx(GraphDC, newx, newy, NULL); } void win32_erase_screen(void) { PatBlt(memGraphDC, 0, 0, maxX, maxY, PATCOPY); PatBlt(GraphDC, 0, 0, maxX, maxY, PATCOPY); } void win32_set_bg(FIXNUM c) { /* * set global variables that denote the background color, create a new * brush with the desired color, repaint the memory context, wait for * WM_PAINT, and redraw the old display (using the records...) */ back_ground = c; hbrush = CreateSolidBrush(palette[back_ground+2]); SelectObject(memGraphDC, hbrush); DeleteObject(SelectObject(GraphDC, hbrush)); PatBlt(memGraphDC, 0, 0, maxX, maxY, PATCOPY); PatBlt(GraphDC, 0, 0, maxX, maxY, PATCOPY); SetBkColor(memGraphDC, palette[back_ground+2]); SetBkColor(GraphDC, palette[back_ground+2]); redraw_graphics(); } void win32_clear_text(void) { // RECT r; /* * Draw over the entire client area, so that in split screen mode, for * example, there are no ghosts, when the user returns to textscreen mode. */ // GetClientRect(hConWnd, &r); memset(myScreen, ' ',maxXChar*maxYChar); FillRect(ConDC, &allRect, textbrush); FillRect(memConDC, &allRect, textbrush); } LRESULT CALLBACK GraphWindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HFONT hfont; PAINTSTRUCT ps; switch (message) { case WM_CREATE: /* * Now, create a copy of the entire screen in memory to act as a virtual * window to record turtle motions so they can be repainted in a * WM_PAINT message. */ GraphDC = GetDC(hwnd); memGraphDC = CreateCompatibleDC(GraphDC); maxX = GetSystemMetrics(SM_CXSCREEN); maxY = GetSystemMetrics(SM_CYSCREEN); hbitmG = CreateCompatibleBitmap(GraphDC, maxX, maxY); SelectObject(memGraphDC, hbitmG); hbitG = CreateCompatibleBitmap(GraphDC, maxX, maxY); SelectObject(GraphDC, hbitG); if (oemfont) { hfont = GetStockObject(OEM_FIXED_FONT); SelectObject(memGraphDC, hfont); SelectObject(GraphDC, hfont); } if (ansifont) { hfont = GetStockObject(ANSI_FIXED_FONT); SelectObject(memGraphDC, hfont); SelectObject(GraphDC, hfont); } /* * first-time initialization of the brush for the background requires * setting the back_ground, and selecting the right color. while * there may be stock objects that contain the right color for the * initial pen/brush, subsequent changes might try to delete these * "stock" pens/brushes, and that would be "Bad". */ back_ground = 0; hbrush = CreateSolidBrush(palette[back_ground+2]); SetBkColor(memGraphDC, palette[back_ground+2]); SetBkColor(GraphDC, palette[back_ground+2]); SelectObject(memGraphDC, hbrush); SelectObject(GraphDC, hbrush); /* * first-time initialization of the pen structure requires setting up * all of the fields in the data first, then creating a new pen object */ turtlePen.h = 0; /* ?? */ turtlePen.v = 0; /* ?? */ turtlePen.vis = 0; turtlePen.mode = WIN_PEN_DOWN; turtlePen.width = 1; /* default */ turtlePen.color = pen_color = old_pen_color = 7; /* turtlePen.pattern = ... ? */ turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, palette[2+turtlePen.color]); SetTextColor(memGraphDC, palette[2+turtlePen.color]); SetTextColor(GraphDC, palette[2+turtlePen.color]); SelectObject(memGraphDC, turtlePen.hpen); SelectObject(GraphDC, turtlePen.hpen); PatBlt(memGraphDC, 0, 0, maxX, maxY, PATCOPY); PatBlt(GraphDC, 0, 0, maxX, maxY, PATCOPY); break; case WM_LBUTTONDOWN: w_button = 1; goto abutton; case WM_RBUTTONDOWN: w_button = 2; goto abutton; case WM_MBUTTONDOWN: w_button = 3; abutton: SetCapture(hwnd); case WM_MOUSEMOVE: mouse_x = (LOWORD(lParam))-(screen_width/2); mouse_y = (screen_height/2)-(HIWORD(lParam)); break; case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: w_button = 0; ReleaseCapture(); break; case WM_USER: InvalidateRect(hGraphWnd, NULL, 1); case WM_PAINT: BeginPaint(hGraphWnd, &ps); BitBlt(ps.hdc, 0, 0, maxX, maxY, memGraphDC, 0, 0, SRCCOPY); EndPaint(hGraphWnd, &ps); break; case WM_DESTROY: /* end program */ PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } void win32_text_cursor(void) { print_char(stdout, '_'); update_coords('\b'); } void DrawBoxOutline(POINT ptBeg, POINT ptEnd) { SetROP2(ConDC, R2_NOT); SelectObject(ConDC, GetStockObject(NULL_BRUSH)); Rectangle(ConDC, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y); } LRESULT CALLBACK ConsoleWindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HFONT hfont; PAINTSTRUCT ps; RECT rect; TEXTMETRIC tm; HGLOBAL hClipMemory, hCopyText; PSTR pClipMemory, copyText; static int fBlocking=FALSE, haveBlock=FALSE; static POINT ptBeg, ptEnd; static int chBegX, chBegY, chEndX, chEndY; char *copyPtr; int i,j; switch (message) { case WM_CREATE: ConDC = GetDC(hwnd); memConDC = CreateCompatibleDC(ConDC); allRect.left = allRect.top = 0; allRect.right = maxX = GetSystemMetrics(SM_CXSCREEN); allRect.bottom = maxY = GetSystemMetrics(SM_CYSCREEN); hbitmC = CreateCompatibleBitmap(ConDC, maxX, maxY); SelectObject(memConDC, hbitmC); hbitC = CreateCompatibleBitmap(ConDC, maxX, maxY); SelectObject(ConDC, hbitC); if (oemfont) { hfont = GetStockObject(OEM_FIXED_FONT); SelectObject(memConDC, hfont); SelectObject(ConDC, hfont); } if (ansifont) { hfont = GetStockObject(ANSI_FIXED_FONT); SelectObject(memConDC, hfont); SelectObject(ConDC, hfont); } textbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); SelectObject(memConDC, textbrush); SelectObject(ConDC, textbrush); FillRect(memConDC, &allRect, textbrush); GetClientRect(hConWnd, &rect); GetTextMetrics(ConDC, &tm); maxXChar = maxX / tm.tmAveCharWidth; maxYChar = maxY / (tm.tmHeight + tm.tmExternalLeading); myScreen = (char *)malloc(maxXChar * maxYChar); memset(myScreen, ' ',maxXChar*maxYChar); ibm_plain_mode(); break; case WM_LBUTTONDOWN: if (haveBlock) DrawBoxOutline(ptBeg, ptEnd); GetTextMetrics(memConDC, &tm); ptEnd.x = LOWORD(lParam); ptEnd.y = HIWORD(lParam); ptEnd.x = (ptEnd.x/tm.tmAveCharWidth) * tm.tmAveCharWidth; ptEnd.y = (ptEnd.y/(tm.tmHeight + tm.tmExternalLeading)) * (tm.tmHeight + tm.tmExternalLeading); ptBeg.x = ptEnd.x; ptBeg.y = ptEnd.y; DrawBoxOutline(ptBeg, ptEnd); SetCapture(hwnd); fBlocking = TRUE; haveBlock = FALSE; return 0; case WM_MOUSEMOVE: GetTextMetrics(memConDC, &tm); if (fBlocking) { DrawBoxOutline(ptBeg, ptEnd); ptEnd.x = LOWORD(lParam); ptEnd.y = HIWORD(lParam); ptEnd.x = (ptEnd.x/tm.tmAveCharWidth) * tm.tmAveCharWidth; ptEnd.y = (ptEnd.y/(tm.tmHeight + tm.tmExternalLeading)) * (tm.tmHeight + tm.tmExternalLeading); DrawBoxOutline(ptBeg, ptEnd); } return 0; case WM_LBUTTONUP: if (fBlocking) { ReleaseCapture(); fBlocking = FALSE; haveBlock=TRUE; GetClientRect(hConWnd, &rect); if (ptEnd.x >= 0 && ptEnd.y >= 0 && ptEnd.x < rect.right && ptEnd.y < rect.bottom) { GetTextMetrics(memConDC, &tm); chBegX = ptBeg.x/tm.tmAveCharWidth; chBegY = ptBeg.y/(tm.tmHeight + tm.tmExternalLeading); chEndX = ptEnd.x/tm.tmAveCharWidth; chEndY = ptEnd.y/(tm.tmHeight + tm.tmExternalLeading); } else { DrawBoxOutline(ptBeg, ptEnd); haveBlock = FALSE; } } return 0; case WM_CHAR: if (haveBlock) DrawBoxOutline(ptBeg, ptEnd); if (char_mode) { buffered_char = (char)wParam; char_avail++; haveBlock = FALSE; return 0; } print_space(stdout); // flush cursor update_coords('\b'); if ((char) wParam == '\b') { if (cur_index > 0) { update_coords('\b'); print_space(stdout); update_coords('\b'); win32_text_cursor(); cur_index--; } else { MessageBeep(0); haveBlock = FALSE; win32_lines[cur_line][cur_index++] = (char) wParam; print_char(stdout, (char) wParam); win32_text_cursor(); } } else if ((char) wParam == '\r') { // line ready, let's go! print_char(stdout, '\n'); haveBlock = FALSE; win32_lines[cur_line][cur_index++] = '\n'; // reader code expects \n win32_lines[cur_line][cur_index] = '\0'; cur_len = cur_index; read_line = (char *)malloc((strlen(win32_lines[cur_line]) + 1) * sizeof(char)); strncpy(read_line, win32_lines[cur_line], cur_index + 1); line_avail = 1; read_index = 0; if (++cur_line >= NUM_LINES) cur_line %= NUM_LINES; // wrap around cur_index = 0; return 0; } else if ((char)wParam == 17 || (char)wParam == 23) { haveBlock = FALSE; print_char(stdout, '\n'); read_line = (char *)malloc(sizeof(char)); *read_line = (char)wParam; line_avail = 1; read_index = 0; cur_index = 0; return 0; } else if ((char)wParam == 3 && haveBlock) { /* ^C for copy */ int temp; haveBlock = FALSE; if (chEndX < chBegX) { temp = chEndX; chEndX = chBegX; chBegX = temp; } if (chEndY < chBegY) { temp = chEndY; chEndY = chBegY; chBegY = temp; } hCopyText = GlobalAlloc(GHND, (chEndY-chBegY)*(2+chEndX-chBegX)+1); copyText = GlobalLock(hCopyText); copyPtr = copyText; for (i=chBegY; i= NUM_LINES) cur_line %= NUM_LINES; // wrap around cur_index = 0; return; } if (ch != 3 && ch != 22 && ch != '\n') { win32_lines[cur_line][cur_index++] = ch; print_char(stdout, ch); } ch = *winPastePtr++; } free(winPasteText); winPasteText = NULL; } NODE *win32_get_node_pen_pattern(void) { return cons(make_intnode(-1), NIL); } NODE *maximize(NODE *args) { int big=torf_arg(args); ShowWindow(hMainWnd, (big ? SW_MAXIMIZE : SW_RESTORE)); UpdateWindow(hMainWnd); return UNBOUND; } void logofill(void) { COLORREF col; hbrush = CreateSolidBrush(palette[2+pen_color]); SelectObject(memGraphDC, hbrush); DeleteObject(SelectObject(GraphDC, hbrush)); col = GetPixel(memGraphDC, g_round(screen_x_coord), g_round(screen_y_coord)); (void)ExtFloodFill(memGraphDC, g_round(screen_x_coord), g_round(screen_y_coord), col, FLOODFILLSURFACE); (void)ExtFloodFill(GraphDC, g_round(screen_x_coord), g_round(screen_y_coord), col, FLOODFILLSURFACE); hbrush = CreateSolidBrush(palette[2+back_ground]); SelectObject(memGraphDC, hbrush); DeleteObject(SelectObject(GraphDC, hbrush)); } void get_pen_pattern(void) { } void set_pen_pattern(void) { } void get_palette(int slot, unsigned int *r, unsigned int *g, unsigned int *b) { if (slot > 263 || (slot >= 0 && slot < 8) || slot < -2) // 256 rgb values return; slot+=2; *b = ((palette[slot % 264] & 0x00ff0000) >> 16) * 256; *g = ((palette[slot % 264] & 0x0000ff00) >> 8) * 256; *r = (palette[slot % 264] & 0x000000ff) * 256; } void set_palette(int slot, unsigned int r, unsigned int g, unsigned int b) { if (slot > 263 || (slot >= 0 && slot < 8) || slot < -2) // 256 rgb values return; slot+=2; palette[slot] = RGB(r/256, g/256, b/256); } void save_pen(pen_info *p) { POINT pt; p->vis = pen_vis; p->color = pen_color; GetCurrentPositionEx(memGraphDC, &pt); p->h = (int) pt.x; p->v = (int) pt.y; p->width = turtlePen.width; p->mode = turtlePen.mode; } void restore_pen(pen_info *p) { pen_vis = p->vis; MoveCursor(p->h, p->v); turtlePen.mode = p->mode; win32_set_pen_mode(turtlePen.mode); turtlePen.width = p->width; pen_color = p->color; turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, (in_erase_mode ? palette[2+back_ground] : palette[2+pen_color])); SelectObject(memGraphDC, turtlePen.hpen); DeleteObject(SelectObject(GraphDC, turtlePen.hpen)); } void set_list_pen_pattern(void) { } void label(char *str) { draw_string(str); } void plain_xor_pen(void) { win32_set_pen_mode(WIN_PEN_REVERSE); } BOOLEAN check_ibm_stop(void) { MSG msg; SHORT s; static int count; if ((s = GetAsyncKeyState(VK_CONTROL)) < 0) { if ((s = GetAsyncKeyState(65 + ('q' - 'a')) < 0)) { err_logo(STOP_ERROR,NIL); return (1); } if ((s = GetAsyncKeyState(65 + ('w' - 'a')) < 0)) { // control w to_pending = 0; lpause(NIL); } } count++; count %= 300; // empirical value if (!count) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) ; else { TranslateMessage(&msg); DispatchMessage(&msg); } } } return FALSE; } void win32_con_full_screen(void) { RECT r; PAINTSTRUCT ps; if (in_graphics_mode && !in_splitscreen) return; in_graphics_mode = 1; in_splitscreen = 0; GetClientRect(hMainWnd, &r); /* position coordinates are relative to the parent's frame. */ MoveWindow(hGraphWnd, 0, 0, r.right, r.bottom, TRUE); ShowWindow(hConWnd, SW_HIDE); ShowWindow(hGraphWnd, SW_SHOWNORMAL); BeginPaint(hGraphWnd, &ps); BitBlt(ps.hdc, 0, 0, maxX, maxY, memGraphDC, 0, 0, SRCCOPY); EndPaint(hGraphWnd, &ps); redraw_graphics(); } void win32_prepare_draw(void) { if (in_graphics_mode) return; win32_con_split_screen(); } long upscroll_text(int limit) { TEXTMETRIC tm; RECT r, inv; int y_new, offset, old, rbot; GetClientRect(hMainWnd, &r); GetTextMetrics(memConDC, &tm); y_new = r.bottom; y_new /= (tm.tmHeight + tm.tmExternalLeading); rbot = y_new * (tm.tmHeight + tm.tmExternalLeading); y_new--; if (limit > 0 && limit < y_new) { y_new = limit; rbot = r.bottom = (limit+1) * (tm.tmHeight + tm.tmExternalLeading); } offset = y_coord - y_new; if (offset > 0) { old = (y_coord + 1) * (tm.tmHeight + tm.tmExternalLeading); BitBlt(ConDC, 0, 0, maxX, maxY, memConDC, 0, old-rbot, SRCCOPY); inv.left = 0; inv.right = allRect.right; inv.top = rbot - 1; inv.bottom = allRect.bottom; BitBlt(memConDC, 0, 0, maxX, maxY, ConDC, 0, 0, SRCCOPY); FillRect(memConDC, &inv, textbrush); y_coord = y_new; } return r.bottom; } void reshow_text(void) { TEXTMETRIC tm; RECT r, foo; ShowWindow(hConWnd, SW_SHOW); GetClientRect(hConWnd, &r); GetTextMetrics(memConDC, &tm); FillRect(ConDC, &r, textbrush); if (r.right > Xsofar) { foo.left = Xsofar; foo.right = r.right; foo.top = 0; foo.bottom = allRect.bottom; FillRect(memConDC, &foo, textbrush); Xsofar = r.right; } if (r.bottom > Ysofar) { foo.left = 0; foo.right = r.right; foo.top = Ysofar; foo.bottom = r.bottom; FillRect(memConDC, &foo, textbrush); Ysofar = r.bottom; } BitBlt(ConDC, 0, 0, r.right, r.bottom, memConDC, 0, 0, SRCCOPY); ValidateRect(hConWnd, &r); x_max = r.right; x_max /= tm.tmAveCharWidth; x_max--; y_max = r.bottom; y_max /= (tm.tmHeight + tm.tmExternalLeading); y_max--; } void win32_con_split_screen(void) { RECT r; PAINTSTRUCT ps; long vert; if (in_graphics_mode && in_splitscreen) return; in_graphics_mode = in_splitscreen = 1; ShowWindow(hConWnd, SW_SHOW); vert = upscroll_text(3); GetClientRect(hMainWnd, &r); MoveWindow(hConWnd, 0, r.bottom - vert - 6, r.right, vert + 6, FALSE); MoveWindow(hGraphWnd, 0, 0, r.right, r.bottom - vert - 8, TRUE); ShowWindow(hGraphWnd, SW_HIDE); BeginPaint(hGraphWnd, &ps); BitBlt(ps.hdc, 0, 0, maxX, maxY, memGraphDC, 0, 0, SRCCOPY); EndPaint(hGraphWnd, &ps); reshow_text(); redraw_graphics(); ShowWindow(hGraphWnd, SW_SHOW); if (!seen_once) { seen_once = TRUE; lclearscreen(NIL); } } void win32_con_text_screen(void) { RECT r; if (!in_graphics_mode) return; in_graphics_mode = in_splitscreen = 0; (void)upscroll_text(0); GetClientRect(hMainWnd, &r); MoveWindow(hConWnd, 0, 0, r.right, r.bottom, FALSE); ShowWindow(hGraphWnd, SW_HIDE); reshow_text(); } void win32_turtle_prep(void) { if (in_erase_mode) { /* current pen color != "real" pen color */ turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, palette[2+pen_color]); SelectObject(memGraphDC, turtlePen.hpen); DeleteObject(SelectObject(GraphDC, turtlePen.hpen)); } else { SelectObject(memGraphDC, turtlePen.hpen); SelectObject(GraphDC, turtlePen.hpen); } update_pos = FALSE; pre_turtle_pen_mode = SetROP2(memGraphDC, R2_XORPEN); (void)SetROP2(GraphDC, R2_XORPEN); } void win32_turtle_end(void) { if (in_erase_mode) { /* * current pen color should now be set to background color to resume * "erase mode" */ turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, palette[2+back_ground]); SelectObject(memGraphDC, turtlePen.hpen); DeleteObject(SelectObject(GraphDC, turtlePen.hpen)); } else { SelectObject(memGraphDC, turtlePen.hpen); SelectObject(GraphDC, turtlePen.hpen); } update_pos = TRUE; SetROP2(memGraphDC, pre_turtle_pen_mode); SetROP2(GraphDC, pre_turtle_pen_mode); } void win32_init_palette(void) { palette[2] = RGB(0, 0, 0); /* black */ palette[3] = RGB(0, 0, 255); /* blue */ palette[4] = RGB(0, 255, 0); /* green */ palette[5] = RGB(0, 255, 255); /* cyan */ palette[6] = RGB(255, 0, 0); /* red */ palette[7] = RGB(255, 0, 255); /* magenta */ palette[8] = RGB(255, 255, 0); /* yellow */ palette[9] = RGB(255, 255, 255); /* white */ palette[10] = RGB(155, 96, 59); /* brown */ palette[11] = RGB(197, 136, 18); /* tan */ palette[12] = RGB(100, 162, 64); /* forest */ palette[13] = RGB(120, 187, 187); /* aqua */ palette[14] = RGB(255, 149, 119); /* salmon */ palette[15] = RGB(144, 113, 208); /* purple */ palette[16] = RGB(255, 163, 0); /* orange */ palette[17] = RGB(183, 183, 183); /* gray */ /* rest are user defined */ } void win32_set_pen_color(int c) { draw_turtle(); turtlePen.color = pen_color = c; if (!in_erase_mode) { turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, palette[2+turtlePen.color]); SelectObject(memGraphDC, turtlePen.hpen); DeleteObject(SelectObject(GraphDC, turtlePen.hpen)); } SetTextColor(memGraphDC, palette[2+pen_color]); SetTextColor(GraphDC, palette[2+pen_color]); draw_turtle(); } int win32_set_pen_width(int w) { int old; old = turtlePen.width; turtlePen.width = w; turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, (in_erase_mode ? palette[2+back_ground] : palette[2+turtlePen.color])); SelectObject(memGraphDC, turtlePen.hpen); DeleteObject(SelectObject(GraphDC, turtlePen.hpen)); return old; } NODE *win32_lsetcursor(NODE *args) { NODE *arg; TEXTMETRIC tm; int xpos, ypos; GetTextMetrics(memConDC, &tm); arg = pos_int_vector_arg(args); if (NOT_THROWING) { x_coord = x_margin + getint(car(arg)); y_coord = y_margin + getint(cadr(arg)); while ((x_coord >= x_max || y_coord >= y_max) && NOT_THROWING) { setcar(args, err_logo(BAD_DATA, arg)); if (NOT_THROWING) { arg = pos_int_vector_arg(args); x_coord = x_margin + getint(car(arg)); y_coord = y_margin + getint(cadr(arg)); } } } xpos = tm.tmAveCharWidth * x_coord; ypos = (tm.tmHeight + tm.tmExternalLeading) * y_coord; if (NOT_THROWING) { MoveToEx(memConDC, xpos, ypos, NULL); MoveToEx(ConDC, xpos, ypos, NULL); } return(UNBOUND); } void win32_pen_erase(void) { win32_set_pen_mode(WIN_PEN_ERASE); } void win32_pen_down(void) { win32_set_pen_mode(WIN_PEN_DOWN); } void win32_pen_reverse(void) { win32_set_pen_mode(WIN_PEN_REVERSE); } void win32_set_pen_mode(int newmode) { int rop2_mode, newpc; turtlePen.mode = newmode; if (newmode == WIN_PEN_ERASE) in_erase_mode = TRUE; else in_erase_mode = FALSE; if (newmode == WIN_PEN_REVERSE) rop2_mode = R2_XORPEN; else rop2_mode = R2_COPYPEN; SetROP2(memGraphDC, rop2_mode); SetROP2(GraphDC, rop2_mode); if (newmode == WIN_PEN_ERASE) newpc = back_ground; else newpc = pen_color; turtlePen.hpen = CreatePen(PS_SOLID, turtlePen.width, palette[2+newpc]); SelectObject(memGraphDC, turtlePen.hpen); DeleteObject(SelectObject(GraphDC, turtlePen.hpen)); } LRESULT CALLBACK ParentWindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT r; switch (message) { case WM_CHAR: SendMessage(hConWnd, WM_CHAR, wParam, lParam); break; case WM_SIZE: case WM_EXITSIZEMOVE: if (wParam != SIZE_MINIMIZED) { if (!in_graphics_mode) { // Text screen mode in_graphics_mode = 1; win32_con_text_screen(); } else if (in_splitscreen) { in_splitscreen = 0; win32_con_split_screen(); } else { in_graphics_mode = 0; win32_con_full_screen(); } } case WM_MOVE: case WM_SETFOCUS: case WM_EXITMENULOOP: if (!in_graphics_mode || in_splitscreen) SendMessage(hConWnd, WM_USER, wParam, lParam); if (in_graphics_mode) SendMessage(hGraphWnd, WM_USER, wParam, lParam); win32_update_text(); break; case WM_PAINT: /* * The parent window really has nothing to draw. Therefore, all that * the parent window's paint function does is dispatch the appropriate * message to the child window. */ if (!in_graphics_mode || in_splitscreen) SendMessage(hConWnd, WM_PAINT, wParam, lParam); if (in_graphics_mode) SendMessage(hGraphWnd, WM_PAINT, wParam, lParam); GetClientRect(hwnd, &r); ValidateRect(hwnd, &r); break; case WM_CREATE: hConWnd = CreateWindow(szConWinName, NULL, WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER, 0, 0, 0, 0, hwnd, (HMENU) (2 << 8), (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hGraphWnd = CreateWindow(szGraphWinName, NULL, WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER, 0, 0, 0, 0, hwnd, (HMENU) (4 << 8), (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); break; case WM_DESTROY: /* end program */ win32_go_away(); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } void CharOut(int c) { TEXTMETRIC tm; RECT r; int xpos, ypos; char nog[3]; sprintf(nog, "%c", c); if (x_coord < maxXChar && y_coord < maxYChar) myScreen[(y_coord * maxXChar) + x_coord] = c; GetTextMetrics(memConDC, &tm); xpos = tm.tmAveCharWidth * x_coord; ypos = (tm.tmHeight + tm.tmExternalLeading) * y_coord; r.left = xpos; r.right = (xpos + tm.tmAveCharWidth); r.top = ypos; r.bottom = (ypos + tm.tmHeight + tm.tmExternalLeading); TextOut(memConDC, xpos, ypos, nog, 1); TextOut(ConDC, xpos, ypos, nog, 1); } int win32_putc(int c, FILE *strm) { if (strm == stdout || strm == stderr) { if (c == '\n') win32_advance_line(); else if (c == '\t') /* do nothing */ ; else if (c == '\007') tone(400,30); else { if (x_coord == x_max) new_line(strm); CharOut(c); } return 0; } return putc(c, strm); } void win32_charmode_on(void) { char_mode = 1; } void win32_charmode_off(void) { char_mode = 0; } void ibm_bold_mode(void) { SetTextColor(memConDC, GetSysColor(COLOR_WINDOW)); SetTextColor(ConDC, GetSysColor(COLOR_WINDOW)); SetBkColor(memConDC, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(ConDC, GetSysColor(COLOR_WINDOWTEXT)); } void ibm_plain_mode(void) { SetTextColor(memConDC, GetSysColor(COLOR_WINDOWTEXT)); SetTextColor(ConDC, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(memConDC, GetSysColor(COLOR_WINDOW)); SetBkColor(ConDC, GetSysColor(COLOR_WINDOW)); } NODE *set_text_color(NODE *args) { int fore, back; fore = getint(pos_int_arg(args)); if (NOT_THROWING) { back = getint(pos_int_arg(cdr(args))); if (NOT_THROWING) { SetTextColor(memConDC, palette[2+fore]); SetTextColor(ConDC, palette[2+fore]); SetBkColor(memConDC, palette[2+back]); SetBkColor(ConDC, palette[2+back]); } } return UNBOUND; } /* Thanks to George Mills for the tone code! */ /* was: MessageBeep(0xffffffff); */ void tone(FIXNUM pitch, FIXNUM duration) { OSVERSIONINFO VersionInformation; unsigned char count_lo; unsigned char count_hi; FIXNUM count; clock_t NumTicksToWait; memset(&VersionInformation, 0, sizeof(OSVERSIONINFO)); VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (pitch < 37) pitch = 37; GetVersionEx(&VersionInformation); if (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT) Beep(pitch, duration); else { count = 1193180L / pitch; count_lo = LOBYTE(count); count_hi = HIBYTE(count); _asm { mov al, 0xB6 out 0x43, al mov al, count_lo out 0x42, al mov al, count_hi out 0x42, al xor al, al in al, 0x61 or al, 0x03 out 0x61, al } NumTicksToWait = duration + clock(); while (NumTicksToWait > clock()); _asm { xor al, al in al, 0x61 xor al, 0x03 out 0x61, al } } } ucblogo-5.5/usermanual0100644000161300001330000044042110276047421013037 0ustar bhdoeBerkeley Logo User Manual * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. This is a program that is still being written. Many things are missing, including adequate documentation. This manual assumes that you already know how to program in Logo, and merely presents the details of this new implementation. Read _Computer_Science_Logo_Style,_Volume_1:_ _Symbolic_Computing_ by Brian Harvey (MIT Press, 1997) for a tutorial on Logo programming with emphasis on symbolic computation. Here are the special features of this dialect of Logo: Source file compatible among Unix, DOS, Windows, and Mac platforms. Random-access arrays. Variable number of inputs to user-defined procedures. Mutators for list structure (dangerous). Pause on error, and other improvements to error handling. Comments and continuation lines; formatting is preserved when procedure definitions are saved or edited. Terrapin-style tokenization (e.g., [2+3] is a list with one member) but LCSI-style syntax (no special forms except TO). The best of both worlds. First-class instruction and expression templates (see APPLY). Macros. Features *not* found in Berkeley Logo include robotics, music, GUIs, animation, parallelism, and multimedia. For those, buy a commercial version. GETTER/SETTER VARIBLE SYNTAX ============================ Logo distinguishes PROCEDURES from VARIABLES. A procedure is a set of instructions to carry out some computation; a variable is a named container that holds a data value such as a number, word, list, or array. In traditional Logo syntax, a non-numeric word typed without punctuation represents a request to invoke the procedure named by that word. A word typed with a preceding quotation mark represents the word itself. For example, in the instruction PRINT FIRST "WORD the procedures named FIRST and PRINT are invoked, but the procedure named WORD is not invoked; the word W-O-R-D is the input to FIRST. What about variables? There are two things one can do with a variable: give it a value, and find out its value. To give a variable a value, Logo provides the primitive procedure MAKE, which requires two inputs: the name of the variable and the new value to be assigned. The first input, the name of the variable, is just a word, and if (as is almost always the case) the programmer wants to assign a value to a specific variable whose name is known in advance, that input is quoted, just as any known specific word would be: MAKE "MY.VAR FIRST "WORD gives the variable named MY.VAR the value W (the first letter of WORD). To find the value of a variable, Logo provides the primitive procedure THING, which takes a variable name as its input, and outputs the value of the accessible variable with that name. Thus PRINT THING "MY.VAR will print W (supposing the MAKE above has been done). Since finding the value of a specific, known variable name is such a common operation, Logo also provides an abbreviated notation that combines THING with quote: PRINT :MY.VAR The colon (which Logo old-timers pronounce "dots") replaces THING and " in the earlier version of the instruction. Newcomers to Logo often complain about the need for all this punctuation. In particular, Logo programmers who learned about dots and quotes without also learning about THING wonder why an instruction such as MAKE "NEW.VAR :OLD.VAR uses two different punctuation marks to identify the two variables. (Having read the paragraphs above, you will understand that actually both variable names are quoted, but the procedure THING is invoked to find the value of OLD.VAR, since it's that value, not OLD.VAR's name, that MAKE needs to know. It wouldn't make sense to ask for THING of NEW.VAR, since we haven't given NEW.VAR a value yet.) Although Logo's punctuation rules make sense once understood, they do form a barrier to entry for the Logo beginner. Why, then, couldn't Logo be designed so that an unpunctuated word would represent a procedure if there is a procedure by that name, or a variable if there is a variable by that name? Then we could say PRINT MY.VAR and Logo would realize that MY.VAR is the name of a variable, not of a procedure. The traditional reason not to use this convention is that Logo allows the same word to name a procedure and a variable at the same time. This is most often important for words that name data types, as in the following procedure: TO PLURAL :WORD OUTPUT WORD :WORD "S END Here the name WORD is a natural choice for the input to PLURAL, since it describes the kind of input that PLURAL expects. Within the procedure, we use WORD to represent Logo's primitive procedure that combines two input words to form a new, longer word; we use :WORD to represent the variable containing the input, whatever actual word is given when PLURAL is invoked. ? PRINT PLURAL "COMPUTER COMPUTERS However, if a Logo instruction includes an unquoted word that is *not* the name of a procedure, Logo could look for a variable of that name instead. This would allow a "punctuationless" Logo, ** PROVIDED THAT USERS WHO WANT TO WORK WITHOUT COLONS FOR VARIABLES CHOOSE VARIABLE NAMES THAT ARE NOT ALSO PROCEDURE NAMES. ** What about assigning a value to a variable? Could we do without the quotation mark on MAKE's first input? Alas, no. Although the first input to MAKE is *usually* a constant, known variable name, sometimes it isn't, as in this example: TO INCREMENT :VAR MAKE :VAR (THING :VAR)+1 ; Note: it's not "VAR here! END ? MAKE "X 5 ? INCREMENT "X ? PRINT :X 6 The procedure INCREMENT takes a variable name as its input and changes the value of that variable. In this example there are two variables; the variable whose name is VAR, and whose value is the word X; and the variable whose name is X and whose value changes from 5 to 6. Suppose we changed the behavior of MAKE so that it took the word after MAKE as the name of the variable to change; we would be unable to write INCREMENT: TO INCREMENT :VAR ; nonworking! MAKE VAR (THING VAR)+1 END This would assign a new value to VAR, not to X. What we can do is to allow an *alternative* to MAKE, a "setter" procedure for a particular variable. The notation will be ? SETFOO 7 ? PRINT FOO 7 SETFOO is a "setter procedure" that takes one input (in this case the input 7) and assigns its value to the variable named FOO. Berkeley Logo allows users to choose either the traditional notation, in which case the same name can be used both for a procedure and for a variable, or the getter/setter notation, in which variable FOO is set with SETFOO and examined with FOO, but the same name can't be used for procedure and variable. Here is how this choice is allowed: Berkeley Logo uses traditional notation, with procedures distinct from variables. However, if there is a variable named AllowGetSet whose value is TRUE (which there is, by default, when Logo starts up), then if a Logo instruction refers to a *nonexistent* procedure (so that the error message "I don't know how to ..." would result), Logo tries the following two steps: 1. If the name is at least four characters long, and the first three characters are the letters SET (upper or lower case), and if the name is followed in the instruction by another value, and if the name without the SET is the name of a variable that already exists, then Logo will invoke MAKE with its first input being the name without the SET, and its second input being the following value. 2. If step 1's conditions are not met, but the name is the name of an accessible variable, then Logo will invoke THING with that name as input, to find the variable's value. Step 1 requires that the variable already exist so that misspellings of names of SETxxx primitives (e.g., SETHEADING) will still be caught, instead of silently creating a new variable. The command GLOBAL can be used to create a variable without giving it a value. One final point: The TO command in Logo has always been a special case; the rest of the line starting with TO is not evaluated as ordinary Logo expressions are. In particular, the colons used to mark the names of inputs to the procedure do not cause THING to be invoked. They are merely mnemonic aids, reminding the Logo user that these words are names of variables. (Arguably, this nonstantard behavior of TO adds to Logo beginners' confusion about colons.) To a programmer using colonless variable references, the colons in the TO line are unnecessary and meaningless. Berkeley Logo therefore makes the colons optional: TO FOO :IN1 :IN2 and TO FOO IN1 IN2 are both allowed. ENTERING AND LEAVING LOGO ========================= The process to start Logo depends on your operating system: Unix: Type the word {\tt logo} to the shell. (The directory in which you've installed Logo must be in your path.) DOS: Change directories to the one containing Logo (probably C:\UCBLOGO). Then type UCBLOGO for the large memory version, or BL for the 640K version. Mac: Double-click on the LOGO icon within the "UCB Logo" folder. Windows: Double-click on the UCBWLOGO icon in the UCBLOGO folder. To leave Logo, enter the command "bye". After initialization, Logo looks for a file in the current working directory named startup.lg and, if one is found, executes the Logo instructions in it. Then, under Unix, DOS, or Windows, if you include one or more filenames on the command line when starting Logo, those files will be loaded before the interpreter starts reading commands from your terminal. If you load a file that executes some program that includes a "bye" command, Logo will run that program and exit. You can therefore write standalone programs in Logo and run them with shell/batch scripts. To support this technique, Logo does not print its usual welcoming and parting messages if you give file arguments to the logo command. If you type your interrupt character (see table below) Logo will stop what it's doing and return to toplevel, as if you did THROW "TOPLEVEL. If you type your quit character Logo will pause as if you did PAUSE. Unix DOS/Windows Mac toplevel usually ctrl-C ctrl-Q command-. (period) pause usually ctrl-\ ctrl-W command-, (comma) If you have an environment variable called LOGOLIB whose value is the name of a directory, then Logo will use that directory instead of the default library. If you invoke a procedure that has not been defined, Logo first looks for a file in the current directory named proc.lg where "proc" is the procedure name in lower case letters. If such a file exists, Logo loads that file. If the missing procedure is still undefined, or if there is no such file, Logo then looks in the library directory for a file named proc (no ".lg") and, if it exists, loads it. If neither file contains a definition for the procedure, then Logo signals an error. Several procedures that are primitive in most versions of Logo are included in the default library, so if you use a different library you may want to include some or all of the default library in it. TOKENIZATION ============ Names of procedures, variables, and property lists are case-insensitive. So are the special words END, TRUE, and FALSE. Case of letters is preserved in everything you type, however. Within square brackets, words are delimited only by spaces and square brackets. [2+3] is a list containing one word. Note, however, that the Logo primitives that interpret such a list as a Logo instruction or expression (RUN, IF, etc.) reparse the list as if it had not been typed inside brackets. After a quotation mark outside square brackets, a word is delimited by a space, a square bracket, or a parenthesis. A word not after a quotation mark or inside square brackets is delimited by a space, a bracket, a parenthesis, or an infix operator +-*/=<>. Note that words following colons are in this category. Note that quote and colon are not delimiters. Each infix operator character is a word in itself, except that the two-character sequences <= >= and <> (the latter meaning not-equal) with no intervening space are recognized as a single word. A word consisting of a question mark followed by a number (e.g., ?37), when runparsed (i.e., where a procedure name is expected), is treated as if it were the sequence ( ? 37 ) making the number an input to the ? procedure. (See the discussion of templates, below.) This special treatment does not apply to words read as data, to words with a non-number following the question mark, or if the question mark is backslashed. A line (an instruction line or one read by READLIST or READWORD) can be continued onto the following line if its last character is a tilde (~). READWORD preserves the tilde and the newline; READLIST does not. Lines read with READRAWLINE are never continued. An instruction line or a line read by READLIST (but not by READWORD) is automatically continued to the next line, as if ended with a tilde, if there are unmatched brackets, parentheses, braces, or vertical bars pending. However, it's an error if the continuation line contains only the word END; this is to prevent runaway procedure definitions. Lines eplicitly continued with a tilde avoid this restriction. If a line being typed interactively on the keyboard is continued, either with a tilde or automatically, Logo will display a tilde as a prompt character for the continuation line. A semicolon begins a comment in an instruction line. Logo ignores characters from the semicolon to the end of the line. A tilde as the last character still indicates a continuation line, but not a continuation of the comment. For example, typing the instruction print "abc;comment ~ def will print the word abcdef. Semicolon has no special meaning in data lines read by READWORD or READLIST, but such a line can later be reparsed using RUNPARSE and then comments will be recognized. The two-character sequence #! at the beginning of a line also starts a comment. Unix users can therefore write a file containing Logo commands, starting with the line #! /usr/local/bin/logo (or wherever your Logo executable lives) and the file will be executable directly from the shell. To include an otherwise delimiting character (including semicolon or tilde) in a word, precede it with backslash (\). If the last character of a line is a backslash, then the newline character following the backslash will be part of the last word on the line, and the line continues onto the following line. To include a backslash in a word, use \\. If the combination backslash-newline is entered at the terminal, Logo will issue a backslash as a prompt character for the continuation line. All of this applies to data lines read with READWORD or READLIST as well as to instruction lines. A character entered with backslash is EQUALP to the same character without the backslash, but can be distinguished by the BACKSLASHEDP predicate. (However, BACKSLASHEDP recgnizes backslashedness only on characters for which it is necessary: whitespace, parentheses, brackets, infix operators, backslash, vertical bar, tilde, quote, question mark, colon, and semicolon.) A line read with READRAWLINE has no special quoting mechanism; both backslash and vertical bar (described below) are just ordinary characters. An alternative notation to include otherwise delimiting characters in words is to enclose a group of characters in vertical bars. All characters between vertical bars are treated as if they were letters. In data read with READWORD the vertical bars are preserved in the resulting word. In data read with READLIST (or resulting from a PARSE or RUNPARSE of a word) the vertical bars do not appear explicitly; all potentially delimiting characters (including spaces, brackets, parentheses, and infix operators) appear as though entered with a backslash. Within vertical bars, backslash may still be used; the only characters that must be backslashed in this context are backslash and vertical bar themselves. Characters entered between vertical bars are forever special, even if the word or list containing them is later reparsed with PARSE or RUNPARSE. Characters typed after a backslash are treated somewhat differently: When a quoted word containing a backslashed character is runparsed, the backslashed character loses its special quality and acts thereafter as if typed normally. This distinction is important only if you are building a Logo expression out of parts, to be RUN later, and want to use parentheses. For example, PRINT RUN (SE "\( 2 "+ 3 "\)) will print 5, but RUN (SE "MAKE ""|(| 2) will create a variable whose name is open-parenthesis. (Each example would fail if vertical bars and backslashes were interchanged.) DATA STRUCTURE PRIMITIVES ========================= CONSTRUCTORS ------------ WORD word1 word2 (WORD word1 word2 word3 ...) outputs a word formed by concatenating its inputs. LIST thing1 thing2 (LIST thing1 thing2 thing3 ...) outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array). SENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...) outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists. FPUT thing list outputs a list equal to its second input with one extra member, the first input, at the beginning. If the second input is a word, then the first input must be a one-letter word, and FPUT is equivalent to WORD. LPUT thing list outputs a list equal to its second input with one extra member, the first input, at the end. If the second input is a word, then the first input must be a one-letter word, and LPUT is equivalent to WORD with its inputs in the other order. ARRAY size (ARRAY size origin) outputs an array of "size" members (must be a positive integer), each of which initially is an empty list. Array members can be selected with ITEM and changed with SETITEM. The first member of the array is member number 1 unless an "origin" input (must be an integer) is given, in which case the first member of the array has that number as its index. (Typically 0 is used as the origin if anything.) Arrays are printed by PRINT and friends, and can be typed in, inside curly braces; indicate an origin with {a b c}@0. MDARRAY sizelist (library procedure) (MDARRAY sizelist origin) outputs a multi-dimensional array. The first input must be a list of one or more positive integers. The second input, if present, must be a single integer that applies to every dimension of the array. Ex: (MDARRAY [3 5] 0) outputs a two-dimensional array whose members range from [0 0] to [2 4]. LISTTOARRAY list (LISTTOARRAY list origin) outputs an array of the same size as the input list, whose members are the members of the input list. ARRAYTOLIST array outputs a list whose members are the members of the input array. The first member of the output is the first member of the array, regardless of the array's origin. COMBINE thing1 thing2 (library procedure) if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2. REVERSE list (library procedure) outputs a list whose members are the members of the input list, in reverse order. GENSYM (library procedure) outputs a unique word each time it's invoked. The words are of the form G1, G2, etc. SELECTORS --------- FIRST thing if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array). FIRSTS list outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as to firsts :list output map "first :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. to transpose :matrix if emptyp first :matrix [op []] op fput firsts :matrix transpose bfs :matrix end LAST wordorlist if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list. BUTFIRST wordorlist BF wordorlist if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input. BUTFIRSTS list BFS list outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as to butfirsts :list output map "butfirst :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. BUTLAST wordorlist BL wordorlist if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input. ITEM index thing if the "thing" is a word, outputs the "index"th character of the word. If the "thing" is a list, outputs the "index"th member of the list. If the "thing" is an array, outputs the "index"th member of the array. "Index" starts at 1 for words and lists; the starting index of an array is specified when the array is created. MDITEM indexlist array (library procedure) outputs the member of the multidimensional "array" selected by the list of numbers "indexlist". PICK list (library procedure) outputs a randomly chosen member of the input list. REMOVE thing list (library procedure) outputs a copy of "list" with every member equal to "thing" removed. REMDUP list (library procedure) outputs a copy of "list" with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output. QUOTED thing (library procedure) outputs its input, if a list; outputs its input with a quotation mark prepended, if a word. MUTATORS -------- SETITEM index array value command. Replaces the "index"th member of "array" with the new "value". Ensures that the resulting array is not circular, i.e., "value" may not be a list or array that contains "array". MDSETITEM indexlist array value (library procedure) command. Replaces the member of "array" chosen by "indexlist" with the new "value". .SETFIRST list value command. Changes the first member of "list" to be "value". WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; and the loss of memory if a circular structure is released. .SETBF list value command. Changes the butfirst of "list" to be "value". WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; Logo crashes and coredumps if the butfirst of a list is not itself a list; and the loss of memory if a circular structure is released. .SETITEM index array value command. Changes the "index"th member of "array" to be "value", like SETITEM, but without checking for circularity. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETITEM can lead to circular arrays, which will get some Logo primitives into infinite loops; and the loss of memory if a circular structure is released. PUSH stackname thing (library procedure) command. Adds the "thing" to the stack that is the value of the variable whose name is "stackname". This variable must have a list as its value; the initial value should be the empty list. New members are added at the front of the list. POP stackname (library procedure) outputs the most recently PUSHed member of the stack that is the value of the variable whose name is "stackname" and removes that member from the stack. QUEUE queuename thing (library procedure) command. Adds the "thing" to the queue that is the value of the variable whose name is "queuename". This variable must have a list as its value; the initial value should be the empty list. New members are added at the back of the list. DEQUEUE queuename (library procedure) outputs the least recently QUEUEd member of the queue that is the value of the variable whose name is "queuename" and removes that member from the queue. PREDICATES ---------- WORDP thing WORD? thing outputs TRUE if the input is a word, FALSE otherwise. LISTP thing LIST? thing outputs TRUE if the input is a list, FALSE otherwise. ARRAYP thing ARRAY? thing outputs TRUE if the input is an array, FALSE otherwise. EMPTYP thing EMPTY? thing outputs TRUE if the input is the empty word or the empty list, FALSE otherwise. EQUALP thing1 thing2 EQUAL? thing1 thing2 thing1 = thing2 outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named CASEIGNOREDP whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.) NOTEQUALP thing1 thing2 NOTEQUAL? thing1 thing2 thing1 <> thing2 outputs FALSE if the inputs are equal, TRUE otherwise. See EQUALP for the meaning of equality for different data types. BEFOREP word1 word2 BEFORE? word1 word2 outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, BEFOREP 3 12 is false because 3 collates after 1. .EQ thing1 thing2 outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of mutators can lead to circular data structures, infinite loops, or Logo crashes. MEMBERP thing1 thing2 MEMBER? thing1 thing2 if "thing2" is a list or an array, outputs TRUE if "thing1" is EQUALP to a member of "thing2", FALSE otherwise. If "thing2" is a word, outputs TRUE if "thing1" is a one-character word EQUALP to a character of "thing2", FALSE otherwise. SUBSTRINGP thing1 thing2 SUBSTRING? thing1 thing2 if "thing1" or "thing2" is a list or an array, outputs FALSE. If "thing2" is a word, outputs TRUE if "thing1" is EQUALP to a substring of "thing2", FALSE otherwise. NUMBERP thing NUMBER? thing outputs TRUE if the input is a number, FALSE otherwise. BACKSLASHEDP char BACKSLASHED? char outputs TRUE if the input character was originally entered into Logo with a backslash (\) before it or within vertical bars (|) to prevent its usual special syntactic meaning, FALSE otherwise. (Outputs TRUE only if the character is a backslashed space, tab, newline, or one of ()[]+-*/=<>":;\~?| ) QUERIES ------- COUNT thing outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.) ASCII char outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing backslashed punctuation, and returns the character code for the corresponding punctuation character without backslash. (Compare RAWASCII.) RAWASCII char outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing themselves. To find out the ASCII code of an arbitrary keystroke, use RAWASCII RC. CHAR int outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255. MEMBER thing1 thing2 if "thing2" is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of "thing2" from the first instance of "thing1" to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of "thing2". It is an error for "thing2" to be an array. LOWERCASE word outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter. UPPERCASE word outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter. STANDOUT thing outputs a word that, when printed, will appear like the input but displayed in standout mode (boldface, reverse video, or whatever your terminal does for standout). The word contains terminal-specific magic characters at the beginning and end; in between is the printed form (as if displayed using TYPE) of the input. The output is always a word, even if the input is of some other type, but it may include spaces and other formatting characters. Note: a word output by STANDOUT while Logo is running on one terminal will probably not have the desired effect if printed on another type of terminal. On the Macintosh, the way that standout works is incompatible with the use of characters whose ASCII code is greater than 127. Therefore, you have a choice to make: The instruction CANINVERSE 0 disables standout, but enables the display of ASCII codes above 127, and the instruction CANINVERSE 1 restores the default situation in which standout is enabled and the extra graphic characters cannot be printed. PARSE word outputs the list that would result if the input word were entered in response to a READLIST operation. That is, PARSE READWORD has the same value as READLIST for the same characters read. RUNPARSE wordorlist outputs the list that would result if the input word or list were entered as an instruction line; characters such as infix operators and parentheses are separate members of the output. Note that sublists of a runparsed list are not themselves runparsed. COMMUNICATION ============= TRANSMITTERS ------------ Note: If there is a variable named PRINTDEPTHLIMIT with a nonnegative integer value, then complex list and array structures will be printed only to the allowed depth. That is, members of members of... of members will be allowed only so far. The members omitted because they are just past the depth limit are indicated by an ellipsis for each one, so a too-deep list of two members will print as [... ...]. If there is a variable named PRINTWIDTHLIMIT with a nonnegative integer value, then only the first so many members of any array or list will be printed. A single ellipsis replaces all missing data within the structure. The width limit also applies to the number of characters printed in a word, except that a PRINTWIDTHLIMIT between 0 and 9 will be treated as if it were 10 when applied to words. This limit applies not only to the top-level printed datum but to any substructures within it. If there is a variable named FULLPRINTP whose value is TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.) PRINT thing PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...) command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays. TYPE thing (TYPE thing1 thing2 ...) command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces. Note: printing to the terminal is ordinarily "line buffered"; that is, the characters you print using TYPE will not actually appear on the screen until either a newline character is printed (for example, by PRINT or SHOW) or Logo tries to read from the keyboard (either at the request of your program or after an instruction prompt). This buffering makes the program much faster than it would be if each character appeared immediately, and in most cases the effect is not disconcerting. To accommodate programs that do a lot of positioned text display using TYPE, Logo will force printing whenever SETCURSOR is invoked. This solves most buffering problems. Still, on occasion you may find it necessary to force the buffered characters to be printed explicitly; this can be done using the WAIT command. WAIT 0 will force printing without actually waiting. SHOW thing (SHOW thing1 thing2 ...) command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets. RECEIVERS --------- READLIST RL reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character. READWORD RW reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READWORD outputs the empty list (not the empty word). READWORD processes backslash, vertical bar, and tilde characters in the read stream. In the case of a tilde used for line continuation, the output word DOES include the tilde and the newline characters, so that the user program can tell exactly what the user entered. Vertical bars in the line are also preserved in the output. Backslash characters are not preserved in the output, but the character following the backslash has 128 added to its representation. Programs can use BACKSLASHEDP to check for this code. (Backslashedness is preserved only for certain characters. See BACKSLASHEDP.) READRAWLINE reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters. READCHAR RC reads a single character from the read stream and outputs that character as a word. If the read stream is a file, and the end of file is reached, READCHAR outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHAR is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. READCHARS num RCS num reads "num" characters from the read stream and outputs those characters as a word. If the read stream is a file, and the end of file is reached, READCHARS outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHARS is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. SHELL command (SHELL command wordflag) Under Unix, outputs the result of running "command" as a shell command. (The command is sent to /bin/sh, not csh or other alternatives.) If the command is a literal list in the instruction line, and if you want a backslash character sent to the shell, you must use \\ to get the backslash through Logo's reader intact. The output is a list containing one member for each line generated by the shell command. Ordinarily each such line is represented by a list in the output, as though the line were read using READLIST. If a second input is given, regardless of the value of the input, each line is represented by a word in the output as though it were read with READWORD. Example: to dayofweek output first first shell [date] end This is "first first" to extract the first word of the first (and only) line of the shell output. Under DOS, SHELL is a command, not an operation; it sends its input to a DOS command processor but does not collect the result of the command. The Macintosh, of course, is not programmable (unless you are running the Unix version of UCBLogo under OS X). FILE ACCESS ----------- SETPREFIX string command. Sets a prefix that will be used as the implicit beginning of filenames in OPENREAD, OPENWRITE, OPENAPPEND, OPENUPDATE, LOAD, and SAVE commands. Logo will put the appropriate separator character (slash for Unix, backslash for DOS/Windows, colon for MacOS) between the prefix and the filename entered by the user. The input to SETPREFIX must be a word, unless it is the empty list, to indicate that there should be no prefix. PREFIX outputs the current file prefix, or [] if there is no prefix. See SETPREFIX. OPENREAD filename command. Opens the named file for reading. The read position is initially at the beginning of the file. OPENWRITE filename command. Opens the named file for writing. If the file already existed, the old version is deleted and a new, empty file created. OPENWRITE, but not the other OPEN variants, will accept as input a two-element list, in which the first element must be a variable name, and the second must be a positive integer. A character buffer of the specified size will be created. When a SETWRITE is done with this same list (in the sense of .EQ, not a copy, so you must do something like ? make "buf [foo 100] ? openwrite :buf ? setwrite :buf [...] ? close :buf and not just ? openwrite [foo 100] ? setwrite [foo 100] and so on), the printed characters are stored in the buffer; when a CLOSE is done with the same list as input, the characters from the buffer (treated as one long word, even if spaces and newlines are included) become the value of the specified variable. OPENAPPEND filename command. Opens the named file for writing. If the file already exists, the write position is initially set to the end of the old file, so that newly written data will be appended to it. OPENUPDATE filename command. Opens the named file for reading and writing. The read and write position is initially set to the end of the old file, if any. Note: each open file has only one position, for both reading and writing. If a file opened for update is both READER and WRITER at the same time, then SETREADPOS will also affect WRITEPOS and vice versa. Also, if you alternate reading and writing the same file, you must SETREADPOS between a write and a read, and SETWRITEPOS between a read and a write. CLOSE filename command. Closes the named file. If the file was currently the reader or writer, then the reader or writer is changed to the keyboard or screen, as if SETREAD [] or SETWRITE [] had been done. ALLOPEN outputs a list whose members are the names of all files currently open. This list does not include the dribble file, if any. CLOSEALL (library procedure) command. Closes all open files. Abbreviates FOREACH ALLOPEN [CLOSE ?] ERASEFILE filename ERF filename command. Erases (deletes, removes) the named file, which should not currently be open. DRIBBLE filename command. Creates a new file whose name is the input, like OPENWRITE, and begins recording in that file everything that is read from the keyboard or written to the terminal. That is, this writing is in addition to the writing to WRITER. The intent is to create a transcript of a Logo session, including things like prompt characters and interactions. NODRIBBLE command. Stops copying information into the dribble file, and closes the file. SETREAD filename command. Makes the named file the read stream, used for READLIST, etc. The file must already be open with OPENREAD or OPENUPDATE. If the input is the empty list, then the read stream becomes the terminal, as usual. Changing the read stream does not close the file that was previously the read stream, so it is possible to alternate between files. SETWRITE filename command. Makes the named file the write stream, used for PRINT, etc. The file must already be open with OPENWRITE, OPENAPPEND, or OPENUPDATE. If the input is the empty list, then the write stream becomes the terminal, as usual. Changing the write stream does not close the file that was previously the write stream, so it is possible to alternate between files. If the input is a list, then its first element must be a variable name, and its second and last element must be a positive integer; a buffer of that many characters will be allocated, and will become the writestream. If the same list (same in the .EQ sense, not a copy) has been used as input to OPENWRITE, then the already-allocated buffer will be used, and the writer can be changed to and from this buffer, with all the characters accumulated as in a file. When the same list is used as input to CLOSE, the contents of the buffer (as an unparsed word, which may contain newline characters) will become the value of the named variable. For compatibility with earlier versions, if the list has not been opened when the SETWRITE is done, it will be opened implicitly, but the first SETWRITE after this one will implicitly close it, setting the variable and freeing the allocated buffer. READER outputs the name of the current read stream file, or the empty list if the read stream is the terminal. WRITER outputs the name of the current write stream file, or the empty list if the write stream is the terminal. SETREADPOS charpos command. Sets the file pointer of the read stream file so that the next READLIST, etc., will begin reading at the "charpos"th character in the file, counting from 0. (That is, SETREADPOS 0 will start reading from the beginning of the file.) Meaningless if the read stream is the terminal. SETWRITEPOS charpos command. Sets the file pointer of the write stream file so that the next PRINT, etc., will begin writing at the "charpos"th character in the file, counting from 0. (That is, SETWRITEPOS 0 will start writing from the beginning of the file.) Meaningless if the write stream is the terminal. READPOS outputs the file position of the current read stream file. WRITEPOS outputs the file position of the current write stream file. EOFP EOF? predicate, outputs TRUE if there are no more characters to be read in the read stream file, FALSE otherwise. FILEP filename FILE? filename (library procedure) predicate, outputs TRUE if a file of the specified name exists and can be read, FALSE otherwise. TERMINAL ACCESS --------------- KEYP KEY? predicate, outputs TRUE if there are characters waiting to be read from the read stream. If the read stream is a file, this is equivalent to NOT EOFP. If the read stream is the terminal, then echoing is turned off and the terminal is set to CBREAK (character at a time instead of line at a time) mode. It remains in this mode until some line-mode reading is requested (e.g., READLIST). The Unix operating system forgets about any pending characters when it switches modes, so the first KEYP invocation will always output FALSE. CLEARTEXT CT command. Clears the text screen of the terminal. SETCURSOR vector command. The input is a list of two numbers, the x and y coordinates of a screen position (origin in the upper left corner, positive direction is southeast). The screen cursor is moved to the requested position. This command also forces the immediate printing of any buffered characters. CURSOR outputs a list containing the current x and y coordinates of the screen cursor. Logo may get confused about the current cursor position if, e.g., you type in a long line that wraps around or your program prints escape codes that affect the terminal strangely. SETMARGINS vector command. The input must be a list of two numbers, as for SETCURSOR. The effect is to clear the screen and then arrange for all further printing to be shifted down and to the right according to the indicated margins. Specifically, every time a newline character is printed (explicitly or implicitly) Logo will type x_margin spaces, and on every invocation of SETCURSOR the margins will be added to the input x and y coordinates. (CURSOR will report the cursor position relative to the margins, so that this shift will be invisible to Logo programs.) The purpose of this command is to accommodate the display of terminal screens in lecture halls with inadequate TV monitors that miss the top and left edges of the screen. SETTEXTCOLOR foreground background SETTC foreground background command (Windows and DOS extended only). The inputs are color numbers, as for turtle graphics. Future printing to the text window will use the specified colors for foreground (the characters printed) and background (the space under those characters). Using STANDOUT will revert to the default text window colors. In the DOS extended (ucblogo.exe) version, colors in textscreen mode are limited to numbers 0-7, and the coloring applies only to text printed by the program, not to the echoing of text typed by the user. Neither limitation applies to the text portion of splitscreen mode, which is actually drawn as graphics internally. ARITHMETIC ========== NUMERIC OPERATIONS ------------------ SUM num1 num2 (SUM num1 num2 num3 ...) num1 + num2 outputs the sum of its inputs. DIFFERENCE num1 num2 num1 - num2 outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.) MINUS num - num outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms: MINUS 3 + 4 means -(3+4) - 3 + 4 means (-3)+4 PRODUCT num1 num2 (PRODUCT num1 num2 num3 ...) num1 * num2 outputs the product of its inputs. QUOTIENT num1 num2 (QUOTIENT num) num1 / num2 outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is 2, not 2.0 -- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input. REMAINDER num1 num2 outputs the remainder on dividing "num1" by "num2"; both must be integers and the result is an integer with the same sign as num1. MODULO num1 num2 outputs the remainder on dividing "num1" by "num2"; both must be integers and the result is an integer with the same sign as num2. INT num outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input. ROUND num outputs the nearest integer to the input. SQRT num outputs the square root of the input, which must be nonnegative. POWER num1 num2 outputs "num1" to the "num2" power. If num1 is negative, then num2 must be an integer. EXP num outputs e (2.718281828+) to the input power. LOG10 num outputs the common logarithm of the input. LN num outputs the natural logarithm of the input. SIN degrees outputs the sine of its input, which is taken in degrees. RADSIN radians outputs the sine of its input, which is taken in radians. COS degrees outputs the cosine of its input, which is taken in degrees. RADCOS radians outputs the cosine of its input, which is taken in radians. ARCTAN num (ARCTAN x y) outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or -90 depending on the sign of y, if x is zero. RADARCTAN num (RADARCTAN x y) outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or -pi/2 depending on the sign of y, if x is zero. The expression 2*(RADARCTAN 0 1) can be used to get the value of pi. ISEQ from to (library procedure) outputs a list of the integers from FROM to TO, inclusive. ? show iseq 3 7 [3 4 5 6 7] ? show iseq 7 3 [7 6 5 4 3] RSEQ from to count (library procedure) outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive. ? show rseq 3 5 9 [3 3.25 3.5 3.75 4 4.25 4.5 4.75 5] ? show rseq 3 5 5 [3 3.5 4 4.5 5] PREDICATES ---------- LESSP num1 num2 LESS? num1 num2 num1 < num2 outputs TRUE if its first input is strictly less than its second. GREATERP num1 num2 GREATER? num1 num2 num1 > num2 outputs TRUE if its first input is strictly greater than its second. LESSEQUALP num1 num2 LESSEQUAL? num1 num2 num1 <= num2 outputs TRUE if its first input is less than or equal to its second. GREATEREQUALP num1 num2 GREATEREQUAL? num1 num2 num1 >= num2 outputs TRUE if its first input is greater than or equal to its second. RANDOM NUMBERS -------------- RANDOM num (RANDOM start end) with one input, outputs a random nonnegative integer less than its input, which must be a positive integer. With two inputs, RANDOM outputs a random integer greater than or equal to the first input, and less than or equal to the second input. Both inputs must be integers, and the first must be less than the second. (RANDOM 0 9) is equivalent to RANDOM 10; (RANDOM 3 8) is equivalent to (RANDOM 6)+3. RERANDOM (RERANDOM seed) command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers. PRINT FORMATTING ---------------- FORM num width precision outputs a word containing a printable representation of "num", possibly preceded by spaces (and therefore not a number for purposes of performing arithmetic operations), with at least "width" characters, including exactly "precision" digits after the decimal point. (If "precision" is 0 then there will be no decimal point in the output.) As a debugging feature, (FORM num -1 format) will print the floating point "num" according to the C printf "format", to allow to hex :num op form :num -1 "|%08X %08X| end to allow finding out the exact result of floating point operations. The precise format needed may be machine-dependent. BITWISE OPERATIONS ------------------ BITAND num1 num2 (BITAND num1 num2 num3 ...) outputs the bitwise AND of its inputs, which must be integers. BITOR num1 num2 (BITOR num1 num2 num3 ...) outputs the bitwise OR of its inputs, which must be integers. BITXOR num1 num2 (BITXOR num1 num2 num3 ...) outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers. BITNOT num outputs the bitwise NOT of its input, which must be an integer. ASHIFT num1 num2 outputs "num1" arithmetic-shifted to the left by "num2" bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers. LSHIFT num1 num2 outputs "num1" logical-shifted to the left by "num2" bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers. LOGICAL OPERATIONS ================== AND tf1 tf2 (AND tf1 tf2 tf3 ...) outputs TRUE if all inputs are TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, "true" or "True" or "TRUE" are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example: MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5] to avoid the division by zero if the first part is false. OR tf1 tf2 (OR tf1 tf2 tf3 ...) outputs TRUE if any input is TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, "true" or "True" or "TRUE" are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example: IF OR :X=0 [some.long.computation] [...] to avoid the long computation if the first condition is met. NOT tf outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. GRAPHICS ======== Berkeley Logo provides traditional Logo turtle graphics with one turtle. Multiple turtles, dynamic turtles, and collision detection are not supported. This is the most hardware-dependent part of Logo; some features may exist on some machines but not others. Nevertheless, the goal has been to make Logo programs as portable as possible, rather than to take fullest advantage of the capabilities of each machine. In particular, Logo attempts to scale the screen so that turtle coordinates [-100 -100] and [100 100] fit on the graphics window, and so that the aspect ratio is 1:1. The center of the graphics window (which may or may not be the entire screen, depending on the machine used) is turtle location [0 0]. Positive X is to the right; positive Y is up. Headings (angles) are measured in degrees clockwise from the positive Y axis. (This differs from the common mathematical convention of measuring angles counterclockwise from the positive X axis.) The turtle is represented as an isoceles triangle; the actual turtle position is at the midpoint of the base (the short side). However, the turtle is drawn one step behind its actual position, so that the display of the base of the turtle's triangle does not obscure a line drawn perpendicular to it (as would happen after drawing a square). Colors are, of course, hardware-dependent. However, Logo provides partial hardware independence by interpreting color numbers 0 through 7 uniformly on all computers: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white Where possible, Logo provides additional user-settable colors; how many are available depends on the hardware and operating system environment. If at least 16 colors are available, Logo tries to provide uniform initial settings for the colors 8-15: 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey Logo begins with a black background and white pen. TURTLE MOTION ------------- FORWARD dist FD dist moves the turtle forward, in the direction that it's facing, by the specified distance (measured in turtle steps). BACK dist BK dist moves the turtle backward, i.e., exactly opposite to the direction that it's facing, by the specified distance. (The heading of the turtle does not change.) LEFT degrees LT degrees turns the turtle counterclockwise by the specified angle, measured in degrees (1/360 of a circle). RIGHT degrees RT degrees turns the turtle clockwise by the specified angle, measured in degrees (1/360 of a circle). SETPOS pos moves the turtle to an absolute screen position. The input is a list of two numbers, the X and Y coordinates. SETXY xcor ycor moves the turtle to an absolute screen position. The two inputs are numbers, the X and Y coordinates. SETX xcor moves the turtle horizontally from its old position to a new absolute horizontal coordinate. The input is the new X coordinate. SETY ycor moves the turtle vertically from its old position to a new absolute vertical coordinate. The input is the new Y coordinate. SETHEADING degrees SETH degrees turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive Y axis. HOME moves the turtle to the center of the screen. Equivalent to SETPOS [0 0] SETHEADING 0. ARC angle radius draws an arc of a circle, with the turtle at the center, with the specified radius, starting at the turtle's heading and extending clockwise through the specified angle. The turtle does not move. TURTLE MOTION QUERIES --------------------- POS outputs the turtle's current position, as a list of two numbers, the X and Y coordinates. XCOR (library procedure) outputs a number, the turtle's X coordinate. YCOR (library procedure) outputs a number, the turtle's Y coordinate. HEADING outputs a number, the turtle's heading in degrees. TOWARDS pos outputs a number, the heading at which the turtle should be facing so that it would point from its current position to the position given as the input. SCRUNCH outputs a list containing two numbers, the X and Y scrunch factors, as used by SETSCRUNCH. (But note that SETSCRUNCH takes two numbers as inputs, not one list of numbers.) TURTLE AND WINDOW CONTROL ------------------------- SHOWTURTLE ST makes the turtle visible. HIDETURTLE HT makes the turtle invisible. It's a good idea to do this while you're in the middle of a complicated drawing, because hiding the turtle speeds up the drawing substantially. CLEAN erases all lines that the turtle has drawn on the graphics window. The turtle's state (position, heading, pen mode, etc.) is not changed. CLEARSCREEN CS erases the graphics window and sends the turtle to its initial position and heading. Like HOME and CLEAN together. WRAP tells the turtle to enter wrap mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will "wrap around" and reappear at the opposite edge of the window. The top edge wraps to the bottom edge, while the left edge wraps to the right edge. (So the window is topologically equivalent to a torus.) This is the turtle's initial mode. Compare WINDOW and FENCE. WINDOW tells the turtle to enter window mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move offscreen. The visible graphics window is considered as just part of an infinite graphics plane; the turtle can be anywhere on the plane. (If you lose the turtle, HOME will bring it back to the center of the window.) Compare WRAP and FENCE. FENCE tells the turtle to enter fence mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move as far as it can and then stop at the edge with an "out of bounds" error message. Compare WRAP and WINDOW. FILL fills in a region of the graphics window containing the turtle and bounded by lines that have been drawn earlier. This is not portable; it doesn't work for all machines, and may not work exactly the same way on different machines. LABEL text takes a word or list as input, and prints the input on the graphics window, starting at the turtle's position. TEXTSCREEN TS rearranges the size and position of windows to maximize the space available in the text window (the window used for interaction with Logo). The details differ among machines. Compare SPLITSCREEN and FULLSCREEN. FULLSCREEN FS rearranges the size and position of windows to maximize the space available in the graphics window. The details differ among machines. Compare SPLITSCREEN and TEXTSCREEN. In the DOS version, switching from fullscreen to splitscreen loses the part of the picture that's hidden by the text window. Also, since there must be a text window to allow printing (including the printing of the Logo prompt), Logo automatically switches from fullscreen to splitscreen whenever anything is printed. [This design decision follows from the scarcity of memory, so that the extra memory to remember an invisible part of a drawing seems too expensive.] SPLITSCREEN SS rearranges the size and position of windows to allow some room for text interaction while also keeping most of the graphics window visible. The details differ among machines. Compare TEXTSCREEN and FULLSCREEN. SETSCRUNCH xscale yscale adjusts the aspect ratio and scaling of the graphics display. After this command is used, all further turtle motion will be adjusted by multiplying the horizontal and vertical extent of the motion by the two numbers given as inputs. For example, after the instruction "SETSCRUNCH 2 1" motion at a heading of 45 degrees will move twice as far horizontally as vertically. If your squares don't come out square, try this. (Alternatively, you can deliberately misadjust the aspect ratio to draw an ellipse.) For Unix machines and Macintoshes, both scale factors are initially 1. For DOS machines, the scale factors are initially set according to what the hardware claims the aspect ratio is, but the hardware sometimes lies. The values set by SETSCRUNCH are remembered in a file (called SCRUNCH.DAT) and are automatically put into effect when a Logo session begins. REFRESH tells Logo to remember the turtle's motions so that they can be reconstructed in case the graphics window is overlayed. The effectiveness of this command may depend on the machine used. NOREFRESH tells Logo not to remember the turtle's motions. This will make drawing faster, but prevents recovery if the window is overlayed. TURTLE AND WINDOW QUERIES ------------------------- SHOWNP SHOWN? outputs TRUE if the turtle is shown (visible), FALSE if the turtle is hidden. See SHOWTURTLE and HIDETURTLE. SCREENMODE outputs the word TEXTSCREEN, SPLITSCREEN, or FULLSCREEN depending on the current screen mode. TURTLEMODE outputs the word WRAP, FENCE, or WINDOW depending on the current turtle mode. PEN AND BACKGROUND CONTROL -------------------------- The turtle carries a pen that can draw pictures. At any time the pen can be UP (in which case moving the turtle does not change what's on the graphics screen) or DOWN (in which case the turtle leaves a trace). If the pen is down, it can operate in one of three modes: PAINT (so that it draws lines when the turtle moves), ERASE (so that it erases any lines that might have been drawn on or through that path earlier), or REVERSE (so that it inverts the status of each point along the turtle's path). PENDOWN PD sets the pen's position to DOWN, without changing its mode. PENUP PU sets the pen's position to UP, without changing its mode. PENPAINT PPT sets the pen's position to DOWN and mode to PAINT. PENERASE PE sets the pen's position to DOWN and mode to ERASE. PENREVERSE PX sets the pen's position to DOWN and mode to REVERSE. (This may interact in hardware-dependent ways with use of color.) SETPENCOLOR colornumber.or.rgblist SETPC colornumber.or.rgblist sets the pen color to the given number, which must be a nonnegative integer. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. Alternatively, sets the pen color to the given RGB values (a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color). SETPALETTE colornumber rgblist sets the actual color corresponding to a given number, if allowed by the hardware and operating system. Colornumber must be an integer greater than or equal to 8. (Logo tries to keep the first 8 colors constant.) The second input is a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color. The actual color resolution on any screen is probably less than 64K, but Logo scales as needed. SETPENSIZE size sets the thickness of the pen. The input is either a single positive integer or a list of two positive integers (for horizontal and vertical thickness). Some versions pay no attention to the second number, but always have a square pen. SETPENPATTERN pattern sets hardware-dependent pen characteristics. This command is not guaranteed compatible between implementations on different machines. SETPEN list (library procedure) sets the pen's position, mode, thickness, and hardware-dependent characteristics according to the information in the input list, which should be taken from an earlier invocation of PEN. SETBACKGROUND colornumber.or.rgblist SETBG colornumber.or.rgblist set the screen background color by slot number or RGB values. See SETPENCOLOR for details. PEN QUERIES ----------- PENDOWNP PENDOWN? outputs TRUE if the pen is down, FALSE if it's up. PENMODE outputs one of the words PAINT, ERASE, or REVERSE according to the current pen mode. PENCOLOR PC outputs a color number, a nonnegative integer that is associated with a particular color, or a list of RGB values if such a list was used as the most recent input to SETPENCOLOR. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. PALETTE colornumber outputs a list of three integers, each in the range 0-65535, representing the amount of red, green, and blue in the color associated with the given number. PENSIZE outputs a list of two positive integers, specifying the horizontal and vertical thickness of the turtle pen. (In some implementations the two numbers may always be equal.) PENPATTERN outputs hardware-specific pen information. PEN (library procedure) outputs a list containing the pen's position, mode, thickness, and hardware-specific characteristics, for use by SETPEN. BACKGROUND BG outputs the graphics background color, either as a slot number or as an RGB list, whichever way it was set. (See PENCOLOR.) SAVING AND LOADING PICTURES --------------------------- SAVEPICT filename command. Writes a file with the specified name containing the state of the graphics window, including any nonstandard color palette settings, in Logo's internal format. This picture can be restored to the screen using LOADPICT. The format is not portable between platforms, nor is it readable by other programs. See EPSPICT to export Logo graphics for other programs. LOADPICT filename command. Reads the specified file, which must have been written by a SAVEPICT command, and restores the graphics window and color palette settings to the values stored in the file. Any drawing previously on the screen is cleared. EPSPICT filename command. Writes a file with the specified name, containing an Encapsulated Postscript (EPS) representation of the state of the graphics window. This file can be imported into other programs that understand EPS format. Restrictions: the drawing cannot use ARC, FILL, PENERASE, or PENREVERSE; any such instructions will be ignored in the translation to Postscript form. MOUSE QUERIES ------------- MOUSEPOS outputs the coordinates of the mouse, provided that it's within the graphics window, in turtle coordinates. If the mouse is outside the graphics window, then the last position within the window is returned. Exception: If a mouse button is pressed within the graphics window and held while the mouse is dragged outside the window, the mouse's position is returned as if the window were big enough to include it. BUTTONP BUTTON? outputs TRUE if a mouse button is down and the mouse is over the graphics window. Once the button is down, BUTTONP remains true until the button is released, even if the mouse is dragged out of the graphics window. BUTTON outputs 0 if BUTTONP would output FALSE; otherwise, it outputs an integer between 1 and 3 indicating which button was pressed. Ordinarily 1 means left, 2 means right, and 3 means center, but operating systems may reconfigure these. WORKSPACE MANAGEMENT ==================== PROCEDURE DEFINITION -------------------- TO procname :input1 :input2 ... (special form) command. Prepares Logo to accept a procedure definition. The procedure will be named "procname" and there must not already be a procedure by that name. The inputs will be called "input1" etc. Any number of inputs are allowed, including none. Names of procedures and inputs are case-insensitive. Unlike every other Logo procedure, TO takes as its inputs the actual words typed in the instruction line, as if they were all quoted, rather than the results of evaluating expressions to provide the inputs. (That's what "special form" means.) This version of Logo allows variable numbers of inputs to a procedure. After the procedure name come four kinds of things, *in this order*: 1. 0 or more REQUIRED inputs :FOO :FROBOZZ 2. 0 or more OPTIONAL inputs [:BAZ 87] [:THINGO 5+9] 3. 0 or 1 REST input [:GARPLY] 4. 0 or 1 DEFAULT number 5 Every procedure has a MINIMUM, DEFAULT, and MAXIMUM number of inputs. (The latter can be infinite.) The MINIMUM number of inputs is the number of required inputs, which must come first. A required input is indicated by the :inputname notation. After all the required inputs can be zero or more optional inputs, each of which is represented by the following notation: [:inputname default.value.expression] When the procedure is invoked, if actual inputs are not supplied for these optional inputs, the default value expressions are evaluated to set values for the corresponding input names. The inputs are processed from left to right, so a default value expression can be based on earlier inputs. Example: to proc :inlist [:startvalue first :inlist] If the procedure is invoked by saying proc [a b c] then the variable INLIST will have the value [A B C] and the variable STARTVALUE will have the value A. If the procedure is invoked by saying (proc [a b c] "x) then INLIST will have the value [A B C] and STARTVALUE will have the value X. After all the required and optional input can come a single "rest" input, represented by the following notation: [:inputname] This is a rest input rather than an optional input because there is no default value expression. There can be at most one rest input. When the procedure is invoked, the value of this input will be a list containing all of the actual inputs provided that were not used for required or optional inputs. Example: to proc :in1 [:in2 "foo] [:in3 "baz] [:in4] If this procedure is invoked by saying proc "x then IN1 has the value X, IN2 has the value FOO, IN3 has the value BAZ, and IN4 has the value [] (the empty list). If it's invoked by saying (proc "a "b "c "d "e) then IN1 has the value A, IN2 has the value B, IN3 has the value C, and IN4 has the value [D E]. The MAXIMUM number of inputs for a procedure is infinite if a rest input is given; otherwise, it is the number of required inputs plus the number of optional inputs. The DEFAULT number of inputs for a procedure, which is the number of inputs that it will accept if its invocation is not enclosed in parentheses, is ordinarily equal to the minimum number. If you want a different default number you can indicate that by putting the desired default number as the last thing on the TO line. example: to proc :in1 [:in2 "foo] [:in3] 3 This procedure has a minimum of one input, a default of three inputs, and an infinite maximum. Logo responds to the TO command by entering procedure definition mode. The prompt character changes from "?" to ">" and whatever instructions you type become part of the definition until you type a line containing only the word END. DEFINE procname text command. Defines a procedure with name "procname" and text "text". If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.) It is an error to redefine a primitive procedure unless the variable REDEFP has the value TRUE. TEXT procname outputs the text of the procedure named "procname" in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces. FULLTEXT procname outputs a representation of the procedure "procname" in which formatting information is preserved. If the procedure was defined with TO, EDIT, or LOAD, then the output is a list of words. Each word represents one entire line of the definition in the form output by READWORD, including extra spaces and continuation lines. The last member of the output represents the END line. If the procedure was defined with DEFINE, then the output is a list of lists. If these lists are printed, one per line, the result will look like a definition using TO. Note: the output from FULLTEXT is not suitable for use as input to DEFINE! COPYDEF newname oldname command. Makes "newname" a procedure identical to "oldname". The latter may be a primitive. If "newname" was already defined, its previous definition is lost. If "newname" was already a primitive, the redefinition is not permitted unless the variable REDEFP has the value TRUE. Note: dialects of Logo differ as to the order of inputs to COPYDEF. This dialect uses "MAKE order," not "NAME order." VARIABLE DEFINITION ------------------- MAKE varname value command. Assigns the value "value" to the variable named "varname", which must be a word. Variable names are case-insensitive. If a variable with the same name already exists, the value of that variable is changed. If not, a new global variable is created. NAME value varname (library procedure) command. Same as MAKE but with the inputs in reverse order. LOCAL varname LOCAL varnamelist (LOCAL varname1 varname2 ...) command. Accepts as inputs one or more words, or a list of words. A variable is created for each of these words, with that word as its name. The variables are local to the currently running procedure. Logo variables follow dynamic scope rules; a variable that is local to a procedure is available to any subprocedure invoked by that procedure. The variables created by LOCAL have no initial value; they must be assigned a value (e.g., with MAKE) before the procedure attempts to read their value. LOCALMAKE varname value (library procedure) command. Makes the named variable local, like LOCAL, and assigns it the given value, like MAKE. THING varname :quoted.varname outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination thing " so that :FOO means THING "FOO. GLOBAL varname GLOBAL varnamelist (GLOBAL varname1 varname2 ...) command. Accepts as inputs one or more words, or a list of words. A global variable is created for each of these words, with that word as its name. The only reason this is necessary is that you might want to use the "setter" notation SETXYZ for a variable XYZ that does not already have a value; GLOBAL "XYZ makes that legal. Note: If there is currently a local variable of the same name, this command does *not* make Logo use the global value instead of the local one. PROPERTY LISTS -------------- Note: Names of property lists are always case-insensitive. Names of individual properties are case-sensitive or case-insensitive depending on the value of CASEIGNOREDP, which is TRUE by default. In principle, every possible name is the name of a property list, which is initially empty. So Logo never gives a "no such property list" error, as it would for undefined procedure or variable names. But the primitive procedures that deal with "all" property lists (CONTENTS, PLISTS, etc.) list only nonempty ones. To "erase" a property list (see ERASE below) means to make it empty, removing all properties from it. PPROP plistname propname value command. Adds a property to the "plistname" property list with name "propname" and value "value". GPROP plistname propname outputs the value of the "propname" property in the "plistname" property list, or the empty list if there is no such property. REMPROP plistname propname command. Removes the property named "propname" from the property list named "plistname". PLIST plistname outputs a list whose odd-numbered members are the names, and whose even-numbered members are the values, of the properties in the property list named "plistname". The output is a copy of the actual property list; changing properties later will not magically change a list output earlier by PLIST. PREDICATES ---------- PROCEDUREP name PROCEDURE? name outputs TRUE if the input is the name of a procedure. PRIMITIVEP name PRIMITIVE? name outputs TRUE if the input is the name of a primitive procedure (one built into Logo). Note that some of the procedures described in this document are library procedures, not primitives. DEFINEDP name DEFINED? name outputs TRUE if the input is the name of a user-defined procedure, including a library procedure. (However, Logo does not know about a library procedure until that procedure has been invoked.) NAMEP name NAME? name outputs TRUE if the input is the name of a variable. PLISTP name PLIST? name outputs TRUE if the input is the name of a *nonempty* property list. (In principle every word is the name of a property list; if you haven't put any properties in it, PLIST of that name outputs an empty list, rather than giving an error message.) QUERIES ------- CONTENTS outputs a "contents list," i.e., a list of three lists containing names of defined procedures, variables, and property lists respectively. This list includes all unburied named items in the workspace. BURIED outputs a contents list including all buried named items in the workspace. TRACED outputs a contents list including all traced named items in the workspace. STEPPED outputs a contents list including all stepped named items in the workspace. PROCEDURES outputs a list of the names of all unburied user-defined procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.) PRIMITIVES outputs a list of the names of all primitive procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.) NAMES outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace. PLISTS outputs a contents list consisting of two empty lists (indicating no procedures or variables) followed by a list of all unburied nonempty property lists in the workspace. NAMELIST varname (library procedure) NAMELIST varnamelist outputs a contents list consisting of an empty list followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. PLLIST plname (library procedure) PLLIST plnamelist outputs a contents list consisting of two empty lists followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. Note: All procedures whose input is indicated as "contentslist" will accept a single word (taken as a procedure name), a list of words (taken as names of procedures), or a list of three lists as described under the CONTENTS command above. ARITY procedurename outputs a list of three numbers: the minimum, default, and maximum number of inputs for the procedure whose name is the input. It is an error if there is no such procedure. A maximum of -1 means that the number of inputs is unlimited. NODES outputs a list of two numbers. The first represents the number of nodes of memory currently in use. The second shows the maximum number of nodes that have been in use at any time since the last invocation of NODES. (A node is a small block of computer memory as used by Logo. Each number uses one node. Each non-numeric word uses one node, plus some non-node memory for the characters in the word. Each array takes one node, plus some non-node memory, as well as the memory required by its elements. Each list requires one node per element, as well as the memory within the elements.) If you want to track the memory use of an algorithm, it is best if you invoke GC at the beginning of each iteration, since otherwise the maximum will include storage that is unused but not yet collected. INSPECTION ---------- PRINTOUT contentslist PO contentslist command. Prints to the write stream the definitions of all procedures, variables, and property lists named in the input contents list. POALL (library procedure) command. Prints all unburied definitions in the workspace. Abbreviates PO CONTENTS. POPS (library procedure) command. Prints the definitions of all unburied procedures in the workspace. Abbreviates PO PROCEDURES. PONS (library procedure) command. Prints the definitions of all unburied variables in the workspace. Abbreviates PO NAMES. POPLS (library procedure) command. Prints the contents of all unburied nonempty property lists in the workspace. Abbreviates PO PLISTS. PON varname (library procedure) PON varnamelist command. Prints the definitions of the named variable(s). Abbreviates PO NAMELIST varname(list). POPL plname (library procedure) POPL plnamelist command. Prints the definitions of the named property list(s). Abbreviates PO PLLIST plname(list). POT contentslist command. Prints the title lines of the named procedures and the definitions of the named variables and property lists. For property lists, the entire list is shown on one line instead of as a series of PPROP instructions as in PO. POTS (library procedure) command. Prints the title lines of all unburied procedures in the workspace. Abbreviates POT PROCEDURES. WORKSPACE CONTROL ----------------- ERASE contentslist ER contentslist command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE. ERALL command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates ERASE CONTENTS. ERPS command. Erases all unburied procedures from the workspace. Abbreviates ERASE PROCEDURES. ERNS command. Erases all unburied variables from the workspace. Abbreviates ERASE NAMES. ERPLS command. Erases all unburied property lists from the workspace. Abbreviates ERASE PLISTS. ERN varname (library procedure) ERN varnamelist command. Erases from the workspace the variable(s) named in the input. Abbreviates ERASE NAMELIST varname(list). ERPL plname (library procedure) ERPL plnamelist command. Erases from the workspace the property list(s) named in the input. Abbreviates ERASE PLLIST plname(list). BURY contentslist command. Buries the procedures, variables, and property lists named in the input. A buried item is not included in the lists output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is included in the list output by BURIED. By implication, buried things are not printed by POALL or saved by SAVE. BURYALL (library procedure) command. Abbreviates BURY CONTENTS. BURYNAME varname (library procedure) BURYNAME varnamelist command. Abbreviates BURY NAMELIST varname(list). UNBURY contentslist command. Unburies the procedures, variables, and property lists named in the input. That is, the named items will be returned to view in CONTENTS, etc. UNBURYALL (library procedure) command. Abbreviates UNBURY BURIED. UNBURYNAME varname (library procedure) UNBURYNAME varnamelist command. Abbreviates UNBURY NAMELIST varname(list). BURIEDP contentslist BURIED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is buried, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can BURIEDP [[] [VARIABLE]] or BURIEDP [[] [] [PROPLIST]]. TRACE contentslist command. Marks the named items for tracing. A message is printed whenever a traced procedure is invoked, giving the actual input values, and whenever a traced procedure STOPs or OUTPUTs. A message is printed whenever a new value is assigned to a traced variable using MAKE. A message is printed whenever a new property is given to a traced property list using PPROP. UNTRACE contentslist command. Turns off tracing for the named items. TRACEDP contentslist TRACED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is traced, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can TRACEDP [[] [VARIABLE]] or TRACEDP [[] [] [PROPLIST]]. STEP contentslist command. Marks the named items for stepping. Whenever a stepped procedure is invoked, each instruction line in the procedure body is printed before being executed, and Logo waits for the user to type a newline at the terminal. A message is printed whenever a stepped variable name is "shadowed" because a local variable of the same name is created either as a procedure input or by the LOCAL command. UNSTEP contentslist command. Turns off stepping for the named items. STEPPEDP contentslist STEPPED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is stepped, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can STEPPEDP [[] [VARIABLE]] or STEPPEDP [[] [] [PROPLIST]]. EDIT contentslist ED contentslist (EDIT) (ED) command. If invoked with an input, EDIT writes the definitions of the named items into a temporary file and edits that file, using your favorite editor as determined by the EDITOR environment variable. If you don't have an EDITOR variable, edits the definitions using jove. If invoked without an input, EDIT edits the same file left over from a previous EDIT or EDITFILE instruction. When you leave the editor, Logo reads the revised definitions and modifies the workspace accordingly. It is not an error if the input includes names for which there is no previous definition. If there is a variable LOADNOISILY whose value is TRUE, then, after leaving the editor, TO commands in the temporary file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. If there is an environment variable called TEMP, then Logo uses its value as the directory in which to write the temporary file used for editing. Exceptionally, the EDIT command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. EDITFILE filename command. Starts the Logo editor, like EDIT, but instead of editing a temporary file it edits the file specified by the input. When you leave the editor, Logo reads the revised file, as for EDIT. EDITFILE also remembers the filename, so that a subsequent EDIT command with no input will re-edit the same file. EDITFILE is intended as an alternative to LOAD and SAVE. You can maintain a workspace file yourself, controlling the order in which definitions appear, maintaining comments in the file, and so on. EDALL (library procedure) command. Abbreviates EDIT CONTENTS. EDPS (library procedure) command. Abbreviates EDIT PROCEDURES. EDNS (library procedure) command. Abbreviates EDIT NAMES. EDPLS (library procedure) command. Abbreviates EDIT PLISTS. EDN varname (library procedure) EDN varnamelist command. Abbreviates EDIT NAMELIST varname(list). EDPL plname (library procedure) EDPL plnamelist command. Abbreviates EDIT PLLIST plname(list). SAVE filename command. Saves the definitions of all unburied procedures, variables, and nonempty property lists in the named file. Equivalent to to save :filename local "oldwriter make "oldwriter writer openwrite :filename setwrite :filename poall setwrite :oldwriter close :filename end SAVEL contentslist filename (library procedure) command. Saves the definitions of the procedures, variables, and property lists specified by "contentslist" to the file named "filename". LOAD filename command. Reads instructions from the named file and executes them. The file can include procedure definitions with TO, and these are accepted even if a procedure by the same name already exists. If the file assigns a list value to a variable named STARTUP, then that list is run as an instructionlist after the file is loaded. If there is a variable LOADNOISILY whose value is TRUE, then TO commands in the file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. CSLSLOAD name command. Loads the named file, like LOAD, but from the directory containing the Computer Science Logo Style programs instead of the current user's directory. HELP name (HELP) command. Prints information from the reference manual about the primitive procedure named by the input. With no input, lists all the primitives about which help is available. If there is an environment variable LOGOHELP, then its value is taken as the directory in which to look for help files, instead of the default help directory. If HELP is called with the name of a defined procedure for which there is no help file, it will print the title line of the procedure followed by lines from the procedure body that start with semicolon, stopping when a non-semicolon line is seen. Exceptionally, the HELP command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. SETEDITOR path command. Tells Logo to use the specified program as its editor instead of the default editor. The format of a path depends on your operating system. SETLIBLOC path command. Tells Logo to use the specified directory as its library instead of the default. (Note that many Logo "primitive" procedures are actually found in the library, so they may become unavailable if your new library does not include them!) The format of a path depends on your operating system. SETHELPLOC path command. Tells Logo to look in the specified directory for the information provided by the HELP command, instead of the default directory. The format of a path depends on your operating system. SETCSLSLOC path command. Tells Logo to use the specified directory for the CSLSLOAD command, instead of the default directory. The format of a path depends on your operating system. SETTEMPLOC path command. Tells Logo to write editor temporary files in the specified directory rather than in the default directory. You must have write permission for this directory. The format of a path depends on your operating system. GC (GC anything) command. Runs the garbage collector, reclaiming unused nodes. Logo does this when necessary anyway, but you may want to use this command to control exactly when Logo does it. In particular, the numbers output by the NODES operation will not be very meaningful unless garbage has been collected. Another reason to use GC is that a garbage collection takes a noticeable fraction of a second, and you may want to schedule collections for times before or after some time-critical animation. If invoked with an input (of any value), GC runs a full garbage collection, including GCTWA (Garbage Collect Truly Worthless Atoms, which means that it removes from Logo's memory words that used to be procedure or variable names but aren't any more); without an input, GC does a generational garbage collection, which means that only recently created nodes are examined. (The latter is usually good enough.) .SETSEGMENTSIZE num command. Sets the number of nodes that Logo allocates from the operating system at once to num, which mush be a positive integer. The name is dotted because bad things will happen if you use a number that's too small or too large for your computer. The initial value is 16,000 for most systems, but is smaller for 68000-based Macs. Making it larger will speed up computations (by reducing the number of garbage collections) at the cost of allocating more memory than necessary. CONTROL STRUCTURES ================== Note: in the following descriptions, an "instructionlist" can be a list or a word. In the latter case, the word is parsed into list form before it is run. Thus, RUN READWORD or RUN READLIST will work. The former is slightly preferable because it allows for a continued line (with ~) that includes a comment (with ;) on the first line. A "tf" input must be the word TRUE, the word FALSE, or a list. If it's a list, then it must be a Logo expression, which will be evaluated to produce a value that must be TRUE or FALSE. The comparisons with TRUE and FALSE are always case-insensitive. RUN instructionlist command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs. RUNRESULT instructionlist runs the instructions in the input; outputs an empty list if those instructions produce no output, or a list whose only member is the output from running the input instructionlist. Useful for inventing command-or-operation control structures: local "result make "result runresult [something] if emptyp :result [stop] output first :result REPEAT num instructionlist command. Runs the "instructionlist" repeatedly, "num" times. FOREVER instructionlist command. Runs the "instructionlist" repeatedly, until something inside the instructionlist (such as STOP or THROW) makes it stop. REPCOUNT outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs -1. IF tf instructionlist (IF tf instructionlist1 instructionlist2) command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE. For compatibility with earlier versions of Logo, if an IF instruction is not enclosed in parentheses, but the first thing on the instruction line after the second input expression is a literal list (i.e., a list in square brackets), the IF is treated as if it were IFELSE, but a warning message is given. If this aberrant IF appears in a procedure body, the warning is given only the first time the procedure is invoked in each Logo session. IFELSE tf instructionlist1 instructionlist2 command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value. TEST tf command. Remembers its input, which must be TRUE or FALSE, for use by later IFTRUE or IFFALSE instructions. The effect of TEST is local to the procedure in which it is used; any corresponding IFTRUE or IFFALSE must be in the same procedure or a subprocedure. IFTRUE instructionlist IFT instructionlist command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure. IFFALSE instructionlist IFF instructionlist command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure. STOP command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value. OUTPUT value OP value command. Ends the running of the procedure in which it appears. That procedure outputs the value "value" to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation. CATCH tag instructionlist command or operation. Runs its second input. Outputs if that instructionlist outputs. If, while running the instructionlist, a THROW instruction is executed with a tag equal to the first input (case-insensitive comparison), then the running of the instructionlist is terminated immediately. In this case the CATCH outputs if a value input is given to THROW. The tag must be a word. If the tag is the word ERROR, then any error condition that arises during the running of the instructionlist has the effect of THROW "ERROR instead of printing an error message and returning to toplevel. The CATCH does not output if an error is caught. Also, during the running of the instructionlist, the variable ERRACT is temporarily unbound. (If there is an error while ERRACT has a value, that value is taken as an instructionlist to be run after printing the error message. Typically the value of ERRACT, if any, is the list [PAUSE].) THROW tag (THROW tag value) command. Must be used within the scope of a CATCH with an equal tag. Ends the running of the instructionlist of the CATCH. If THROW is used with only one input, the corresponding CATCH does not output a value. If THROW is used with two inputs, the second provides an output for the CATCH. THROW "TOPLEVEL can be used to terminate all running procedures and interactive pauses, and return to the toplevel instruction prompt. Typing the system interrupt character (normally control-C for Unix, control-Q for DOS, or command-period for Mac) has the same effect. THROW "ERROR can be used to generate an error condition. If the error is not caught, it prints a message (THROW "ERROR) with the usual indication of where the error (in this case the THROW) occurred. If a second input is used along with a tag of ERROR, that second input is used as the text of the error message instead of the standard message. Also, in this case, the location indicated for the error will be, not the location of the THROW, but the location where the procedure containing the THROW was invoked. This allows user-defined procedures to generate error messages as if they were primitives. Note: in this case the corresponding CATCH "ERROR, if any, does not output, since the second input to THROW is not considered a return value. THROW "SYSTEM immediately leaves Logo, returning to the operating system, without printing the usual parting message and without deleting any editor temporary file written by EDIT. ERROR outputs a list describing the error just caught, if any. If there was not an error caught since the last use of ERROR, the empty list will be output. The error list contains four members: an integer code corresponding to the type of error, the text of the error message, the name of the procedure in which the error occurred, and the instruction line on which the error occurred. PAUSE command or operation. Enters an interactive pause. The user is prompted for instructions, as at toplevel, but with a prompt that includes the name of the procedure in which PAUSE was invoked. Local variables of that procedure are available during the pause. PAUSE outputs if the pause is ended by a CONTINUE with an input. If the variable ERRACT exists, and an error condition occurs, the contents of that variable are run as an instructionlist. Typically ERRACT is given the value [PAUSE] so that an interactive pause will be entered on the event of an error. This allows the user to check values of local variables at the time of the error. Typing the system quit character (normally control-\ for Unix, control-W for DOS, or command-comma for Mac) will also enter a pause. CONTINUE value CO value (CONTINUE) (CO) command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output. Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. WAIT time command. Delays further execution for "time" 60ths of a second. Also causes any buffered characters destined for the terminal to be printed immediately. WAIT 0 can be used to achieve this buffer flushing without actually waiting. BYE command. Exits from Logo; returns to the operating system. .MAYBEOUTPUT value (special form) works like OUTPUT except that the expression that provides the input value might not, in fact, output a value, in which case the effect is like STOP. This is intended for use in control structure definitions, for cases in which you don't know whether or not some expression produces a value. Example: to invoke :function [:inputs] 2 .maybeoutput apply :function :inputs end ? (invoke "print "a "b "c) a b c ? print (invoke "word "a "b "c) abc This is an alternative to RUNRESULT. It's fast and easy to use, at the cost of being an exception to Logo's evaluation rules. (Ordinarily, it should be an error if the expression that's supposed to provide an input to something doesn't have a value.) GOTO word command. Looks for a TAG command with the same input in the same procedure, and continues running the procedure from the location of that TAG. It is meaningless to use GOTO outside of a procedure. TAG quoted.word command. Does nothing. The input must be a literal word following a quotation mark ("), not the result of a computation. Tags are used by the GOTO command. IGNORE value (library procedure) command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant. ` list (library procedure) outputs a list equal to its input but with certain substitutions. If a member of the input list is the word "," (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word ",@" (comma atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the ,@ and the instructionlist. Example: show `[foo baz ,[bf [a b c]] garply ,@[bf [a b c]]] will print [foo baz [b c] garply b c] A word starting with , or ,@ is treated as if the rest of the word were a one-word list, e.g., ,:FOO is equivalent to ,[:FOO]. A word starting with ", (quote comma) or :, (colon comma) becomes a word starting with " or : but with the result of running the substitution (or its first word, if the result is a list) replacing what comes after the comma. Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found: ? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f] [a ` [b , [1+2] , [foo 4 d] e] f] ?make "name1 "x ?make "name2 "y ? show `[a `[b ,:,:name1 ,",:name2 d] e] [a ` [b , [:x] , ["y] d] e] FOR forcontrol instructionlist (library procedure) command. The first input must be a list containing three or four members: (1) a word, which will be used as the name of a local variable; (2) a word or list that will be evaluated as by RUN to determine a number, the starting value of the variable; (3) a word or list that will be evaluated to determine a number, the limit value of the variable; (4) an optional word or list that will be evaluated to determine the step size. If the fourth member is missing, the step size will be 1 or -1 depending on whether the limit value is greater than or less than the starting value, respectively. The second input is an instructionlist. The effect of FOR is to run that instructionlist repeatedly, assigning a new value to the control variable (the one named by the first member of the forcontrol list) each time. First the starting value is assigned to the control variable. Then the value is compared to the limit value. FOR is complete when the sign of (current - limit) is the same as the sign of the step size. (If no explicit step size is provided, the instructionlist is always run at least once. An explicit step size can lead to a zero-trip FOR, e.g., FOR [I 1 0 1] ...) Otherwise, the instructionlist is run, then the step is added to the current value of the control variable and FOR returns to the comparison step. ? for [i 2 7 1.5] [print :i] 2 3.5 5 6.5 ? DO.WHILE instructionlist tfexpression (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains TRUE. Evaluates the first input first, so the "instructionlist" is always run at least once. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. WHILE tfexpression instructionlist (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains TRUE. Evaluates the first input first, so the "instructionlist" may never be run at all. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. DO.UNTIL instructionlist tfexpression (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains FALSE. Evaluates the first input first, so the "instructionlist" is always run at least once. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. UNTIL tfexpression instructionlist (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains FALSE. Evaluates the first input first, so the "instructionlist" may never be run at all. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. CASE value clauses (library procedure) command or operation. The second input is a list of lists (clauses); each clause is a list whose first element is either a list of values or the word ELSE and whose butfirst is a Logo expression or instruction. CASE examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. If the first input to CASE is a member of the first element of a clause, then the butfirst of that clause is evaluated and CASE outputs its value, if any. If neither of these conditions is met, then CASE goes on to the next clause. If no clause is satisfied, CASE does nothing. Example: to vowelp :letter output case :letter [ [[a e i o u] "true] [else "false] ] end COND clauses (library procedure) command or operation. The input is a list of lists (clauses); each clause is a list whose first element is either an expression whose value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo expression or instruction. COND examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. Otherwise, the first element of the clause is evaluated; the resulting value must be TRUE or FALSE. If it's TRUE, then the butfirst of that clause is evaluated and COND outputs its value, if any. If the value is FALSE, then COND goes on to the next clause. If no clause is satisfied, COND does nothing. Example: to evens :numbers ; select even numbers from a list op cond [ [[emptyp :numbers] []] [[evenp first :numbers] ; assuming EVENP is defined fput first :numbers evens butfirst :numbers] [else evens butfirst :numbers] ] end TEMPLATE-BASED ITERATION ------------------------ The procedures in this section are iteration tools based on the idea of a "template." This is a generalization of an instruction list or an expression list in which "slots" are provided for the tool to insert varying data. Four different forms of template can be used. The most commonly used form for a template is "explicit-slot" form, or "question mark" form. Example: ? show map [? * ?] [2 3 4 5] [4 9 16 25] ? In this example, the MAP tool evaluated the template [? * ?] repeatedly, with each of the members of the data list [2 3 4 5] substituted in turn for the question marks. The same value was used for every question mark in a given evaluation. Some tools allow for more than one datum to be substituted in parallel; in these cases the slots are indicated by ?1 for the first datum, ?2 for the second, and so on: ? show (map [(word ?1 ?2 ?1)] [a b c] [d e f]) [ada beb cfc] ? If the template wishes to compute the datum number, the form (? 1) is equivalent to ?1, so (? ?1) means the datum whose number is given in datum number 1. Some tools allow additional slot designations, as shown in the individual descriptions. The second form of template is the "named-procedure" form. If the template is a word rather than a list, it is taken as the name of a procedure. That procedure must accept a number of inputs equal to the number of parallel data slots provided by the tool; the procedure is applied to all of the available data in order. That is, if data ?1 through ?3 are available, the template "PROC is equivalent to [PROC ?1 ?2 ?3]. ? show (map "word [a b c] [d e f]) [ad be cf] ? to dotprod :a :b ; vector dot product op apply "sum (map "product :a :b) end The third form of template is "named-slot" or "lambda" form. This form is indicated by a template list containing more than one member, whose first member is itself a list. The first member is taken as a list of names; local variables are created with those names and given the available data in order as their values. The number of names must equal the number of available data. This form is needed primarily when one iteration tool must be used within the template list of another, and the ? notation would be ambiguous in the inner template. Example: to matmul :m1 :m2 [:tm2 transpose :m2] ; multiply two matrices output map [[row] map [[col] dotprod :row :col] :tm2] :m1 end The fourth form is "procedure text" form, a variant of lambda form. In this form, the template list contains at least two members, all of which are lists. This is the form used by the DEFINE and TEXT primitives, and APPLY accepts it so that the text of a defined procedure can be used as a template. Note: The fourth form of template is interpreted differently from the others, in that Logo considers it to be an independent defined procedure for the purposes of OUTPUT and STOP. For example, the following two instructions are identical: ? print apply [[x] :x+3] [5] 8 ? print apply [[x] [output :x+3]] [5] 8 although the first instruction is in named-slot form and the second is in procedure-text form. The named-slot form can be understood as telling Logo to evaluate the expression :x+3 in place of the entire invocation of apply, with the variable x temporarily given the value 5. The procedure-text form can be understood as invoking the procedure to foo :x output :x+3 end with input 5, but without actually giving the procedure a name. If the use of OUTPUT were interchanged in these two examples, we'd get errors: ? print apply [[x] output :x+3] [5] Can only use output inside a procedure ? print apply [[x] [:x+3]] [5] You don't say what to do with 8 The named-slot form can be used with STOP or OUTPUT inside a procedure, to stop the enclosing procedure. The following iteration tools are extended versions of the ones in Appendix B of the book _Computer_Science_Logo_Style,_Volume_3:_Advanced_Topics_ by Brian Harvey [MIT Press, 1987]. The extensions are primarily to allow for variable numbers of inputs. APPLY template inputlist command or operation. Runs the "template," filling its slots with the members of "inputlist." The number of members in "inputlist" must be an acceptable number of slots for "template." It is illegal to apply the primitive TO as a template, but anything else is okay. APPLY outputs what "template" outputs, if anything. INVOKE template input (library procedure) (INVOKE template input1 input2 ...) command or operation. Exactly like APPLY except that the inputs are provided as separate expressions rather than in a list. FOREACH data template (library procedure) (FOREACH data1 data2 ... template) command. Evaluates the template list repeatedly, once for each member of the data list. If more than one data list are given, each of them must be the same length. (The data inputs can be words, in which case the template is evaluated once for each character. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. MAP template data (library procedure) (MAP template data1 data2 ...) outputs a word or list, depending on the type of the data input, of the same length as that data input. (If more than one data input are given, the output is of the same type as data1.) Each member of the output is the result of evaluating the template list, filling the slots with the corresponding member(s) of the data input(s). (All data inputs must be the same length.) In the case of a word output, the results of the template evaluation must be words, and they are concatenated with WORD. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. MAP.SE template data (library procedure) (MAP.SE template data1 data2 ...) outputs a list formed by evaluating the template list repeatedly and concatenating the results using SENTENCE. That is, the members of the output are the members of the results of the evaluations. The output list might, therefore, be of a different length from that of the data input(s). (If the result of an evaluation is the empty list, it contributes nothing to the final output.) The data inputs may be words or lists. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. FILTER tftemplate data (library procedure) outputs a word or list, depending on the type of the data input, containing a subset of the members (for a list) or characters (for a word) of the input. The template is evaluated once for each member or character of the data, and it must produce a TRUE or FALSE value. If the value is TRUE, then the corresponding input constituent is included in the output. ? print filter "vowelp "elephant eea ? In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. FIND tftemplate data (library procedure) outputs the first constituent of the data input (the first member of a list, or the first character of a word) for which the value produced by evaluating the template with that consituent in its slot is TRUE. If there is no such constituent, the empty list is output. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. REDUCE template data (library procedure) outputs the result of applying the template to accumulate the members of the data input. The template must be a two-slot function. Typically it is an associative function name like "SUM. If the data input has only one constituent (member in a list or character in a word), the output is that consituent. Otherwise, the template is first applied with ?1 filled with the next-to-last consitient and ?2 with the last constituent. Then, if there are more constituents, the template is applied with ?1 filled with the next constituent to the left and ?2 with the result from the previous evaluation. This process continues until all constituents have been used. The data input may not be empty. Note: If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs: to max :a :b output ifelse :a > :b [:a] [:b] end print reduce "max [...] Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does: to max [:inputs] 2 if emptyp :inputs ~ [(throw "error [not enough inputs to max])] output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs end CROSSMAP template listlist (library procedure) (CROSSMAP template data1 data2 ...) outputs a list containing the results of template evaluations. Each data list contributes to a slot in the template; the number of slots is equal to the number of data list inputs. As a special case, if only one data list input is given, that list is taken as a list of data lists, and each of its members contributes values to a slot. CROSSMAP differs from MAP in that instead of taking members from the data inputs in parallel, it takes all possible combinations of members of data inputs, which need not be the same length. ? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4]) [a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4] ? For compatibility with the version in the first edition of CSLS, CROSSMAP templates may use the notation :1 instead of ?1 to indicate slots. CASCADE endtest template startvalue (library procedure) (CASCADE endtest tmp1 sv1 tmp2 sv2 ...) (CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate) outputs the result of applying a template (or several templates, as explained below) repeatedly, with a given value filling the slot the first time, and the result of each application filling the slot for the following application. In the simplest case, CASCADE has three inputs. The second input is a one-slot expression template. That template is evaluated some number of times (perhaps zero). On the first evaluation, the slot is filled with the third input; on subsequent evaluations, the slot is filled with the result of the previous evaluation. The number of evaluations is determined by the first input. This can be either a nonnegative integer, in which case the template is evaluated that many times, or a predicate expression template, in which case it is evaluated (with the same slot filler that will be used for the evaluation of the second input) repeatedly, and the CASCADE evaluation continues as long as the predicate value is FALSE. (In other words, the predicate template indicates the condition for stopping.) If the template is evaluated zero times, the output from CASCADE is the third (startvalue) input. Otherwise, the output is the value produced by the last template evaluation. CASCADE templates may include the symbol # to represent the number of times the template has been evaluated. This slot is filled with 1 for the first evaluation, 2 for the second, and so on. ? show cascade 5 [lput # ?] [] [1 2 3 4 5] ? show cascade [vowelp first ?] [bf ?] "spring ing ? show cascade 5 [# * ?] 1 120 ? Several cascaded results can be computed in parallel by providing additional template-startvalue pairs as inputs to CASCADE. In this case, all templates (including the endtest template, if used) are multi-slot, with the number of slots equal to the number of pairs of inputs. In each round of evaluations, ?2 represents the result of evaluating the second template in the previous round. If the total number of inputs (including the first endtest input) is odd, then the output from CASCADE is the final value of the first template. If the total number of inputs is even, then the last input is a template that is evaluated once, after the end test is satisfied, to determine the output from CASCADE. to fibonacci :n output (cascade :n [?1 + ?2] 1 [?1] 0) end to piglatin :word output (cascade [vowelp first ?] ~ [word bf ? first ?] ~ :word ~ [word ? "ay]) end CASCADE.2 endtest temp1 startval1 temp2 startval2 (library procedure) outputs the result of invoking CASCADE with the same inputs. The only difference is that the default number of inputs is five instead of three. TRANSFER endtest template inbasket (library procedure) outputs the result of repeated evaluation of the template. The template is evaluated once for each member of the list "inbasket." TRANSFER maintains an "outbasket" that is initially the empty list. After each evaluation of the template, the resulting value becomes the new outbasket. In the template, the symbol ?IN represents the current member from the inbasket; the symbol ?OUT represents the entire current outbasket. Other slot symbols should not be used. If the first (endtest) input is an empty list, evaluation continues until all inbasket members have been used. If not, the first input must be a predicate expression template, and evaluation continues until either that template's value is TRUE or the inbasket is used up. MACROS ====== .MACRO procname :input1 :input2 ... (special form) .DEFMACRO procname text A macro is a special kind of procedure whose output is evaluated as Logo instructions in the context of the macro's caller. .MACRO is exactly like TO except that the new procedure becomes a macro; .DEFMACRO is exactly like DEFINE with the same exception. Macros are useful for inventing new control structures comparable to REPEAT, IF, and so on. Such control structures can almost, but not quite, be duplicated by ordinary Logo procedures. For example, here is an ordinary procedure version of REPEAT: to my.repeat :num :instructions if :num=0 [stop] run :instructions my.repeat :num-1 :instructions end This version works fine for most purposes, e.g., my.repeat 5 [print "hello] But it doesn't work if the instructions to be carried out include OUTPUT, STOP, or LOCAL. For example, consider this procedure: to example print [Guess my secret word. You get three guesses.] repeat 3 [type "|?? | ~ if readword = "secret [pr "Right! stop]] print [Sorry, the word was "secret"!] end This procedure works as written, but if MY.REPEAT is used instead of REPEAT, it won't work because the STOP will stop MY.REPEAT instead of stopping EXAMPLE as desired. The solution is to make MY.REPEAT a macro. Instead of actually carrying out the computation, a macro must return a list containing Logo instructions. The contents of that list are evaluated as if they appeared in place of the call to the macro. Here's a macro version of REPEAT: .macro my.repeat :num :instructions if :num=0 [output []] output sentence :instructions ~ (list "my.repeat :num-1 :instructions) end Every macro is an operation -- it must always output something. Even in the base case, MY.REPEAT outputs an empty instruction list. To show how MY.REPEAT works, let's take the example my.repeat 5 [print "hello] For this example, MY.REPEAT will output the instruction list [print "hello my.repeat 4 [print "hello]] Logo then executes these instructions in place of the original invocation of MY.REPEAT; this prints "hello" once and invokes another repetition. The technique just shown, although fairly easy to understand, has the defect of slowness because each repetition has to construct an instruction list for evaluation. Another approach is to make my.repeat a macro that works just like the non-macro version unless the instructions to be repeated include OUTPUT or STOP: .macro my.repeat :num :instructions catch "repeat.catchtag ~ [op repeat.done runresult [repeat1 :num :instructions]] op [] end to repeat1 :num :instructions if :num=0 [throw "repeat.catchtag] run :instructions .maybeoutput repeat1 :num-1 :instructions end to repeat.done :repeat.result if emptyp :repeat.result [op [stop]] op list "output quoted first :repeat.result end If the instructions do not include STOP or OUTPUT, then REPEAT1 will reach its base case and invoke THROW. As a result, my.repeat's last instruction line will output an empty list, so the second evaluation of the macro result will do nothing. But if a STOP or OUTPUT happens, then REPEAT.DONE will output a STOP or OUTPUT instruction that will be re-executed in the caller's context. The macro-defining commands have names starting with a dot because macros are an advanced feature of Logo; it's easy to get in trouble by defining a macro that doesn't terminate, or by failing to construct the instruction list properly. Lisp users should note that Logo macros are NOT special forms. That is, the inputs to the macro are evaluated normally, as they would be for any other Logo procedure. It's only the output from the macro that's handled unusually. Here's another example: .macro localmake :name :value output (list "local ~ word "" :name ~ "apply ~ ""make ~ (list :name :value)) end It's used this way: to try localmake "garply "hello print :garply end LOCALMAKE outputs the list [local "garply apply "make [garply hello]] The reason for the use of APPLY is to avoid having to decide whether or not the second input to MAKE requires a quotation mark before it. (In this case it would -- MAKE "GARPLY "HELLO -- but the quotation mark would be wrong if the value were a list.) It's often convenient to use the ` function to construct the instruction list: .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end On the other hand, ` is pretty slow, since it's tree recursive and written in Logo. MACROP name MACRO? name outputs TRUE if its input is the name of a macro. MACROEXPAND expr (library procedure) takes as its input a Logo expression that invokes a macro (that is, one that begins with the name of a macro) and outputs the the Logo expression into which the macro would translate the input expression. .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end ? show macroexpand [localmake "pi 3.14159] [local "pi apply "make [pi 3.14159]] ERROR PROCESSING ================ If an error occurs, Logo takes the following steps. First, if there is an available variable named ERRACT, Logo takes its value as an instructionlist and runs the instructions. The operation ERROR may be used within the instructions (once) to examine the error condition. If the instructionlist invokes PAUSE, the error message is printed before the pause happens. Certain errors are "recoverable"; for one of those errors, if the instructionlist outputs a value, that value is used in place of the expression that caused the error. (If ERRACT invokes PAUSE and the user then invokes CONTINUE with an input, that input becomes the output from PAUSE and therefore the output from the ERRACT instructionlist.) It is possible for an ERRACT instructionlist to produce an inappropriate value or no value where one is needed. As a result, the same error condition could recur forever because of this mechanism. To avoid that danger, if the same error condition occurs twice in a row from an ERRACT instructionlist without user interaction, the message "Erract loop" is printed and control returns to toplevel. "Without user interaction" means that if ERRACT invokes PAUSE and the user provides an incorrect value, this loop prevention mechanism does not take effect and the user gets to try again. During the running of the ERRACT instructionlist, ERRACT is locally unbound, so an error in the ERRACT instructions themselves will not cause a loop. In particular, an error during a pause will not cause a pause-within-a-pause unless the user reassigns the value [PAUSE] to ERRACT during the pause. But such an error will not return to toplevel; it will remain within the original pause loop. If there is no available ERRACT value, Logo handles the error by generating an internal THROW "ERROR. (A user program can also generate an error condition deliberately by invoking THROW.) If this throw is not caught by a CATCH "ERROR in the user program, it is eventually caught either by the toplevel instruction loop or by a pause loop, which prints the error message. An invocation of CATCH "ERROR in a user program locally unbinds ERRACT, so the effect is that whichever of ERRACT and CATCH "ERROR is more local will take precedence. If a floating point overflow occurs during an arithmetic operation, or a two-input mathematical function (like POWER) is invoked with an illegal combination of inputs, the "doesn't like" message refers to the second operand, but should be taken as meaning the combination. ERROR CODES ----------- Here are the numeric codes that appear as the first member of the list output by ERROR when an error is caught, with the corresponding messages. Some messages may have two different codes depending on whether or not the error is recoverable (that is, a substitute value can be provided through the ERRACT mechanism) in the specific context. Some messages are warnings rather than errors; these will not be caught. Errors 0 and 32 are so bad that Logo exits immediately. 0 Fatal internal error (can't be caught) 1 Out of memory 2 Stack overflow 3 Turtle out of bounds 4 PROC doesn't like DATUM as input (not recoverable) 5 PROC didn't output to PROC 6 Not enough inputs to PROC 7 PROC doesn't like DATUM as input (recoverable) 8 Too much inside ()'s 9 You don't say what to do with DATUM 10 ')' not found 11 VAR has no value 12 Unexpected ')' 13 I don't know how to PROC (recoverable) 14 Can't find catch tag for THROWTAG 15 PROC is already defined 16 Stopped 17 Already dribbling 18 File system error 19 Assuming you mean IFELSE, not IF (warning only) 20 VAR shadowed by local in procedure call (warning only) 21 Throw "Error 22 PROC is a primitive 23 Can't use TO inside a procedure 24 I don't know how to PROC (not recoverable) 25 IFTRUE/IFFALSE without TEST 26 Unexpected ']' 27 Unexpected '}' 28 Couldn't initialize graphics 29 Macro returned VALUE instead of a list 30 You don't say what to do with VALUE 31 Can only use STOP or OUTPUT inside a procedure 32 APPLY doesn't like BADTHING as input 33 END inside multi-line instruction 34 Really out of memory (can't be caught) SPECIAL VARIABLES ================= Logo takes special action if any of the following variable names exists. They follow the normal scoping rules, so a procedure can locally set one of them to limit the scope of its effect. Initially, no variables exist except for ALLOWGETSET, CASEIGNOREDP, and UNBURYONEDIT, which are TRUE and buried. ALLOWGETSET (variable) if TRUE, indicates that an attempt to use a procedure that doesn't exist should be taken as an implicit getter or setter procedure (setter if the first three letters of the name are SET) for a variable of the same name (without the SET if appropriate). CASEIGNOREDP (variable) if TRUE, indicates that lower case and upper case letters should be considered equal by EQUALP, BEFOREP, MEMBERP, etc. Logo initially makes this variable TRUE, and buries it. ERRACT (variable) an instructionlist that will be run in the event of an error. Typically has the value [PAUSE] to allow interactive debugging. FULLPRINTP (variable) if TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.) LOADNOISILY (variable) if TRUE, prints the names of procedures defined when loading from a file (including the temporary file made by EDIT). PRINTDEPTHLIMIT (variable) if a nonnegative integer, indicates the maximum depth of sublist structure that will be printed by PRINT, etc. PRINTWIDTHLIMIT (variable) if a nonnegative integer, indicates the maximum number of members in any one list that will be printed by PRINT, etc. REDEFP (variable) if TRUE, allows primitives to be erased (ERASE) or redefined (COPYDEF). STARTUP (variable) if assigned a list value in a file loaded by LOAD, that value is run as an instructionlist after the loading. UNBURYONEDIT (variable) if TRUE, causes any procedure defined during EDIT or LOAD to be unburied, so that it will be saved by a later SAVE. Files that want to define and bury procedures must do it in that order. USEALTERNATENAMES (variable) if TRUE, causes Logo to generate non-English words (from the Messages file) instead of TRUE, FALSE, END, etc. Logo provides the following buried variables that can be used by programs: LOGOVERSION (variable) a real number indicating the Logo version number, e.g., 5.5 LOGOPLATFORM (variable) one of the following words: X11, Windows, or Unix-Nographics. INTERNATIONALIZATION ==================== Berkeley Logo has limited support for non-English-speaking users. Alas, there is no Unicode support, and high-bit-on ASCII codes work in some contexts but not others. If you want to translate Berkeley Logo for use with another language, there are three main things you have to do: 1. Primitive names 2. Error (and other) messages 3. Documentation For primitive names, the easiest thing is to provide a startup file that defines aliases for the English primitive names, using COPYDEF: COPYDEF "AVANT "FORWARD This should take care of it, unless your language's name for one primitive is spelled like the English name of a different primitive. In that case you have to turn REDEFP on and be sure to copy the non-conflicting name before overwriting the conflicting one! "Primitives" that are actually in the Logo library, of course, can just be replaced or augmented with native-language-named Logo procedures and filenames. Of course Logo programs will still not look like your native language if the word order is dramatically different, especially if you don't put verbs before their objects. For error messages, there is a file named Messages in the logolib directory with texts of messages, one per line. You can replace this with a file for your own language. Do not add, delete, or reorder lines; Logo finds messages by line number. The sequences %p, %s, and %t in these messages represent variable parts of the message and should not be translated. (%p PRINTs the variable part, while %s SHOWs it -- that is, the difference is about whether or not brackets are shown surrounding a list. %t means that the variable part is a C text string rather than a Logo object.) If you want to change the order of two variable parts (no reorderable message has more than two), you would for example replace the line %p doesn't like %s as input with %+s is a lousy input to %p The plus sign tells the message printer to reverse the order; you must reverse the order of %p and %s, if both are used, to match. The plus sign goes just after the first percent sign in the message, which might not be at the beginning of the line. The sequence \n in a message represents a newline; don't be fooled into thinking that the "n" is part of the following word. Some messages appear twice in the file; this isn't a mistake. The two spaces before "to" in "I don't know how to" aren't a mistake either. The message containing just "%p" is for user-provided error messages in THROW "ERROR. The message " in %s\n%s" is the part of all error messages that indicates where the error occurred if it was inside a procedure; you might want to change the word "in" to your language. "%s defined\n" is what LOAD prints for each procedure defined if the variable LOADNOISILY is TRUE. "to %p\nend\n\n" is what EDIT puts in the temporary file if you ask to edit a procedure that isn't already defined. Also in the Messages file are lines containing only one word each; the first of these is the word "true". Some of these words are recognized by Logo in user input; some are generated by Logo; some are both. For example, the words TRUE and FALSE are recognized as Boolean values by IF and IFELSE, and are also generated by Logo as outputs from the primitive predicates such as EQUALP. The word END is recognized as the end of a procedure definition, and may be generated when Logo reconstructs a procedure body for PO or EDIT. I've used capital letters in this paragraph for easier reading, but the words in the Messages file should be in lower case. If you replace these with non-English words, Logo will *recognize* both the English names and your alternate names. For example, if you replace the word "true" with "vrai" then Logo will understand both of these: IF "TRUE [PRINT "YES] IF "VRAI [PRINT "YES] The variable UseAlternateNames determines whether Logo will *generate* other-language names -- for example, whether predicate functions return the other-language alternates for TRUE and FALSE. This variable is FALSE by default, meaning that the English words will be generated. You might wish to have English-named predicate functions generate English TRUE and FALSE, while other-language-named predicates generate the alternate words. This can be done by leaving UseAlternateNames false, and instead of defining the other-language predicates with COPYDEF, do it this way: to french.boolean :bool if equalp :bool "true [output "vrai] if equalp :bool "false [output "faux] output :bool ; shouldn't happen end to make.french.predicate :french :english :arity define :french `[[[inputs] ,[:arity]] [output french.boolean apply ,[word "" :english] :inputs]] end ? make.french.predicate "egal? "equal? 2 ? pr egal? 3 4 faux ? pr egal? 4 4 vrai ? pr equal? 3 4 false ? pr equal? 4 4 true The third input to make.french.predicate is the number of inputs that the predicate expects. This solution isn't quite perfect because the infix predicates (=, <, >) will still output in English. If you want them to generate alternate-language words, set UseAlternateNames to TRUE instead. Some of the words in this section of the Messages file are names of Logo primitives (OUTPUT, STOP, GOTO, TAG, IF, IFELSE, TO, .MACRO). To translate these names, you must use COPYDEF as described earlier, in addition to changing the names in Messages. You should be consistent in these two steps. Don't forget the period in ".macro"! For documentation, there are two kinds: this manual and the help files. The latter are generated automatically from this manual if you have a Unix system, so in that case you need only translate this manual, maintaining the format. (The automatic helpfile generator notices things like capital letters, tabs, hyphens, and equal signs at the beginnings of lines.) The program makefile.c may require modification because a few of the primitive names are special cases (e.g., LOG10 is the only name with digits included). If you don't have Unix tools, you can just translate each helpfile individually. A period in a primitive name is represented as a D in the filename; there are no files for question marks because the HELP command looks for the file named after the corresponding primitive that ends in P. ucblogo-5.5/makefile.in0100644000161300001330000000470010153115633013034 0ustar bhdoeCC = @CC@ CFLAGS = @CFLAGS@ @CPPFLAGS@ @X_CFLAGS@ -O0 LDFLAGS = @LDFLAGS@ LIBS = @X_PRE_LIBS@ @X_LIBS@ @LIBS@ @X_EXTRA_LIBS@ prefix = @prefix@ BINDIR = $(prefix)/bin LIBLOC = $(prefix)/lib/logo MAKE = @MAKE@ # LIBLOC = `pwd` OBJS = coms.o error.o eval.o files.o graphics.o init.o intern.o \ libloc.o lists.o logodata.o main.o math.o mem.o paren.o parse.o \ print.o term.o wrksp.o xgraphics.o nographics.o SRCS = coms.c error.c eval.c files.c graphics.c init.c intern.c \ libloc.c lists.c logodata.c main.c math.c mem.c paren.c parse.c \ print.c term.c wrksp.c xgraphics.c nographics.c HDRS = globals.h logo.h xgraphics.h all: logo logolib/Messages helpfiles helpfiles/HELPCONTENTS logo-mode make-docs mem.o: mem.c $(CC) $(CFLAGS) -O0 -c mem.c logo: $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o logo tags: $(SRCS) ctags --format=1 -N $(SRCS) $(HDRS) # ctags -t $(SRCS) $(HDRS) libloc.c: echo 'char *libloc="'$(LIBLOC)'/logolib";' > libloc.c echo 'char *helploc="'$(LIBLOC)'/helpfiles";' >> libloc.c echo 'char *cslsloc="'$(LIBLOC)'/csls";' >> libloc.c echo 'char *temploc="/tmp";' >> libloc.c echo 'char *separator="/";' >> libloc.c logolib/Messages: makelib Messages chmod +x makelib ./makelib cp -f Messages logolib helpfiles: mkdir helpfiles helpfiles/HELPCONTENTS: makehelp usermanual ./makehelp sort helptemp | pr -5 -t -w80 >> helpfiles/HELPCONTENTS rm helptemp makehelp: makehelp.c $(CC) -o makehelp makehelp.c clean: rm -f *.o libloc.c cd emacs; $(MAKE) clean ship: rm -f config.h config.cache config.log config.status rm -f makefile makehelp logo *.o libloc.c cd emacs; $(MAKE) ship cd docs; $(MAKE) ship install: all for d in $(BINDIR) $(LIBLOC) $(LIBLOC)/logolib $(LIBLOC)/helpfiles $(LIBLOC)/csls; do [ -d $$d ] || mkdir -p $$d || exit 1; done cp logo $(BINDIR)/. cp -f logolib/* $(LIBLOC)/logolib/. cp -f helpfiles/* $(LIBLOC)/helpfiles/. cp -f csls/* $(LIBLOC)/csls/. (cd emacs; prefix=$(prefix) LIBLOC=$(LIBLOC) BINDIR=$(BINDIR) $(MAKE) install) (cd docs; prefix=$(prefix) LIBLOC=$(LIBLOC) BINDIR=$(BINDIR) $(MAKE) install) # prefix=$(prefix); LIBLOC=$(LIBLOC); BINDIR=$(BINDIR); export prefix LIBLOC BINDIR; cd emacs; $(MAKE) install logo-mode: (cd emacs; prefix=$(prefix) LIBLOC=$(LIBLOC) BINDIR=$(BINDIR) $(MAKE)) # @prefix=$(prefix); LIBLOC=$(LIBLOC); BINDIR=$(BINDIR); export prefix LIBLOC BINDIR; cd emacs; $(MAKE) make-docs: (cd docs; prefix=$(prefix) LIBLOC=$(LIBLOC) $(MAKE) all) ucblogo-5.5/README0100644000161300001330000001307207616566044011631 0ustar bhdoeBERKELEY LOGO INTERPRETER Installation guide for Unix systems * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. This version of Logo is designed for a machine with adequate memory. It is not likely to be usable as the basis for a 64K microcomputer implementation. The interpreter was written primarily by Daniel Van Blerkom, Brian Harvey, Michael Katz, and Douglas Orleans. Thanks to Fred Gilham for the X11 code. Emacs logo-mode by Hrvoje Blazevic. Send comments by e-mail to bh@cs.berkeley.edu. The Unix distribution includes a shell script called "configure" that customizes Logo for your particular version of Unix. Just type the name "./configure" at a shell prompt. The script performs various tests to see whether particular libraries, etc., are available. Logo assumes that you will install it in /usr/local/{bin,lib,info}. If you would rather move these subdirectories somewhere else, then instead of saying "./configure" you should say, e.g., ./configure --prefix=/usr to install into /usr/{bin,lib,info}, or ./configure --prefix=/home/users/bh to install into /home/users/bh/{bin,lib,info}. The configure script writes several files. The most important are makefile used to compile Logo config.h header file used by C source files Note: It also writes a file "config.cache" in which it remembers the results of its tests. If you copy the Logo source directory to another machine with a different version of Unix and try to recompile, you should remove config.cache before running configure. With these files in place you should be able to say "make" to the shell and get four results: logo executable Logo interpreter logolib directory with pseudo-primitives in Logo helpfiles directory with online documentation emacs directory with Emacs logo-mode files and documentation in various formats Alternatively, just say "make logo" if you want to preserve the included logolib and helpfiles. The makefile compiles with optimization turned off. This is necessary to avoid mysterious garbage collection failures. (NOTE: On my HP 712, for reasons I don't understand, I had to compile the entire interpreter without optimization. But on other platforms, such as PCs running Linux and FreeBSD, it's sufficient merely to un-optimize mem.c. If that works on your machine, you can remove the "-O0" at the end of the CFLAGS line at the beginning of the makefile, after running configure.) The Emacs logo-mode compilation uses gmake. Some old Linux systems don't have the name "gmake" defined (although their "make" is actually gmake), but FreeBSD systems can't handle the makefile for logo-mode without gmake (which is *not* the same as "make" under FreeBSD). So you may need to install gmake. ** The files logolib/Messages.* are non-English versions of Messages. ** If you want to translate Logo to another language (see the ** Internationalization section of usermanual), rename Messages to ** Messages.english or something, then rename your chosen one to Messages, ** before make install. Say "make install" to install files as follows: /usr/local/bin: executable files: logo, install-logo-mode /usr/local/lib/logo/logolib: Logo library procedures, Messages (texts of error messages) /usr/local/lib/logo/helpfiles: files printed by Logo's HELP command /usr/local/lib/logo/emacs: elisp files *.el, *.elc for logo-mode, Logo-mode tutorial (tutorial.lg), an OOP package for Logo (*loops*) /usr/local/lib/logo/docs: usermanual.{ps,pdf,texi} /usr/local/lib/logo/docs/html: usermanual.html and other HTML files /usr/local/info: ucblogo.info (for Emacs help command) +-----------------------------------------------------------------------------+ | Each user who wants to use the Emacs logo-mode IDE must first run the shell | | command "install-logo-mode". Thereafter, whenever the user opens a Logo | | source file (filename.lg) with Emacs, logo-mode will automatically start. | +-----------------------------------------------------------------------------+ The files ztc*, mac*, and win32* are for toy-computer versions of Logo. But if you are trying to compile for those machines you probably also need some extra help beyond what's in here. You can get complete PC and Mac versions by anonymous FTP from ftp.cs.berkeley.edu. ---------- Here are the special features of this dialect of Logo: Random-access arrays. Variable number of inputs to user-defined procedures. Mutators for list structure (dangerous). Pause on error, and other improvements to error handling. Comments and continuation lines; formatting is preserved when procedure definitions are saved or edited. Terrapin-style tokenization (e.g., [2+3] is a list with one member) but LCSI-style syntax (no special forms except TO). The best of both worlds. First-class instruction and expression templates. Macros. ---------- ucblogo-5.5/configure.in0100644000161300001330000000224707201404500013236 0ustar bhdoednl Process this file with autoconf to produce a configure script. AC_INIT(coms.c) AC_CONFIG_HEADER(config.h) dnl Checks for programs. AC_PROG_CC dnl Checks for libraries. AC_PATH_XTRA AC_CHECK_LIB(m, atan) AC_CHECK_LIB(BSD, signal) AC_CHECK_LIB(bsd, signal) tcap=no AC_CHECK_LIB(termcap, tgetstr, AC_DEFINE(HAVE_LIBTERMCAP) LIBS="$LIBS -ltermcap" tcap=yes) if test $tcap = no; then AC_CHECK_LIB(termlib, tgetstr, AC_DEFINE(HAVE_LIBTERMLIB) LIBS="$LIBS -ltermlib" tcap=yes) fi if test $tcap = no; then AC_CHECK_LIB(curses, tgetstr, AC_DEFINE(HAVE_LIBCURSES) LIBS="$LIBS -lcurses" tcap=yes) fi if test $tcap = no; then AC_CHECK_LIB(ncurses, tgetstr, AC_DEFINE(HAVE_LIBCURSES) LIBS="$LIBS -lncurses" tcap=yes) fi dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(sgtty.h termio.h unistd.h string.h termcap.h termlib.h curses.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_TYPE_SIGNAL dnl Checks for library functions. AC_CHECK_FUNCS(usleep srandom sigvec sigsetmask matherr drem irint memcpy) AC_PROG_GCC_TRADITIONAL dnl AC_TYPE_SIGNAL if test "$no_x" != yes; then LIBS="$LIBS -lX11" fi AC_OUTPUT(makefile) ucblogo-5.5/makelib0100755000161300001330000006472310275741526012307 0ustar bhdoemkdir -p logolib cp Messages* logolib cat << "ENDOFFILE" > logolib/# ;;; -*- logo -*- to # if not namep "template.number [op repcount] op :template.number end bury "# ENDOFFILE cat << "ENDOFFILE" > logolib/\` ;;; -*- logo -*- to ` :backq.list [:backq.depth 0] if emptyp :backq.list [op []] if equalp first :backq.list "` ~ [op fput "` fput (` first bf :backq.list :backq.depth+1) (` bf bf :backq.list :backq.depth)] if equalp first first :backq.list ", ~ [op backq.unquote (bf first :backq.list) (bf :backq.list) :backq.depth] if memberp first first :backq.list [" :] ~ [op backq.word (first first :backq.list) (bf first :backq.list) (bf :backq.list) :backq.depth] if wordp first :backq.list ~ [op fput first :backq.list (` bf :backq.list :backq.depth)] op fput (` first :backq.list :backq.depth) (` bf :backq.list :backq.depth) end to backq.word :backq.symbol :backq.word :backq.rest :backq.depth if emptyp :backq.word ~ [output fput :backq.symbol (` :backq.rest :backq.depth)] if not equalp first :backq.word ", ~ [output fput (word :backq.symbol :backq.word) (` :backq.rest :backq.depth)] localmake "result backq.unquote (bf :backq.word) :backq.rest :backq.depth if wordp :result [output word :backq.symbol :result] output fput (word :backq.symbol first :result) bf :result end to backq.unquote :unquote.symbol :unquote.rest :unquote.depth localmake "unquote.splicing "false if not emptyp :unquote.symbol [ if equalp first :unquote.symbol "@ [ make "unquote.splicing "true make "unquote.symbol butfirst :unquote.symbol ]] if :unquote.depth=0 [ if emptyp :unquote.symbol [output backq.combine run first :unquote.rest (` bf :unquote.rest :unquote.depth)] output backq.combine run :unquote.symbol (` :unquote.rest :unquote.depth) ] if emptyp :unquote.symbol ~ [output fput (ifelse :unquote.splicing [",@] [",]) fput (` first :unquote.rest :unquote.depth-1) (` bf :unquote.rest :unquote.depth)] if backq.all.commas :unquote.symbol ~ [output fput (ifelse :unquote.splicing [",@] [",]) fput (` (list :unquote.symbol first :unquote.rest) :unquote.depth-1) (` bf :unquote.rest :unquote.depth)] output fput (ifelse :unquote.splicing [",@] [",]) ~ fput (` (list :unquote.symbol) :unquote.depth-1) ~ (` :unquote.rest :unquote.depth) end to backq.combine :this :those output ifelse :unquote.splicing [se :this :those] [fput :this :those] end to backq.all.commas :word if emptyp :word [output "true] if equalp first :word ", ~ [if emptyp butfirst :word [output "true] if equalp first butfirst :word "@ [output backq.all.commas bf bf :word] output backq.all.commas butfirst :word] output "false end bury [` backq.word backq.unquote backq.combine backq.all.commas] ENDOFFILE cat << "ENDOFFILE" > logolib/\?rest ;;; -*- logo -*- to ?rest [:which 1] output bf item :which :template.lists end bury "?rest ENDOFFILE cat << "ENDOFFILE" > logolib/buryall ;;; -*- logo -*- to buryall bury contents end bury "buryall ENDOFFILE cat << "ENDOFFILE" > logolib/buryname ;;; -*- logo -*- to buryname :names bury namelist :names end bury "buryname ENDOFFILE cat << "ENDOFFILE" > logolib/cascade ;;; -*- logo -*- to cascade :cascade.limit [:cascade.inputs] 3 if numberp :cascade.limit ~ [if lessp :cascade.limit 0 ~ [(throw "error (se [cascade doesn't like] :cascade.limit [as input]))] ~ make "cascade.limit `[greaterp :template.number ,[int :cascade.limit]]] local [cascade.templates template.vars cascade.final] make "cascade.templates [] make "template.vars [] make "cascade.final [?1] cascade.setup :cascade.inputs op cascade1 1 :template.vars end to cascade.setup :inputs if emptyp :inputs [stop] if emptyp bf :inputs [make "cascade.final first :inputs stop] make "cascade.templates lput first :inputs :cascade.templates make "template.vars lput first bf :inputs :template.vars cascade.setup bf bf :inputs end to cascade1 :template.number :template.vars if apply :cascade.limit :template.vars [op apply :cascade.final :template.vars] op cascade1 (:template.number+1) (cascade.eval :cascade.templates) end to cascade.eval :cascade.templates if emptyp :cascade.templates [op []] op fput (apply first :cascade.templates :template.vars) ~ (cascade.eval bf :cascade.templates) end bury [cascade cascade.setup cascade1 cascade.eval] ENDOFFILE cat << "ENDOFFILE" > logolib/cascade.2 ;;; -*- logo -*- to cascade.2 [:cascade2.inputs] 5 op apply "cascade :cascade2.inputs end bury "cascade.2 ENDOFFILE cat << "ENDOFFILE" > logolib/case ;;; -*- logo -*- .macro case :case.value :case.clauses [:caseignoredp "true] catch "case.error [output case.helper :case.value :case.clauses] (throw "error [Empty CASE clause]) end to case.helper :case.value :case.clauses if emptyp :case.clauses [output []] if emptyp first :case.clauses [throw "case.error] if or equalp first first :case.clauses "else ~ memberp :case.value first first :case.clauses ~ [output butfirst first :case.clauses] output case.helper :case.value butfirst :case.clauses end bury [case case.helper] ENDOFFILE cat << "ENDOFFILE" > logolib/closeall ;;; -*- logo -*- to closeall foreach allopen [close ?] end bury "closeall ENDOFFILE cat << "ENDOFFILE" > logolib/combine ;;; -*- logo -*- to combine :this :those if wordp :those [output word :this :those] output fput :this :those end bury "combine ENDOFFILE cat << "ENDOFFILE" > logolib/cond ;;; -*- logo -*- .macro cond :cond.clauses localmake "cond.result cond.helper :cond.clauses if equalp first :cond.result "error [(throw "error last :cond.result)] output last :cond.result end to cond.helper :cond.clauses if emptyp :cond.clauses [output [[] []]] if emptyp first :cond.clauses [output [error [Empty COND clause]]] if equalp first first :cond.clauses "else ~ [output list [] butfirst first :cond.clauses] ignore error catch "error [localmake "cond.result run first first :cond.clauses] localmake "cond.error error if not emptyp :cond.error [output list "error item 2 :cond.error] if not memberp :cond.result [true false] ~ [output list "error fput :cond.result [not TRUE or FALSE]] if :cond.result [output list [] butfirst first :cond.clauses] output cond.helper butfirst :cond.clauses end bury [cond cond.helper] ENDOFFILE cat << "ENDOFFILE" > logolib/crossmap ;;; -*- logo -*- to crossmap :cm.template [:cm.lists] 2 if emptyp bf :cm.lists [op cm1 first :cm.lists 1 []] op cm1 :cm.lists 1 [] end to cm1 :cm.lists :cm.level :template.vars if emptyp :cm.lists [op (list apply :cm.template :template.vars)] op cm2 first :cm.lists end to cm2 :cm.thislist if emptyp :cm.thislist [op []] local :cm.level make :cm.level first :cm.thislist op se (cm1 bf :cm.lists :cm.level+1 lput first :cm.thislist :template.vars) ~ (cm2 bf :cm.thislist) end bury [crossmap cm1 cm2] ENDOFFILE cat << "ENDOFFILE" > logolib/dequeue ;;; -*- logo -*- to dequeue :the.queue.name local "result make "result first thing :the.queue.name make :the.queue.name butfirst thing :the.queue.name output :result end bury "dequeue ENDOFFILE cat << "ENDOFFILE" > logolib/do.until ;;; -*- logo -*- .macro do.until :until.instr :until.cond op se :until.instr (list "until :until.cond :until.instr) end bury "do.until ENDOFFILE cat << "ENDOFFILE" > logolib/do.while ;;; -*- logo -*- .macro do.while :while.instr :while.cond op se :while.instr (list "while :while.cond :while.instr) end bury "do.while ENDOFFILE cat << "ENDOFFILE" > logolib/edall ;;; -*- logo -*- to edall edit contents end bury "edall ENDOFFILE cat << "ENDOFFILE" > logolib/edn ;;; -*- logo -*- to edn :names edit namelist :names end bury "edn ENDOFFILE cat << "ENDOFFILE" > logolib/edns ;;; -*- logo -*- to edns edit names end bury "edns ENDOFFILE cat << "ENDOFFILE" > logolib/edpl ;;; -*- logo -*- to edpl :names edit pllist :names end bury "edpl ENDOFFILE cat << "ENDOFFILE" > logolib/edpls ;;; -*- logo -*- to edpls edit plists end bury "edpls ENDOFFILE cat << "ENDOFFILE" > logolib/edps ;;; -*- logo -*- to edps edit procedures end bury "edps ENDOFFILE cat << "ENDOFFILE" > logolib/emacs.debug ;;; -*- logo -*- to emacs.debug :file_elisp_code :trace_or_step localmake "wr_elisp_code writer if namep "printwidthlimit [ localmake "pw_elisp_code :printwidthlimit ern "printwidthlimit] openwrite :file_elisp_code setwrite :file_elisp_code bury [[] [wr_elisp_code pw_elisp_code file_elisp_code trace_or_step] []] (foreach contents run (list :trace_or_step) [PROCEDURES: VARIABLES: PROPERTIES:] [[names debugged title] [pr :title pr [] pr map [[name] [op ifelse memberp :name :debugged [(word "\( :name "\))] [:name]]] :names pr []]]) close :file_elisp_code setwrite :wr_elisp_code if namep "pw_elisp_code [make "printwidthlimit :pw_elisp_code] end bury "emacs.debug ENDOFFILE cat << "ENDOFFILE" > logolib/ern ;;; -*- logo -*- to ern :names erase namelist :names end bury "ern ENDOFFILE cat << "ENDOFFILE" > logolib/erpl ;;; -*- logo -*- to erpl :names erase pllist :names end bury "erpl ENDOFFILE cat << "ENDOFFILE" > logolib/filep ;;; -*- logo -*- to filep :filename ignore error catch "error [openread :filename close :filename] output emptyp error end bury "filep ENDOFFILE cat << "ENDOFFILE" > logolib/file\? ;;; -*- logo -*- to file? :filename ignore error catch "error [openread :filename close :filename] output not emptyp error end bury "file? ENDOFFILE cat << "ENDOFFILE" > logolib/filter ;;; -*- logo -*- to filter :filter.template :template.list [:template.number 1] ~ [:template.lists (list :template.list)] if emptyp :template.list [op :template.list] if apply :filter.template (list first :template.list) ~ [op combine (first :template.list) ~ (filter :filter.template bf :template.list :template.number+1)] op (filter :filter.template bf :template.list :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [filter ?rest] ENDOFFILE cat << "ENDOFFILE" > logolib/find ;;; -*- logo -*- to find :find.template :template.list [:template.number 1] ~ [:template.lists (list :template.list)] if emptyp :template.list [op []] if apply :find.template (list first :template.list) [op first :template.list] op (find :find.template bf :template.list :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [find ?rest] ENDOFFILE cat << "ENDOFFILE" > logolib/for ;;; -*- logo -*- .macro for :for.values :for.instr ~ [:for.var first :for.values] ~ [:for.initial run first bf :for.values] ~ [:for.final run first bf bf :for.values] ~ [:for.step forstep] ~ [:for.tester (ifelse :for.step < 0 ~ [[:for.initial < :for.final]] ~ [[:for.initial > :for.final]])] local :for.var catch "for.catchtag [op for.done runresult [forloop :for.initial]] op [] end to forloop :for.initial make :for.var :for.initial if run :for.tester [throw "for.catchtag] run :for.instr .maybeoutput forloop (:for.initial + :for.step) end to for.done :for.result if emptyp :for.result [op [stop]] op (list "output "first (list first :for.result)) end to forstep if equalp count :for.values 4 [op run last :for.values] op ifelse :for.initial > :for.final [-1] [1] end bury [for forstep forloop for.done] ENDOFFILE cat << "ENDOFFILE" > logolib/foreach ;;; -*- logo -*- .macro foreach [:foreach.inputs] 2 catch "foreach.catchtag ~ [op foreach.done runresult ~ [foreach1 butlast :foreach.inputs last :foreach.inputs 1]] op [] end to foreach1 :template.lists :foreach.template :template.number if emptyp first :template.lists [throw "foreach.catchtag] apply :foreach.template firsts :template.lists .maybeoutput foreach1 butfirsts :template.lists ~ :foreach.template :template.number+1 end to foreach.done :foreach.result if emptyp :foreach.result [op [stop]] op (list "output "first (list first :foreach.result)) end to ?rest [:which 1] output butfirst item :which :template.lists end bury [foreach foreach1 foreach.done ?rest] ENDOFFILE cat << "ENDOFFILE" > logolib/gensym ;;; -*- logo -*- to gensym if not namep "gensym.number [make "gensym.number 0] make "gensym.number :gensym.number + 1 output word "g :gensym.number end bury [[gensym] [gensym.number]] ENDOFFILE cat << "ENDOFFILE" > logolib/ignore ;;; -*- logo -*- to ignore :stuff end bury "ignore ENDOFFILE cat << "ENDOFFILE" > logolib/invoke ;;; -*- logo -*- to invoke :invoked.function [:invoke.inputs] 2 .maybeoutput apply :invoked.function :invoke.inputs end bury "invoke ENDOFFILE cat << "ENDOFFILE" > logolib/iseq ;;; -*- logo -*- to iseq :a :b if not (:a > :b) [output iseq1 :a :b] output map [[x] -1 * :x] iseq1 (-1 * :a) (-1 * :b) end to iseq1 :a :b if :a > :b [output []] output fput :a iseq1 :a + 1 :b end bury [iseq iseq1] ENDOFFILE cat << "ENDOFFILE" > logolib/localmake ;;; -*- logo -*- .macro localmake :name :value output (list "local (word "" :name) "apply ""make (list :name :value)) end bury "localmake ENDOFFILE cat << "ENDOFFILE" > logolib/macroexpand ;;; -*- logo -*- to macroexpand :expr local [name inputlist macro.result] make "name first :expr make "inputlist bf :expr if not macrop :name [(throw "error (se :name [is not a macro.]))] define "%%%$%macro.procedure text :name make "macro.result run fput "%%%$%macro.procedure :inputlist erase "%%%$%macro.procedure op :macro.result end bury "macroexpand ENDOFFILE cat << "ENDOFFILE" > logolib/map ;;; -*- logo -*- to map :map.template [:template.lists] 2 op map1 :template.lists 1 end to map1 :template.lists :template.number if emptyp first :template.lists [output first :template.lists] output combine (apply :map.template firsts :template.lists) ~ (map1 bfs :template.lists :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [map map1 ?rest] ENDOFFILE cat << "ENDOFFILE" > logolib/map.se ;;; -*- logo -*- to map.se :map.se.template [:template.lists] 2 op map.se1 :template.lists 1 end to map.se1 :template.lists :template.number if emptyp first :template.lists [output []] output sentence (apply :map.se.template firsts :template.lists) ~ (map.se1 bfs :template.lists :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [map.se map.se1 ?rest] ENDOFFILE cat << "ENDOFFILE" > logolib/mdarray ;;; -*- logo -*- to mdarray :sizes [:origin 1] local "array make "array (array first :sizes :origin) if not emptyp bf :sizes ~ [for [i :origin [:origin + (first :sizes) - 1]] ~ [setitem :i :array (mdarray bf :sizes :origin)]] output :array end bury "mdarray ENDOFFILE cat << "ENDOFFILE" > logolib/mditem ;;; -*- logo -*- to mditem :index :array if emptyp :index [op :array] op mditem bf :index item first :index :array end bury "mditem ENDOFFILE cat << "ENDOFFILE" > logolib/mdsetitem ;;; -*- logo -*- to mdsetitem :index :array :val setitem last :index (mditem butlast :index :array) :val end bury "mdsetitem ENDOFFILE cat << "ENDOFFILE" > logolib/name ;;; -*- logo -*- to name :name.value.input :name.variable.input make :name.variable.input :name.value.input end bury "name ENDOFFILE cat << "ENDOFFILE" > logolib/namelist ;;; -*- logo -*- to namelist :names if wordp :names [output list [] (list :names)] output list [] :names end bury "namelist ENDOFFILE cat << "ENDOFFILE" > logolib/pen ;;; -*- logo -*- to pen op (list (ifelse pendownp ["pendown] ["penup]) ~ penmode pensize pencolor penpattern) end bury [pen] ENDOFFILE cat << "ENDOFFILE" > logolib/pick ;;; -*- logo -*- to pick :list output item (1+random count :list) :list end bury "pick ENDOFFILE cat << "ENDOFFILE" > logolib/pllist ;;; -*- logo -*- to pllist :names if wordp :names [output (list [] [] (list :names))] output (list [] [] :names) end bury "pllist ENDOFFILE cat << "ENDOFFILE" > logolib/poall ;;; -*- logo -*- to poall po contents end bury "poall ENDOFFILE cat << "ENDOFFILE" > logolib/pon ;;; -*- logo -*- to pon :names ignore error catch "error [po namelist :names] local "err make "err error if not emptyp :err [(throw "error first bf :err)] end bury "pon ENDOFFILE cat << "ENDOFFILE" > logolib/pons ;;; -*- logo -*- to pons po names end bury "pons ENDOFFILE cat << "ENDOFFILE" > logolib/pop ;;; -*- logo -*- to pop :the.stack.name local "result make "result first thing :the.stack.name make :the.stack.name butfirst thing :the.stack.name output :result end bury "pop ENDOFFILE cat << "ENDOFFILE" > logolib/popl ;;; -*- logo -*- to popl :names ignore error catch "error [po pllist :names] local "err make "err error if not emptyp :err [(throw "error first bf :err)] end bury "popl ENDOFFILE cat << "ENDOFFILE" > logolib/popls ;;; -*- logo -*- to popls po plists end bury "popls ENDOFFILE cat << "ENDOFFILE" > logolib/pops ;;; -*- logo -*- to pops po procedures end bury "pops ENDOFFILE cat << "ENDOFFILE" > logolib/pots ;;; -*- logo -*- to pots pot procedures end bury "pots ENDOFFILE cat << "ENDOFFILE" > logolib/push ;;; -*- logo -*- to push :the.stack.name :the.item.value make :the.stack.name fput :the.item.value thing :the.stack.name end bury "push ENDOFFILE cat << "ENDOFFILE" > logolib/queue ;;; -*- logo -*- to queue :the.queue.name :the.item.value make :the.queue.name lput :the.item.value thing :the.queue.name end bury "queue ENDOFFILE cat << "ENDOFFILE" > logolib/quoted ;;; -*- logo -*- to quoted :stuff if wordp :stuff [op word "" :stuff] op :stuff end bury "quoted ENDOFFILE cat << "ENDOFFILE" > logolib/reduce ;;; -*- logo -*- to reduce :reduce.function :reduce.list if emptyp bf :reduce.list [op first :reduce.list] op apply :reduce.function (list (first :reduce.list) ~ (reduce :reduce.function bf :reduce.list)) end bury "reduce ENDOFFILE cat << "ENDOFFILE" > logolib/remdup ;;; -*- logo -*- to remdup :list output filter [not memberp ? ?rest] :list end bury "remdup ENDOFFILE cat << "ENDOFFILE" > logolib/remove ;;; -*- logo -*- to remove :thing :list output filter [not equalp ? :thing] :list end bury "remove ENDOFFILE cat << "ENDOFFILE" > logolib/reverse ;;; -*- logo -*- to reverse :in [:out ifelse listp :in [[]] ["]] if emptyp :in [output :out] output (reverse bf :in combine first :in :out) end bury "reverse ENDOFFILE cat << "ENDOFFILE" > logolib/rseq ;;; -*- logo -*- to rseq :a :b :n output map [[x] :a + :x * (:b - :a) / (:n - 1)] iseq 0 :n - 1 end bury "rseq ENDOFFILE cat << "ENDOFFILE" > logolib/savel ;;; -*- logo -*- to savel :cont :file [:oldwr writer] openwrite :file setwrite :file po :cont setwrite :oldwr close :file end bury "savel ENDOFFILE cat << "ENDOFFILE" > logolib/setpen ;;; -*- logo -*- to setpen :pen_data ifelse equalp first bf :pen_data "reverse ~ [penreverse] ~ [ifelse equalp first bf :pen_data "erase ~ [penerase] ~ [penpaint]] ifelse equalp first :pen_data "penup [penup] [pendown] setpensize first bf bf :pen_data setpencolor first bf bf bf :pen_data setpenpattern first bf bf bf bf :pen_data end bury [setpen] ENDOFFILE cat << "ENDOFFILE" > logolib/transfer ;;; -*- logo -*- to transfer :transfer.limit :transfer.template :transfer.init output cascade.2 (ifelse emptyp :transfer.limit ~ [[emptyp ?2]] ~ [list "transfer.end.test :transfer.limit]) ~ :transfer.template [] [butfirst ?2] :transfer.init end to transfer.end.test :the.condition.expression if emptyp ?2 [output "true] output run :the.condition.expression end to ?in output first ?2 end to ?out output ?1 end bury [transfer transfer.end.test ?in ?out] ENDOFFILE cat << "ENDOFFILE" > logolib/unburyall ;;; -*- logo -*- to unburyall unbury buried end ENDOFFILE cat << "ENDOFFILE" > logolib/unburyname ;;; -*- logo -*- to unburyname :names unbury namelist :names end bury "unburyname ENDOFFILE cat << "ENDOFFILE" > logolib/until ;;; -*- logo -*- .macro until :until.cond :until.instr if run :until.cond [op []] op se :until.instr (list "until :until.cond :until.instr) end bury "until ENDOFFILE cat << "ENDOFFILE" > logolib/while ;;; -*- logo -*- .macro while :while.cond :while.instr if not run :while.cond [op []] op se :while.instr (list "while :while.cond :while.instr) end bury "while ENDOFFILE cat << "ENDOFFILE" > logolib/xcor ;;; -*- logo -*- to xcor output first pos end bury "xcor ENDOFFILE cat << "ENDOFFILE" > logolib/ycor ;;; -*- logo -*- to ycor output last pos end bury "ycor ENDOFFILE cat << "ENDOFFILE" > logolib/logo-logo ;;; -*- logo -*- ;; a logo for logo written in logo ;-) ;; version 0.1 ;; by AKFoerster Make "Startup [UCBLogo wait 300 ucblogo.reset] to ucblogo.reset cs SetPen [pendown paint [0 0] 7 [-1]] setbg 0 clearScreen ShowTurtle Wrap TextScreen erase [ucblogo ucblogo.DrawUCBLogo ucblogo.StartPos ucblogo.DrawUCB] erase [ucblogo.DrawLogo ucblogo.LetterSpace ucblogo.HalfWidth ucblogo.Next] erase [ucblogo.DrawU ucblogo.DrawC ucblogo.DrawB] erase [ucblogo.DrawL ucblogo.DrawO ucblogo.DrawG ucblogo.reset] ern "Startup end ;; Homeposition: Turtle at bottom/center of letter/Line to UCBLogo Localmake "Title word "Berkeley\ Logo\ version\ :LogoVersion Localmake "LetterHeight 70 Localmake "LetterWidth 30 Localmake "LetterSpace 25 Localmake "HalfLineSpace 15 Localmake "MyPenSize 10 Localmake "FontColor 4 Localmake "ShadowColor 0 Localmake "BorderColor 2 Localmake "FillColor 6 Localmake "LabelColor 0 ;; just guessing: (!!!) Localmake "LabelLetterWidth ifelse equalp LogoPlatform "Windows [4] [3] HideTurtle ClearScreen Window FullScreen setPenSize list :MyPenSize :MyPenSize ;; Background ;; "Q should also be dependant on "LetterHeight (!!!) localMake "Q Product ucblogo.LetterSpace 4 setbg :fillcolor setpc 0 fill setPenColor :BorderColor PenUp setXY :Q 0 PenDown setXY 0 :Q setXY -:Q 0 setXY 0 -:Q setXY :Q 0 PenUp Home setPenColor :FillColor fill ;; shadow setXY :myPenSize*0.7 -:myPenSize*0.7 setPenColor :ShadowColor ucblogo.DrawUCBLogo ;; coloured Logo Home setPenColor :FontColor ucblogo.DrawUCBLogo ;; Label - doesn't work on windows (!!!) PenUp Home Back :LetterHeight repeat 3 [Back :HalfLineSpace] setPenColor :LabelColor setX minus product count :Title :LabelLetterWidth setPenSize [1 1] label :Title wait 30 setx 0 fd 15 rt 120 setpc :FontColor setPenSize [7 7] pd arc 120 :LetterHeight pu seth 0 bk 30 setx -20 pd fd 2 bk 2 pu setx 20 pd fd 2 bk 2 pu print :Title end to ucblogo.DrawUCBLogo localMake "HomePos Pos PenUp SetHeading 0 Forward :HalfLineSpace ucblogo.DrawUCB setPos :HomePos SetHeading 0 PenUp back :HalfLineSpace back :LetterHeight ucblogo.DrawLogo end to ucblogo.StartPos "Letters ;; assume Turtle in center of text PenUp setheading 270 Forward quotient ( product :Letters ucblogo.LetterSpace ) 2 back quotient ucblogo.LetterSpace 2 wait 30 end to ucblogo.DrawUCB ucblogo.StartPos 3 ucblogo.DrawU ucblogo.Next ucblogo.DrawC ucblogo.Next ucblogo.DrawB end to ucblogo.DrawLogo ucblogo.StartPos 4 ucblogo.DrawL ucblogo.Next ucblogo.DrawO ucblogo.Next ucblogo.DrawG ucblogo.Next ucblogo.DrawO end to ucblogo.LetterSpace output sum :LetterWidth :LetterSpace end to ucblogo.HalfWidth output quotient :LetterWidth 2 end to ucblogo.Next PenUp setheading 90 Forward ucblogo.LetterSpace wait 30 end to ucblogo.DrawU ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight ucblogo.HalfWidth ;; Left side PenUp Left 90 Forward :LetterWidth PenDown Left 90 Forward difference :LetterHeight ucblogo.HalfWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end to ucblogo.DrawC ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth Left 90 Forward difference :LetterHeight :LetterWidth ;; upper arc PenUp Left 90 Forward ucblogo.HalfWidth PenDown arc 180 ucblogo.HalfWidth ;; Left side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end to ucblogo.DrawB localMake "QuaterHeight Quotient :LetterHeight 4 ;; Move to startposition setheading 270 PenUp ;; the width is equal :QuaterHeight Forward Quotient :QuaterHeight 2 ;; Draw PenDown Right 90 Forward :LetterHeight back :QuaterHeight arc 175 :QuaterHeight back :QuaterHeight back :QuaterHeight arc 175 :QuaterHeight ;; Move to Homeposition PenUp back :QuaterHeight Right 90 Forward Quotient :QuaterHeight 2 end to ucblogo.DrawL ;; Move to top of L setheading 270 PenUp Forward ucblogo.HalfWidth Right 90 Forward :LetterHeight Right 180 ;; Draw PenDown Forward :LetterHeight Left 90 Forward :LetterWidth ;; Move to Homeposition PenUp back ucblogo.HalfWidth end to ucblogo.DrawO ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; upper arc PenUp Left 90 Forward ucblogo.HalfWidth PenDown arc 180 ucblogo.HalfWidth ;; Left side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end to ucblogo.DrawG ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth PenDown Right 90 Forward ucblogo.HalfWidth back ucblogo.HalfWidth Right 90 Forward ucblogo.HalfWidth back ucblogo.HalfWidth PenUp Right 90 Forward difference :LetterHeight :LetterWidth ;; upper arc PenUp Left 90 Forward ucblogo.HalfWidth PenDown arc 180 ucblogo.HalfWidth ;; Left side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end ENDOFFILE ucblogo-5.5/general-public-license0100644000161300001330000004307105777057404015210 0ustar bhdoe GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program 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 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ucblogo-5.5/gpl0100644000161300001330000000000005777057404017634 1ucblogo-5.5/general-public-licenseustar bhdoeucblogo-5.5/libloc.c.pc0100644000161300001330000000024510150241357012740 0ustar bhdoechar *libloc="logolib"; #ifdef WIN32 char *helploc="helpfile"; #else char *helploc="helpfiles"; #endif char *cslsloc="csls"; char *temploc=""; char *separator="\\"; ucblogo-5.5/tags0100644000161300001330000020106007547501766011631 0ustar bhdoe!_TAG_FILE_FORMAT 1 /original ctags format/ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted/ !_TAG_PROGRAM_AUTHOR Darren Hiebert /darren@hiebert.com/ !_TAG_PROGRAM_NAME Exuberant Ctags // !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ !_TAG_PROGRAM_VERSION 5.0.1 // ALREADY_DEFINED logo.h /^ NO_CATCH_TAG, ALREADY_DEFINED, STOP_ERROR, ALREADY_DRIBBLING,$/ ALREADY_DRIBBLING logo.h /^ NO_CATCH_TAG, ALREADY_DEFINED, STOP_ERROR, ALREADY_DRIBBLING,$/ ALREADY_OPEN logo.h /^ NO_FILE, NO_FIONREAD, MEM_LOW, CANT_OPEN, ALREADY_OPEN,$/ APPLY_BAD_DATA logo.h /^ DK_WHAT_UP, AT_TOPLEVEL, APPLY_BAD_DATA, DEEPEND,$/ ARC graphics.c /^#define ARC / ARRAY logo.h /^#define ARRAY / AT_TOPLEVEL logo.h /^ DK_WHAT_UP, AT_TOPLEVEL, APPLY_BAD_DATA, DEEPEND,$/ AllowGetSet init.c /^ *Printwidthlimit, *Pause, *LoadNoisily, *AllowGetSet,$/ Alt logo.h /^ NODE *Alt;$/ BACKSLASH_STRING logo.h /^#define BACKSLASH_STRING / BAD_DATA logo.h /^ BAD_DATA_UNREC, DIDNT_OUTPUT, NOT_ENOUGH, BAD_DATA, TOO_MUCH,$/ BAD_DATA_UNREC logo.h /^ BAD_DATA_UNREC, DIDNT_OUTPUT, NOT_ENOUGH, BAD_DATA, TOO_MUCH,$/ BAD_DEFAULT logo.h /^ BAD_DEFAULT, RUNRES_STOP,$/ BAD_GRAPH_INIT logo.h /^ UNEXPECTED_BRACE, BAD_GRAPH_INIT, ERR_MACRO,$/ BC term.c /^char *BC;$/ BOOLEAN logo.h /^#define BOOLEAN / BOOLEAN logo.h /^typedef int BOOLEAN;$/ BORDER xgraphics.h /^#define BORDER / Big graphics.c /^#define Big / CANT_GC logo.h /^ NOT_OPEN, TRACE_PPROP, WELCOME_TO, CANT_STOP, CANT_GC,$/ CANT_OPEN logo.h /^ NO_FILE, NO_FIONREAD, MEM_LOW, CANT_OPEN, ALREADY_OPEN,$/ CANT_STOP logo.h /^ NOT_OPEN, TRACE_PPROP, WELCOME_TO, CANT_STOP, CANT_GC,$/ CASEOBJ logo.h /^#define CASEOBJ / CNTLSTTYP wrksp.c /^typedef enum {c_PROCS, c_VARS, c_PLISTS} CNTLSTTYP;$/ COLON logo.h /^#define COLON / CONS logo.h /^#define CONS / CONSOLE globals.h /^#undef CONSOLE$/ CONT logo.h /^#define CONT / CTRLTYPE logo.h /^typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE;$/ Caseignoredp init.c /^NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit,$/ DEBUGGING eval.c /^#define DEBUGGING / DEB_CONT eval.c /^#define DEB_CONT / DEB_STACK eval.c /^#define DEB_STACK / DEEPEND logo.h /^ DK_WHAT_UP, AT_TOPLEVEL, APPLY_BAD_DATA, DEEPEND,$/ DEEPEND_NONAME logo.h /^ OUT_OF_MEM_UNREC, USER_ERR_MESSAGE, DEEPEND_NONAME,$/ DEFAULT_HEIGHT xgraphics.h /^#define DEFAULT_HEIGHT / DEFAULT_WIDTH xgraphics.h /^#define DEFAULT_WIDTH / DIDNT_OUTPUT logo.h /^ BAD_DATA_UNREC, DIDNT_OUTPUT, NOT_ENOUGH, BAD_DATA, TOO_MUCH,$/ DK_HOW logo.h /^ DK_WHAT, PAREN_MISMATCH, NO_VALUE, UNEXPECTED_PAREN, DK_HOW,$/ DK_HOW_UNREC logo.h /^ NOT_INSIDE, DK_HOW_UNREC, NO_TEST, UNEXPECTED_BRACKET,$/ DK_WHAT logo.h /^ DK_WHAT, PAREN_MISMATCH, NO_VALUE, UNEXPECTED_PAREN, DK_HOW,$/ DK_WHAT_UP logo.h /^ DK_WHAT_UP, AT_TOPLEVEL, APPLY_BAD_DATA, DEEPEND,$/ Dotsvalue init.c /^ *UnburyOnEdit, *Fullprintp, *Make, *Listvalue, *Dotsvalue,$/ EMPTY_PROC logo.h /^ EXIT_NOW, LOAD_DEF, TRACE_MAKE, EMPTY_PROC, POT_PLIST,$/ END_OF_LIST logo.h /^#define END_OF_LIST / ERRACT_LOOP logo.h /^ ERRACT_LOOP, PAUS_ING, TRACE_STOPS, TRACE_OUTPUTS,$/ ERROR_IN logo.h /^ THANK_YOU, NICE_DAY, NOSHELL_MAC, TYPE_EXIT, ERROR_IN,$/ ERR_MACRO logo.h /^ UNEXPECTED_BRACE, BAD_GRAPH_INIT, ERR_MACRO,$/ ERR_TYPES logo.h /^ MAX_MESSAGE} ERR_TYPES; \/* MAX_MESSAGE must be last *\/$/ EVENT_MASK xgraphics.h /^#define EVENT_MASK / EXIT_NOW logo.h /^ EXIT_NOW, LOAD_DEF, TRACE_MAKE, EMPTY_PROC, POT_PLIST,$/ English logo.h /^ NODE *English;$/ Erract init.c /^NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit,$/ FALSE logo.h /^#define FALSE / FALSE term.c /^#define FALSE / FALSE term.c /^#undef FALSE$/ FATAL logo.h /^typedef enum { FATAL, OUT_OF_MEM, STACK_OVERFLOW, TURTLE_OUT_OF_BOUNDS,$/ FILE_ERROR logo.h /^ FILE_ERROR, IF_WARNING, SHADOW_WARN, USER_ERR, IS_PRIM,$/ FILLERUP graphics.c /^#define FILLERUP / FIXNUM logo.h /^#define FIXNUM / FLOATT logo.h /^#define FLOATT / FLONUM logo.h /^#define FLONUM / FONT xgraphics.h /^#define FONT / False init.c /^#define False / False xgraphics.h /^#undef False$/ FalseName logodata.c /^NODE *FalseName() {$/ Fullprintp init.c /^ *UnburyOnEdit, *Fullprintp, *Make, *Listvalue, *Dotsvalue,$/ GCMAX mem.c /^#define GCMAX / GR_SIZE xgraphics.h /^#define GR_SIZE / HASH_LEN logo.h /^#define HASH_LEN / HAS_GLOBAL_VALUE logo.h /^#define HAS_GLOBAL_VALUE / HAVE_MEMCPY logo.h /^#define HAVE_MEMCPY$/ IF_WARNING logo.h /^ FILE_ERROR, IF_WARNING, SHADOW_WARN, USER_ERR, IS_PRIM,$/ INFIX logo.h /^#define INFIX / INT logo.h /^#define INT / IS_LOCAL_VALUE logo.h /^#define IS_LOCAL_VALUE / IS_PRIM logo.h /^ FILE_ERROR, IF_WARNING, SHADOW_WARN, USER_ERR, IS_PRIM,$/ LABEL graphics.c /^#define LABEL / LINE logo.h /^#define LINE / LINEXY graphics.c /^#define LINEXY / LOAD_DEF logo.h /^ EXIT_NOW, LOAD_DEF, TRACE_MAKE, EMPTY_PROC, POT_PLIST,$/ LOCALSAVE logo.h /^#define LOCALSAVE / Left_Paren init.c /^NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit,$/ Listvalue init.c /^ *UnburyOnEdit, *Fullprintp, *Make, *Listvalue, *Dotsvalue,$/ LoadNoisily init.c /^ *Printwidthlimit, *Pause, *LoadNoisily, *AllowGetSet,$/ MACRO logo.h /^#define MACRO / MACRO_PRIORITY logo.h /^#define MACRO_PRIORITY / MACRO_RETURN logo.h /^typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE;$/ MAXLOGOINT logo.h /^#define MAXLOGOINT / MAX_MESSAGE logo.h /^ MAX_MESSAGE} ERR_TYPES; \/* MAX_MESSAGE must be last *\/$/ MAX_NUMBER logo.h /^#define MAX_NUMBER / MAX_PHYS_LINE logo.h /^#define MAX_PHYS_LINE / MAYBE_PRIORITY logo.h /^#define MAYBE_PRIORITY / MEM_LOW logo.h /^ NO_FILE, NO_FIONREAD, MEM_LOW, CANT_OPEN, ALREADY_OPEN,$/ MORE_HELP logo.h /^ NO_HELP, NO_HELPON, MORE_HELP,$/ MOVEXY graphics.c /^#define MOVEXY / Make init.c /^ *UnburyOnEdit, *Fullprintp, *Make, *Listvalue, *Dotsvalue,$/ Minus_Sign init.c /^ *Minus_Sign, *Minus_Tight, *Startup, *Query, *UseAlternateNames;$/ Minus_Tight init.c /^ *Minus_Sign, *Minus_Tight, *Startup, *Query, *UseAlternateNames;$/ NICE_DAY logo.h /^ THANK_YOU, NICE_DAY, NOSHELL_MAC, TYPE_EXIT, ERROR_IN,$/ NIL logo.h /^#define NIL / NODE logo.h /^} NODE;$/ NODETYPES logo.h /^typedef long int NODETYPES;$/ NOSHELL_MAC logo.h /^ THANK_YOU, NICE_DAY, NOSHELL_MAC, TYPE_EXIT, ERROR_IN,$/ NOT_ENOUGH logo.h /^ BAD_DATA_UNREC, DIDNT_OUTPUT, NOT_ENOUGH, BAD_DATA, TOO_MUCH,$/ NOT_INSIDE logo.h /^ NOT_INSIDE, DK_HOW_UNREC, NO_TEST, UNEXPECTED_BRACKET,$/ NOT_OPEN logo.h /^ NOT_OPEN, TRACE_PPROP, WELCOME_TO, CANT_STOP, CANT_GC,$/ NOT_THROWING logo.h /^#define NOT_THROWING / NO_CATCH_TAG logo.h /^ NO_CATCH_TAG, ALREADY_DEFINED, STOP_ERROR, ALREADY_DRIBBLING,$/ NO_FILE logo.h /^ NO_FILE, NO_FIONREAD, MEM_LOW, CANT_OPEN, ALREADY_OPEN,$/ NO_FIONREAD logo.h /^ NO_FILE, NO_FIONREAD, MEM_LOW, CANT_OPEN, ALREADY_OPEN,$/ NO_HELP logo.h /^ NO_HELP, NO_HELPON, MORE_HELP,$/ NO_HELPON logo.h /^ NO_HELP, NO_HELPON, MORE_HELP,$/ NO_TEST logo.h /^ NOT_INSIDE, DK_HOW_UNREC, NO_TEST, UNEXPECTED_BRACKET,$/ NO_VALUE logo.h /^ DK_WHAT, PAREN_MISMATCH, NO_VALUE, UNEXPECTED_PAREN, DK_HOW,$/ NO_VALUE_OK logo.h /^#define NO_VALUE_OK / NTFREE logo.h /^#define NTFREE / NT_AGGR logo.h /^#define NT_AGGR / NT_ARRAY logo.h /^#define NT_ARRAY / NT_BACKSL logo.h /^#define NT_BACKSL / NT_CASEOBJ logo.h /^#define NT_CASEOBJ / NT_COLON logo.h /^#define NT_COLON / NT_CONT logo.h /^#define NT_CONT / NT_EMPTY logo.h /^#define NT_EMPTY / NT_FLOAT logo.h /^#define NT_FLOAT / NT_INFIX logo.h /^#define NT_INFIX / NT_LINE logo.h /^#define NT_LINE / NT_LIST logo.h /^#define NT_LIST / NT_LOCAL logo.h /^#define NT_LOCAL / NT_MACRO logo.h /^#define NT_MACRO / NT_NUMBER logo.h /^#define NT_NUMBER / NT_PRIM logo.h /^#define NT_PRIM / NT_PUNCT logo.h /^#define NT_PUNCT / NT_RUNP logo.h /^#define NT_RUNP / NT_STACK logo.h /^#define NT_STACK / NT_STRING logo.h /^#define NT_STRING / NT_TAILFORM logo.h /^#define NT_TAILFORM / NT_TREE logo.h /^#define NT_TREE / NT_VBAR logo.h /^#define NT_VBAR / NT_WORD logo.h /^#define NT_WORD / NUMCOLORS xgraphics.h /^#define NUMCOLORS / NUMINITCOLORS xgraphics.h /^#define NUMINITCOLORS / NUM_GENS mem.c /^#define NUM_GENS / Not_Enough_Node init.c /^ *Unbound, *Not_Enough_Node,$/ Null_Word init.c /^NODE *Null_Word = NIL;$/ OK_NO_ARG logo.h /^#define OK_NO_ARG / OUTPUT logo.h /^typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE;$/ OUTPUT_OK logo.h /^#define OUTPUT_OK / OUTPUT_PRIORITY logo.h /^#define OUTPUT_PRIORITY / OUTPUT_TAIL logo.h /^#define OUTPUT_TAIL / OUT_OF_MEM logo.h /^typedef enum { FATAL, OUT_OF_MEM, STACK_OVERFLOW, TURTLE_OUT_OF_BOUNDS,$/ OUT_OF_MEM_UNREC logo.h /^ OUT_OF_MEM_UNREC, USER_ERR_MESSAGE, DEEPEND_NONAME,$/ One graphics.c /^#define One / PAREN_MISMATCH logo.h /^ DK_WHAT, PAREN_MISMATCH, NO_VALUE, UNEXPECTED_PAREN, DK_HOW,$/ PAUS_ING logo.h /^ ERRACT_LOOP, PAUS_ING, TRACE_STOPS, TRACE_OUTPUTS,$/ PC term.c /^char PC;$/ PENMODE_ERASE graphics.c /^#define PENMODE_ERASE / PENMODE_PAINT graphics.c /^#define PENMODE_PAINT / PENMODE_REVERSE graphics.c /^#define PENMODE_REVERSE / PERMANENT logo.h /^#define PERMANENT / PLIST_BURIED logo.h /^#define PLIST_BURIED / PLIST_STEPPED logo.h /^#define PLIST_STEPPED / PLIST_TRACED logo.h /^#define PLIST_TRACED / PNIL logo.h /^#define PNIL / POT_PLIST logo.h /^ EXIT_NOW, LOAD_DEF, TRACE_MAKE, EMPTY_PROC, POT_PLIST,$/ PREFIX_PRIORITY logo.h /^#define PREFIX_PRIORITY / PRIM logo.h /^#define PRIM / PRIMTYPE init.c /^} PRIMTYPE;$/ PROC_BURIED logo.h /^#define PROC_BURIED / PROC_MACRO logo.h /^#define PROC_MACRO / PROC_STEPPED logo.h /^#define PROC_STEPPED / PROC_TRACED logo.h /^#define PROC_TRACED / PUNBOUND logo.h /^#define PUNBOUND / Pause init.c /^ *Printwidthlimit, *Pause, *LoadNoisily, *AllowGetSet,$/ Printdepthlimit init.c /^NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit,$/ Printwidthlimit init.c /^ *Printwidthlimit, *Pause, *LoadNoisily, *AllowGetSet,$/ QUOTE logo.h /^#define QUOTE / Query init.c /^ *Minus_Sign, *Minus_Tight, *Startup, *Query, *UseAlternateNames;$/ RETSIGTYPE logo.h /^#define RETSIGTYPE / RUN logo.h /^typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE;$/ RUNNING logo.h /^#define RUNNING / RUNRESULT_OUTPUT_LEGAL eval.c /^#define RUNRESULT_OUTPUT_LEGAL / RUNRES_STOP logo.h /^ BAD_DEFAULT, RUNRES_STOP,$/ RUN_PARSE logo.h /^#define RUN_PARSE / Redefp init.c /^NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit,$/ Regs_Node eval.c /^NODE *Regs_Node;$/ Right_Paren init.c /^NODE *Right_Paren, *Left_Paren, *Redefp, *Caseignoredp, *Erract, *Printdepthlimit,$/ SAFEINT logo.h /^#define SAFEINT / SCREEN_FULL graphics.c /^enum {SCREEN_TEXT, SCREEN_SPLIT, SCREEN_FULL} screen_mode = SCREEN_TEXT;$/ SCREEN_SPLIT graphics.c /^enum {SCREEN_TEXT, SCREEN_SPLIT, SCREEN_FULL} screen_mode = SCREEN_TEXT;$/ SCREEN_TEXT graphics.c /^enum {SCREEN_TEXT, SCREEN_SPLIT, SCREEN_FULL} screen_mode = SCREEN_TEXT;$/ SEG_SIZE logo.h /^#define SEG_SIZE / SEG_SIZE logo.h /^#define SEG_SIZE / SETPENCOLOR graphics.c /^#define SETPENCOLOR / SETPENMODE graphics.c /^#define SETPENMODE / SETPENPATTERN graphics.c /^#define SETPENPATTERN / SETPENSIZE graphics.c /^#define SETPENSIZE / SETPENVIS graphics.c /^#define SETPENVIS / SHADOW_WARN logo.h /^ FILE_ERROR, IF_WARNING, SHADOW_WARN, USER_ERR, IS_PRIM,$/ SIGQUIT globals.h /^#define SIGQUIT / SIGQUIT main.c /^#define SIGQUIT / SIGRET logo.h /^#define SIGRET / SIG_TAKES_ARG logo.h /^#define SIG_TAKES_ARG$/ STACK logo.h /^#define STACK / STACK_OVERFLOW logo.h /^typedef enum { FATAL, OUT_OF_MEM, STACK_OVERFLOW, TURTLE_OUT_OF_BOUNDS,$/ STDC_HEADERS logo.h /^#define STDC_HEADERS$/ STOP logo.h /^typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE;$/ STOPPING logo.h /^#define STOPPING / STOP_ERROR logo.h /^ NO_CATCH_TAG, ALREADY_DEFINED, STOP_ERROR, ALREADY_DRIBBLING,$/ STOP_OK logo.h /^#define STOP_OK / STOP_PRIORITY logo.h /^#define STOP_PRIORITY / STOP_TAIL logo.h /^#define STOP_TAIL / STRING logo.h /^#define STRING / Startup init.c /^ *Minus_Sign, *Minus_Tight, *Startup, *Query, *UseAlternateNames;$/ TAILFORM logo.h /^#define TAILFORM / TAIL_PRIORITY logo.h /^#define TAIL_PRIORITY / THANK_YOU logo.h /^ THANK_YOU, NICE_DAY, NOSHELL_MAC, TYPE_EXIT, ERROR_IN,$/ THROWING logo.h /^typedef enum { RUN, STOP, OUTPUT, THROWING, MACRO_RETURN } CTRLTYPE;$/ TOO_MUCH logo.h /^ BAD_DATA_UNREC, DIDNT_OUTPUT, NOT_ENOUGH, BAD_DATA, TOO_MUCH,$/ TRACE_MAKE logo.h /^ EXIT_NOW, LOAD_DEF, TRACE_MAKE, EMPTY_PROC, POT_PLIST,$/ TRACE_OUTPUTS logo.h /^ ERRACT_LOOP, PAUS_ING, TRACE_STOPS, TRACE_OUTPUTS,$/ TRACE_PPROP logo.h /^ NOT_OPEN, TRACE_PPROP, WELCOME_TO, CANT_STOP, CANT_GC,$/ TRACE_STOPS logo.h /^ ERRACT_LOOP, PAUS_ING, TRACE_STOPS, TRACE_OUTPUTS,$/ TREE logo.h /^#define TREE / TRUE logo.h /^#define TRUE / TRUE term.c /^#define TRUE / TRUE term.c /^#undef TRUE$/ TURTLE_OUT_OF_BOUNDS logo.h /^typedef enum { FATAL, OUT_OF_MEM, STACK_OVERFLOW, TURTLE_OUT_OF_BOUNDS,$/ TYPE_EXIT logo.h /^ THANK_YOU, NICE_DAY, NOSHELL_MAC, TYPE_EXIT, ERROR_IN,$/ Three graphics.c /^#define Three / True init.c /^#define True / True xgraphics.h /^#undef True$/ TrueName logodata.c /^NODE *TrueName() {$/ Two graphics.c /^#define Two / UNBOUND logo.h /^#define UNBOUND / UNDEFINED logo.h /^#define UNDEFINED / UNEXPECTED_BRACE logo.h /^ UNEXPECTED_BRACE, BAD_GRAPH_INIT, ERR_MACRO,$/ UNEXPECTED_BRACKET logo.h /^ NOT_INSIDE, DK_HOW_UNREC, NO_TEST, UNEXPECTED_BRACKET,$/ UNEXPECTED_PAREN logo.h /^ DK_WHAT, PAREN_MISMATCH, NO_VALUE, UNEXPECTED_PAREN, DK_HOW,$/ UP term.c /^char *UP;$/ USER_ERR logo.h /^ FILE_ERROR, IF_WARNING, SHADOW_WARN, USER_ERR, IS_PRIM,$/ USER_ERR_MESSAGE logo.h /^ OUT_OF_MEM_UNREC, USER_ERR_MESSAGE, DEEPEND_NONAME,$/ Unbound init.c /^ *Unbound, *Not_Enough_Node,$/ UnburyOnEdit init.c /^ *UnburyOnEdit, *Fullprintp, *Make, *Listvalue, *Dotsvalue,$/ UseAlternateNames init.c /^ *Minus_Sign, *Minus_Tight, *Startup, *Query, *UseAlternateNames;$/ VALUE_OK logo.h /^#define VALUE_OK / VAL_BURIED logo.h /^#define VAL_BURIED / VAL_STEPPED logo.h /^#define VAL_STEPPED / VAL_TRACED logo.h /^#define VAL_TRACED / VBAR_STRING logo.h /^#define VBAR_STRING / WANT_EVAL_REGS coms.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS error.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS eval.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS init.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS logodata.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS mem.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS paren.c /^#define WANT_EVAL_REGS / WANT_EVAL_REGS wrksp.c /^#define WANT_EVAL_REGS / WELCOME_TO logo.h /^ NOT_OPEN, TRACE_PPROP, WELCOME_TO, CANT_STOP, CANT_GC,$/ WIN32_DEBUG globals.h /^#undef WIN32_DEBUG$/ WORDSIZE logo.h /^#define WORDSIZE / _LOGO_H logo.h /^#define _LOGO_H$/ __RZTC__ logo.h /^#define __RZTC__$/ __RZTC__ logo.h /^#undef __RZTC__$/ addseg mem.c /^BOOLEAN addseg(void) {$/ addsep wrksp.c /^char *addsep(char *path) {$/ aggregate logo.h /^#define aggregate(/ all_lists wrksp.c /^BOOLEAN all_lists(NODE *val) {$/ anonymous_function wrksp.c /^NODE *anonymous_function(NODE *text) {$/ append eval.c /^NODE *append(NODE *a, NODE *b) {$/ arg eval.c /^ *arg = NIL; \/* the current actual *\/$/ argl logo.h /^#define argl / asciiz files.c /^char *asciiz(NODE *arg) {$/ back_ground xgraphics.c /^int back_ground;$/ backslashed logo.h /^#define backslashed(/ bck wrksp.c /^int bck(int flag) {$/ bf3 eval.c /^NODE *bf3(NODE *name) {$/ bfable_arg lists.c /^NODE *bfable_arg(NODE *args) {$/ bg nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ binary math.c /^NODE *binary(NODE *args, char fcn) {$/ bodylist__procnode logo.h /^#define bodylist__procnode(/ bodywords__procnode logo.h /^#define bodywords__procnode(/ boldmode print.c /^BOOLEAN boldmode = 0;$/ bottom_stack main.c /^NODE **bottom_stack; \/*GC*\/$/ bp term.c /^char bp[1024];$/ bury_helper wrksp.c /^NODE *bury_helper(NODE *arg, BOOLEAN flag, BOOLEAN setp) {$/ button xgraphics.h /^#define button / c_PLISTS wrksp.c /^typedef enum {c_PROCS, c_VARS, c_PLISTS} CNTLSTTYP;$/ c_PROCS wrksp.c /^typedef enum {c_PROCS, c_VARS, c_PLISTS} CNTLSTTYP;$/ c_VARS wrksp.c /^typedef enum {c_PROCS, c_VARS, c_PLISTS} CNTLSTTYP;$/ caar logo.h /^#define caar(/ cadr logo.h /^#define cadr(/ canonical__object logo.h /^#define canonical__object(/ cap_strnzcpy logodata.c /^char *cap_strnzcpy(char *s1, char *s2, int n) {$/ capital logodata.c /^#define capital(/ car logo.h /^#define car(/ case_compare intern.c /^int case_compare(NODE *nd1, NODE *nd2) {$/ caselist__object logo.h /^#define caselist__object(/ caselistptr__object logo.h /^#define caselistptr__object(/ catch_tag eval.c /^ *catch_tag = NIL,$/ cdar logo.h /^#define cdar(/ cddr logo.h /^#define cddr(/ cdr logo.h /^#define cdr(/ char_arg lists.c /^NODE *char_arg(NODE *args) {$/ charmode_off term.c /^void charmode_off() {$/ charmode_on term.c /^void charmode_on() {$/ checkX xgraphics.h /^#define checkX / check_oldyoung mem.c /^void check_oldyoung(NODE *old, NODE *new) {$/ check_proctype wrksp.c /^NODE *check_proctype(NODE *args, int wanted) {$/ check_reserve_tank mem.c /^void check_reserve_tank(void) {$/ check_throwing logo.h /^#define check_throwing / check_valid_oldyoung mem.c /^void check_valid_oldyoung(NODE *old, NODE *new) {$/ check_x_high graphics.c /^void check_x_high(void) {$/ check_x_low graphics.c /^void check_x_low(void) {$/ circular lists.c /^int circular(NODE *arr, NODE *new) {$/ cl_arr term.c /^char cl_arr[40];$/ clear_screen xgraphics.h /^#define clear_screen / clearflag__caseobj logo.h /^#define clearflag__caseobj(/ clearparity logo.h /^#define clearparity(/ cm_arr term.c /^char cm_arr[40];$/ cnt_last wrksp.c /^NODE *cnt_last = NIL;$/ cnt_list wrksp.c /^NODE *cnt_list = NIL;$/ cnv_node_to_numnode logodata.c /^NODE *cnv_node_to_numnode(NODE *ndi) {$/ cnv_node_to_strnode logodata.c /^NODE *cnv_node_to_strnode(NODE *nd) {$/ colon_strnzcpy logodata.c /^char *colon_strnzcpy(char *s1, char *s2, int n) {$/ color xgraphics.c /^XColor color[NUMCOLORS];$/ color xgraphics.h /^ int color;$/ colorname xgraphics.c /^char *colorname[NUMINITCOLORS] = {$/ compare_node math.c /^int compare_node(NODE *n1, NODE *n2, BOOLEAN ignorecase) {$/ compare_numnodes math.c /^int compare_numnodes(NODE *n1, NODE *n2) {$/ cons mem.c /^NODE *cons(NODE *x, NODE *y) {$/ cons_list logodata.c /^NODE *cons_list(int dummy, ...) {$/ cont__cont logo.h /^#define cont__cont(/ contents_list_type wrksp.c /^CNTLSTTYP contents_list_type;$/ contents_map wrksp.c /^void contents_map(NODE *sym) {$/ copy_list logodata.c /^NODE *copy_list(NODE *arg) {$/ cs_helper graphics.c /^void cs_helper(int centerp) { $/ current_gc mem.c /^long int current_gc = 0;$/ current_line main.c /^NODE *current_line = NIL;$/ current_mode graphics.c /^mode_type current_mode = wrapmode;$/ current_unode logo.h /^#define current_unode / cut_error graphics.c /^FLONUM cut_error(FLONUM n) {$/ dbprint print.c /^void dbprint(NODE *data) {$/ deb_enum eval.c /^#define deb_enum(/ debprint eval.c /^#define debprint(/ debprint eval.c /^void debprint(char *name) {$/ debprint2 eval.c /^#define debprint2(/ decstrrefcnt logo.h /^#define decstrrefcnt(/ deep_copy eval.c /^NODE *deep_copy(NODE *exp) {$/ deepend_proc_name parse.c /^NODE *deepend_proc_name = NIL;$/ defargs init.c /^ short defargs;$/ define_helper wrksp.c /^NODE *define_helper(NODE *args, BOOLEAN macro_flag) {$/ degrad math.c /^FLONUM degrad = 0.017453292520;$/ degrad math.c /^FLONUM degrad = 3.141592653589793227020265931059839203954\/180.0;$/ dfltargs__procnode logo.h /^#define dfltargs__procnode(/ didnt_get_output logo.h /^#define didnt_get_output / didnt_output_name logo.h /^#define didnt_output_name / do_arc graphics.c /^void do_arc(FLONUM count, FLONUM ang, FLONUM radius, FLONUM delta,$/ do_case eval.c /^#define do_case(/ do_ctrl_c main.c /^void _far _cdecl do_ctrl_c(void) {$/ do_debug eval.c /^#define do_debug(/ do_enum logo.h /^#define do_enum(/ do_gc mem.c /^void do_gc(BOOLEAN full) {$/ do_list logo.h /^ do_list(do_enum)$/ do_list logo.h /^#define do_list(/ do_trans logo.h /^ do_trans(wd_enum)$/ do_trans logo.h /^#define do_trans(/ done_drawing xgraphics.h /^#define done_drawing / done_drawing_turtle xgraphics.h /^#define done_drawing_turtle / dont_fix_ift eval.c /^FIXNUM dont_fix_ift = 0;$/ dpy xgraphics.c /^Display *dpy; \/* X server connection *\/$/ draw_gc xgraphics.c /^GC draw_gc, \/* GC to draw with *\/$/ draw_string xgraphics.h /^#define draw_string(/ draw_turtle graphics.c /^void draw_turtle(void) {$/ draw_turtle_helper graphics.c /^void draw_turtle_helper(void) {$/ dribblestream parse.c /^FILE *dribblestream = NULL;$/ dummy xgraphics.c /^XColor dummy;$/ ecma logo.h /^#define ecma / ecma_array logodata.c /^char ecma_array[128];$/ ecma_begin logo.h /^#define ecma_begin / ecma_clear logodata.c /^char ecma_clear(int ch) {$/ ecma_get logodata.c /^int ecma_get(int ch) {$/ ecma_set logodata.c /^char ecma_set(int ch) {$/ ecma_size logodata.c /^int ecma_size = sizeof(special_chars)-1;$/ editor wrksp.c /^char *editor, *editorname, *tempdir;$/ editorname wrksp.c /^char *editor, *editorname, *tempdir;$/ equalp_help math.c /^BOOLEAN equalp_help(NODE *arg1, NODE *arg2, BOOLEAN ignc) {$/ erall_helper wrksp.c /^NODE *erall_helper(BOOLEAN procs, BOOLEAN vals, BOOLEAN plists) {$/ erase_gc xgraphics.c /^ erase_gc, \/* Erase gc. *\/$/ erase_screen xgraphics.h /^#define erase_screen(/ err_eval_driver eval.c /^NODE *err_eval_driver(NODE *seq, BOOLEAN recoverable) {$/ err_logo error.c /^NODE *err_logo(ERR_TYPES error_type, NODE *error_desc) {$/ err_mesg error.c /^NODE *err_mesg = NIL;$/ err_print error.c /^void err_print(char *buffer) {$/ erract_errtype error.c /^ERR_TYPES erract_errtype;$/ errchk math.c /^#define errchk(/ eval_driver eval.c /^void eval_driver(NODE *line) {$/ eval_restore eval.c /^void eval_restore() {$/ eval_save eval.c /^void eval_save() {$/ evaluator eval.c /^NODE *evaluator(NODE *list, enum labels where) {$/ even_p logo.h /^#define even_p(/ exp eval.c /^NODE *exp = NIL, \/* the current expression *\/$/ exp logo.h /^#define exp / expand_slash wrksp.c /^char *expand_slash(NODE *wd) {$/ fencemode logo.h /^typedef enum {wrapmode, fencemode, windowmode} mode_type;$/ file_list files.c /^NODE *file_list = NULL;$/ file_prefix files.c /^NODE *reader_name = NIL, *writer_name = NIL, *file_prefix = NIL;$/ fill_reserve_tank mem.c /^void fill_reserve_tank(void) {$/ find_case intern.c /^NODE *find_case(NODE *strnd, NODE *obj) {$/ find_file files.c /^FILE *find_file(NODE *arg, BOOLEAN remove) {$/ find_instance intern.c /^NODE *find_instance(NODE *lownd) {$/ find_limit print.c /^int find_limit(NODE *nd, int forced) {$/ fixhelp wrksp.c /^char *fixhelp(char *ptr, int len) {$/ flag__caseobj logo.h /^#define flag__caseobj(/ flag__object logo.h /^#define flag__object(/ flatten eval.c /^NODE *flatten(NODE *a) {$/ float_arg lists.c /^FLONUM float_arg(NODE *args) {$/ floodfill xgraphics.c /^void floodfill( XImage *img, int x, int y, unsigned long$/ force_printdepth print.c /^int force_printwidth = -1, force_printdepth = -1;$/ force_printwidth print.c /^int force_printwidth = -1, force_printdepth = -1;$/ formals logo.h /^#define formals / formals__procnode logo.h /^#define formals__procnode(/ forward graphics.c /^void forward(FLONUM d) {$/ forward_helper graphics.c /^void forward_helper(FLONUM d) {$/ free_list mem.c /^NODE *free_list = NIL; \/* global ptr to free node list *\/$/ freed_threshold mem.c /^#define freed_threshold / full_screen xgraphics.h /^#define full_screen / fun logo.h /^#define fun / g_round graphics.c /^FIXNUM g_round(FLONUM n) {$/ gather_args paren.c /^NODE *gather_args(NODE *newfun, NODE *pproc, NODE **args, BOOLEAN inparen,$/ gather_some_args paren.c /^NODE *gather_some_args(int min, int max, NODE **args, BOOLEAN inparen,$/ gc mem.c /^void gc(BOOLEAN no_error) {$/ gc_age_threshold mem.c /^#define gc_age_threshold / gc_inc mem.c /^void gc_inc () {$/ gc_overflow_flag mem.c /^long int gc_overflow_flag = 0;$/ gc_stack_malloced mem.c /^long int gc_stack_malloced = 0;$/ gc_stack_size mem.c /^long int gc_stack_size = GCMAX;$/ gcbottom mem.c /^NODE **gcbottom = gcstack;$/ gcstack mem.c /^NODE *gcstack[GCMAX];$/ gctop mem.c /^NODE **gctop = gcstack;$/ gen_age logo.h /^ int gen_age; \/* How many times to GC at this generation *\/$/ generation mem.c /^NODE *generation[NUM_GENS] = {NIL};$/ generation__line logo.h /^#define generation__line(/ generation__tree logo.h /^#define generation__tree(/ get_bodywords wrksp.c /^NODE *get_bodywords(NODE *pproc, NODE *name) {$/ get_contents wrksp.c /^NODE *get_contents() {$/ get_mouse_x xgraphics.c /^int get_mouse_x()$/ get_mouse_y xgraphics.c /^int get_mouse_y()$/ get_node_pen_pattern xgraphics.h /^#define get_node_pen_pattern / get_palette xgraphics.c /^void get_palette(int n, unsigned int *r, unsigned int *g, unsigned int *b) {$/ get_pen_pattern xgraphics.h /^#define get_pen_pattern(/ getarrdim logo.h /^#define getarrdim(/ getarrorg logo.h /^#define getarrorg(/ getarrptr logo.h /^#define getarrptr(/ getfloat logo.h /^#define getfloat(/ getint logo.h /^#define getint(/ getobject logo.h /^#define getobject(/ getparity logo.h /^#define getparity(/ getprimdflt logo.h /^#define getprimdflt(/ getprimfun logo.h /^#define getprimfun(/ getprimmax logo.h /^#define getprimmax(/ getprimmin logo.h /^#define getprimmin(/ getprimpri logo.h /^#define getprimpri(/ getprop logodata.c /^NODE *getprop(NODE *plist, NODE *name, BOOLEAN before)$/ getstrhead logo.h /^#define getstrhead(/ getstrlen logo.h /^#define getstrlen(/ getstrptr logo.h /^#define getstrptr(/ getstrrefcnt logo.h /^#define getstrrefcnt(/ handle_oflo math.c /^RETSIGTYPE handle_oflo(int sig) {$/ handling_oflo math.c /^BOOLEAN handling_oflo = FALSE;$/ hash intern.c /^FIXNUM hash(char *s, int len) {$/ hash_table intern.c /^NODE *hash_table[HASH_LEN] = {NIL};$/ have_x xgraphics.c /^int have_x = -1;$/ helpfiles eval.c /^char *logolib, *helpfiles;$/ helploc libloc.c /^char *helploc="\/usr\/local\/lib\/logo\/helpfiles";$/ iblk_buf main.c /^jmp_buf iblk_buf;$/ ibm logo.h /^#define ibm$/ ift_iff_flag logo.h /^#define ift_iff_flag / in_eval_save eval.c /^int in_eval_save = 0;$/ incstrrefcnt logo.h /^#define incstrrefcnt(/ infixs parse.c /^#define infixs(/ init init.c /^void init(void) {$/ inops wrksp.c /^char inops[] = "+-*\/=<>";$/ input_blocking parse.c /^int input_blocking = 0;$/ inside_gc mem.c /^BOOLEAN inside_gc = 0, int_during_gc = 0;$/ int_arg lists.c /^FIXNUM int_arg(NODE *args) {$/ int_during_gc mem.c /^BOOLEAN inside_gc = 0, int_during_gc = 0;$/ integer_arg lists.c /^NODE *integer_arg(NODE *args) {$/ inter_gen_mark mem.c /^NODE **inter_gen_mark (NODE **prev) {$/ interactive term.c /^int interactive, tty_charmode;$/ intern intern.c /^NODE *intern(NODE *nd) {$/ intern_p init.c /^NODE *intern_p(NODE *caseobj) {$/ internal_penmode graphics.c /^int internal_penmode = PENMODE_PAINT;$/ into_line parse.c /^#define into_line(/ isName logodata.c /^int isName(NODE *nod, enum words wd) {$/ is_cont logo.h /^#define is_cont(/ is_list logo.h /^#define is_list(/ is_macro logo.h /^#define is_macro(/ is_number logo.h /^#define is_number(/ is_prim logo.h /^#define is_prim(/ is_setter paren.c /^int is_setter(NODE *name) {$/ is_string logo.h /^#define is_string(/ is_tailform logo.h /^#define is_tailform(/ is_tree logo.h /^#define is_tree(/ is_word logo.h /^#define is_word(/ isdigit math.c /^#define isdigit(/ l_eq math.c /^NODE *l_eq(NODE *args) {$/ l_setbf lists.c /^NODE *l_setbf(NODE *args) {$/ l_setfirst lists.c /^NODE *l_setfirst(NODE *args) {$/ l_setitem lists.c /^NODE *l_setitem(NODE *args) {$/ label xgraphics.h /^#define label(/ labels logo.h /^enum labels {$/ ladd math.c /^NODE *ladd(NODE *args) {$/ lallopen files.c /^NODE *lallopen(NODE *args) {$/ land coms.c /^NODE *land(NODE *args) {$/ lapply eval.c /^NODE *lapply(NODE *args) {$/ larc graphics.c /^NODE *larc(NODE *arg) {$/ larity wrksp.c /^NODE *larity(NODE *args) {$/ larray lists.c /^NODE *larray(NODE *args) {$/ larrayp lists.c /^NODE *larrayp(NODE *arg) {$/ larraytolist lists.c /^NODE *larraytolist(NODE *args) {$/ lascii lists.c /^NODE *lascii(NODE *args) {$/ lashift math.c /^NODE *lashift(NODE *args) {$/ last_call eval.c /^*last_call = NIL, \/* the last proc called *\/$/ last_line logo.h /^#define last_line / last_ufun logo.h /^#define last_ufun / latan math.c /^NODE *latan(NODE *args) {$/ lback graphics.c /^NODE *lback(NODE *arg) {$/ lbackground graphics.c /^NODE *lbackground(NODE *args) {$/ lbackslashedp lists.c /^NODE *lbackslashedp(NODE *args) {$/ lbeforep math.c /^NODE *lbeforep(NODE *args) {$/ lbfs lists.c /^NODE *lbfs(NODE *args) {$/ lbitand math.c /^NODE *lbitand(NODE *args) {$/ lbitnot math.c /^NODE *lbitnot(NODE *args) {$/ lbitor math.c /^NODE *lbitor(NODE *args) {$/ lbitxor math.c /^NODE *lbitxor(NODE *args) {$/ lburied wrksp.c /^NODE *lburied(NODE *args) {$/ lburiedp wrksp.c /^NODE *lburiedp(NODE *arg) {$/ lbury wrksp.c /^NODE *lbury(NODE *arg) {$/ lbutfirst lists.c /^NODE *lbutfirst(NODE *args) {$/ lbutlast lists.c /^NODE *lbutlast(NODE *args) {$/ lbuttonp graphics.c /^NODE *lbuttonp(NODE *args) {$/ lbye coms.c /^NODE *lbye(NODE *args) {$/ lcatch coms.c /^NODE *lcatch(NODE *args) {$/ lchar lists.c /^NODE *lchar(NODE *args) {$/ lclean graphics.c /^NODE *lclean(NODE *args) {$/ lclearscreen graphics.c /^NODE *lclearscreen(NODE *args) {$/ lcleartext term.c /^NODE *lcleartext(NODE *args) {$/ lclose files.c /^NODE *lclose(NODE *arg) {$/ lcontents wrksp.c /^NODE *lcontents(NODE *args) {$/ lcontinue error.c /^NODE *lcontinue(NODE *args) {$/ lcopydef wrksp.c /^NODE *lcopydef(NODE *args) {$/ lcos math.c /^NODE *lcos(NODE *args) {$/ lcount lists.c /^NODE *lcount(NODE *args) {$/ lcursor term.c /^NODE *lcursor(NODE *args) {$/ ldefine wrksp.c /^NODE *ldefine(NODE *args) {$/ ldefinedp wrksp.c /^NODE *ldefinedp(NODE *args) {$/ ldefmacro wrksp.c /^NODE *ldefmacro(NODE *args) {$/ ldivide math.c /^NODE *ldivide(NODE *args) {$/ ldribble files.c /^NODE *ldribble(NODE *arg) {$/ ledit wrksp.c /^NODE *ledit(NODE *args) {$/ leditfile wrksp.c /^NODE *leditfile(NODE *args) {$/ lemptyp lists.c /^NODE *lemptyp(NODE *arg) {$/ leofp files.c /^NODE *leofp(NODE *args) {$/ lepspict graphics.c /^NODE *lepspict(NODE *args) {$/ lequalp math.c /^NODE *lequalp(NODE *args) {$/ lerall wrksp.c /^NODE *lerall(NODE *args) {$/ lerase wrksp.c /^NODE *lerase(NODE *arg) {$/ lerasefile files.c /^NODE *lerasefile(NODE *arg) {$/ lerns wrksp.c /^NODE *lerns(NODE *args) {$/ lerpls wrksp.c /^NODE *lerpls(NODE *args) {$/ lerps wrksp.c /^NODE *lerps(NODE *args) {$/ lerror error.c /^NODE *lerror(NODE *args) {$/ lexp math.c /^NODE *lexp(NODE *args) {$/ lfence graphics.c /^NODE *lfence(NODE *args) {$/ lfill graphics.c /^NODE *lfill(NODE *args) {$/ lfirst lists.c /^NODE *lfirst(NODE *args) {$/ lfirsts lists.c /^NODE *lfirsts(NODE *args) {$/ lforever coms.c /^NODE *lforever(NODE *args) {$/ lform lists.c /^NODE *lform(NODE *args) {$/ lforward graphics.c /^NODE *lforward(NODE *arg) {$/ lfput lists.c /^NODE *lfput(NODE *args) {$/ lfullscreen graphics.c /^NODE *lfullscreen(NODE *args) {$/ lfulltext wrksp.c /^NODE *lfulltext(NODE *args) {$/ lgc mem.c /^NODE *lgc(NODE *args) {$/ lglobal wrksp.c /^NODE *lglobal(NODE *args) {$/ lgoto coms.c /^NODE *lgoto(NODE *args) {$/ lgprop logodata.c /^NODE *lgprop(NODE *args) {$/ lgreaterp math.c /^NODE *lgreaterp(NODE *args) {$/ lheading graphics.c /^NODE *lheading(NODE *args) {$/ lhelp wrksp.c /^NODE *lhelp(NODE *args) {$/ lhideturtle graphics.c /^NODE *lhideturtle(NODE *args) {$/ lhome graphics.c /^NODE *lhome(NODE *args) {$/ libloc libloc.c /^char *libloc="\/usr\/local\/lib\/logo\/logolib";$/ lif coms.c /^NODE *lif(NODE *args) { \/* macroized *\/$/ lifelse coms.c /^NODE *lifelse(NODE *args) { \/* macroized *\/$/ liffalse coms.c /^NODE *liffalse(NODE *args) {$/ liftrue coms.c /^NODE *liftrue(NODE *args) {$/ line_to xgraphics.h /^#define line_to(/ linteg math.c /^NODE *linteg(NODE *args) {$/ list_arg lists.c /^NODE *list_arg(NODE *args) {$/ list_to_array parse.c /^NODE *list_to_array(NODE *list) {$/ litem lists.c /^NODE *litem(NODE *args) {$/ lkeyp files.c /^NODE *lkeyp(NODE *args) {$/ llabel graphics.c /^NODE *llabel(NODE *arg) {$/ llast lists.c /^NODE *llast(NODE *args) {$/ lleft graphics.c /^NODE *lleft(NODE *arg) {$/ llessp math.c /^NODE *llessp(NODE *args) {$/ llist lists.c /^NODE *llist(NODE *args) {$/ llistp lists.c /^NODE *llistp(NODE *arg) {$/ llisttoarray lists.c /^NODE *llisttoarray(NODE *args) {$/ lln math.c /^NODE *lln(NODE *args) {$/ lload files.c /^NODE *lload(NODE *arg) {$/ lloadpict graphics.c /^NODE *lloadpict(NODE *args) {$/ llocal wrksp.c /^NODE *llocal(NODE *args) {$/ llog10 math.c /^NODE *llog10(NODE *args) {$/ llowercase logodata.c /^NODE *llowercase(NODE *args) {$/ llput lists.c /^NODE *llput(NODE *args) {$/ llshift math.c /^NODE *llshift(NODE *args) {$/ lmacro wrksp.c /^NODE *lmacro(NODE *args) {$/ lmacrop wrksp.c /^NODE *lmacrop(NODE *args) {$/ lmake wrksp.c /^NODE *lmake(NODE *args) {$/ lmember lists.c /^NODE *lmember(NODE *args) {$/ lmemberp lists.c /^NODE *lmemberp(NODE *args) {$/ lmodulo math.c /^NODE *lmodulo(NODE *args) {$/ lmousepos graphics.c /^NODE *lmousepos(NODE *args) {$/ lmul math.c /^NODE *lmul(NODE *args) {$/ lnamep wrksp.c /^NODE *lnamep(NODE *args) {$/ lnames wrksp.c /^NODE *lnames(NODE *args) {$/ lnodes mem.c /^NODE *lnodes(NODE *args) {$/ lnodribble files.c /^NODE *lnodribble(NODE *args) {$/ lnorefresh graphics.c /^NODE *lnorefresh(NODE *args) {$/ lnot coms.c /^NODE *lnot(NODE *args) {$/ lnumberp lists.c /^NODE *lnumberp(NODE *arg) {$/ loadstream parse.c /^FILE *loadstream;$/ logo_node logo.h /^typedef struct logo_node {$/ logo_pause main.c /^RETSIGTYPE logo_pause()$/ logo_stop main.c /^RETSIGTYPE logo_stop()$/ logofill xgraphics.c /^void logofill() {$/ logolib eval.c /^char *logolib, *helpfiles;$/ lopen files.c /^NODE *lopen(NODE *arg, char *mode) {$/ lopenappend files.c /^NODE *lopenappend(NODE *arg) {$/ lopenread files.c /^NODE *lopenread(NODE *arg) {$/ lopenupdate files.c /^NODE *lopenupdate(NODE *arg) {$/ lopenwrite files.c /^NODE *lopenwrite(NODE *arg) {$/ lor coms.c /^NODE *lor(NODE *args) {$/ loutput coms.c /^NODE *loutput(NODE *arg) {$/ low_strncmp logodata.c /^int low_strncmp(char *s1, char *s2, int n) {$/ low_strnzcpy logodata.c /^char *low_strnzcpy(char *s1, char *s2, int n) {$/ lower_p logodata.c /^#define lower_p(/ lpalette graphics.c /^NODE *lpalette(NODE *args) {$/ lparse parse.c /^NODE *lparse(NODE *args) {$/ lpause error.c /^NODE *lpause(NODE *args) {$/ lpencolor graphics.c /^NODE *lpencolor(NODE *args) {$/ lpendown graphics.c /^NODE *lpendown(NODE *args) {$/ lpendownp graphics.c /^NODE *lpendownp(NODE *args) {$/ lpenerase graphics.c /^NODE *lpenerase(NODE *args) {$/ lpenmode graphics.c /^NODE *lpenmode(NODE *args) {$/ lpenpaint graphics.c /^NODE *lpenpaint(NODE *args) {$/ lpenpattern graphics.c /^NODE *lpenpattern(NODE *args) {$/ lpenreverse graphics.c /^NODE *lpenreverse(NODE *args) {$/ lpensize graphics.c /^NODE *lpensize(NODE *args) {$/ lpenup graphics.c /^NODE *lpenup(NODE *args) {$/ lplist logodata.c /^NODE *lplist(NODE *args) {$/ lplistp wrksp.c /^NODE *lplistp(NODE *args) {$/ lplists wrksp.c /^NODE *lplists(NODE *args) {$/ lpo wrksp.c /^NODE *lpo(NODE *arg) {$/ lpos graphics.c /^NODE *lpos(NODE *args) {$/ lpot wrksp.c /^NODE *lpot(NODE *arg) {$/ lpower math.c /^NODE *lpower(NODE *args) {$/ lpprop logodata.c /^NODE *lpprop(NODE *args) {$/ lprefix files.c /^NODE *lprefix(NODE *args) {$/ lprimitivep wrksp.c /^NODE *lprimitivep(NODE *args) {$/ lprint print.c /^NODE *lprint(NODE *args) {$/ lprocedurep wrksp.c /^NODE *lprocedurep(NODE *args) {$/ lprocedures wrksp.c /^NODE *lprocedures(NODE *args) {$/ lqm eval.c /^NODE *lqm(NODE *args) {$/ lradatan math.c /^NODE *lradatan(NODE *args) {$/ lradcos math.c /^NODE *lradcos(NODE *args) {$/ lradsin math.c /^NODE *lradsin(NODE *args) {$/ lrandom math.c /^NODE *lrandom(NODE *arg) {$/ lrawascii lists.c /^NODE *lrawascii(NODE *args) {$/ lreadchar files.c /^NODE *lreadchar(NODE *args) {$/ lreadchars files.c /^NODE *lreadchars(NODE *args) {$/ lreader files.c /^NODE *lreader(NODE *args) {$/ lreadlist files.c /^NODE *lreadlist(NODE *args) {$/ lreadpos files.c /^NODE *lreadpos(NODE *args) {$/ lreadrawline files.c /^NODE *lreadrawline(NODE *args) {$/ lreadword files.c /^NODE *lreadword(NODE *args) {$/ lrefresh graphics.c /^NODE *lrefresh(NODE *args) {$/ lremainder math.c /^NODE *lremainder(NODE *args) {$/ lremprop logodata.c /^NODE *lremprop(NODE *args) {$/ lrepcount coms.c /^NODE *lrepcount(NODE *args) {$/ lrepeat coms.c /^NODE *lrepeat(NODE *args) {$/ lrerandom math.c /^NODE *lrerandom(NODE *arg) {$/ lright graphics.c /^NODE *lright(NODE *arg) {$/ lroundx math.c /^NODE *lroundx(NODE *args) { \/* There's an lround in *\/$/ lrun coms.c /^NODE *lrun(NODE *args) { \/* macroized *\/$/ lrunparse parse.c /^NODE *lrunparse(NODE *args) {$/ lrunresult coms.c /^NODE *lrunresult(NODE *args) {$/ lsave files.c /^NODE *lsave(NODE *arg) {$/ lsavepict graphics.c /^NODE *lsavepict(NODE *args) {$/ lscreenmode graphics.c /^NODE *lscreenmode(NODE *args) {$/ lscrunch graphics.c /^NODE *lscrunch(NODE *args) {$/ lsentence lists.c /^NODE *lsentence(NODE *args) {$/ lsetbackground graphics.c /^NODE *lsetbackground(NODE *arg) {$/ lsetcursor term.c /^NODE *lsetcursor(NODE *args) {$/ lseteditor files.c /^NODE *lseteditor(NODE *args) {$/ lsetheading graphics.c /^NODE *lsetheading(NODE *arg) {$/ lsethelploc files.c /^NODE *lsethelploc(NODE *args) {$/ lsetitem lists.c /^NODE *lsetitem(NODE *args) {$/ lsetlibloc files.c /^NODE *lsetlibloc(NODE *args) {$/ lsetmargins term.c /^NODE *lsetmargins(NODE *args) {$/ lsetpalette graphics.c /^NODE *lsetpalette(NODE *args) {$/ lsetpencolor graphics.c /^NODE *lsetpencolor(NODE *arg) {$/ lsetpenpattern graphics.c /^NODE *lsetpenpattern(NODE *args) { $/ lsetpensize graphics.c /^NODE *lsetpensize(NODE *args) {$/ lsetpos graphics.c /^NODE *lsetpos(NODE *args) {$/ lsetprefix files.c /^NODE *lsetprefix(NODE *args) {$/ lsetread files.c /^NODE *lsetread(NODE *arg) {$/ lsetreadpos files.c /^NODE *lsetreadpos(NODE *arg) {$/ lsetscrunch graphics.c /^NODE *lsetscrunch(NODE *args) {$/ lsetsegsz mem.c /^NODE *lsetsegsz(NODE *args) {$/ lsettemploc files.c /^NODE *lsettemploc(NODE *args) {$/ lsetwrite files.c /^NODE *lsetwrite(NODE *arg) {$/ lsetwritepos files.c /^NODE *lsetwritepos(NODE *arg) {$/ lsetx graphics.c /^NODE *lsetx(NODE *args) {$/ lsetxy graphics.c /^NODE *lsetxy(NODE *args) {$/ lsety graphics.c /^NODE *lsety(NODE *args) {$/ lshell coms.c /^NODE *lshell(NODE *args) {$/ lshow print.c /^NODE *lshow(NODE *args) {$/ lshownp graphics.c /^NODE *lshownp(NODE *args) {$/ lshowturtle graphics.c /^NODE *lshowturtle(NODE *args) {$/ lsin math.c /^NODE *lsin(NODE *args) {$/ lsplitscreen graphics.c /^NODE *lsplitscreen(NODE *args) {$/ lsqrt math.c /^NODE *lsqrt(NODE *args) {$/ lstandout term.c /^NODE *lstandout(NODE *args) {$/ lstep wrksp.c /^NODE *lstep(NODE *arg) {$/ lstepped wrksp.c /^NODE *lstepped(NODE *args) {$/ lsteppedp wrksp.c /^NODE *lsteppedp(NODE *arg) {$/ lstop coms.c /^NODE *lstop(NODE *args) {$/ lsub math.c /^NODE *lsub(NODE *args) {$/ lsubstringp lists.c /^NODE *lsubstringp(NODE *args) {$/ ltag coms.c /^NODE *ltag(NODE *args) {$/ ltest coms.c /^NODE *ltest(NODE *args) {$/ ltext wrksp.c /^NODE *ltext(NODE *args) {$/ ltextscreen graphics.c /^NODE *ltextscreen(NODE *args) {$/ lthing wrksp.c /^NODE *lthing(NODE *args) {$/ lthrow coms.c /^NODE *lthrow(NODE *arg) {$/ lto wrksp.c /^NODE *lto(NODE *args) {$/ ltone graphics.c /^NODE *ltone(NODE *args) {$/ ltowards graphics.c /^NODE *ltowards(NODE *args) {$/ ltrace wrksp.c /^NODE *ltrace(NODE *arg) {$/ ltraced wrksp.c /^NODE *ltraced(NODE *args) {$/ ltracedp wrksp.c /^NODE *ltracedp(NODE *arg) {$/ lturtlemode graphics.c /^NODE *lturtlemode(NODE *args) {$/ ltype print.c /^NODE *ltype(NODE *args) {$/ lunbury wrksp.c /^NODE *lunbury(NODE *arg) {$/ lunstep wrksp.c /^NODE *lunstep(NODE *arg) {$/ luntrace wrksp.c /^NODE *luntrace(NODE *arg) {$/ luppercase logodata.c /^NODE *luppercase(NODE *args) {$/ lwait coms.c /^NODE *lwait(NODE *args) {$/ lwindow graphics.c /^NODE *lwindow(NODE *args) {$/ lword lists.c /^NODE *lword(NODE *args) {$/ lwordp lists.c /^NODE *lwordp(NODE *arg) {$/ lwrap graphics.c /^NODE *lwrap(NODE *args) {$/ lwritepos files.c /^NODE *lwritepos(NODE *args) {$/ lwriter files.c /^NODE *lwriter(NODE *args) {$/ mac logo.h /^#define mac$/ main main.c /^int main(int argc, char *argv[]) {$/ make_array logodata.c /^NODE *make_array(FIXNUM len) {$/ make_case intern.c /^NODE *make_case(NODE *casestrnd, NODE *obj) {$/ make_caseobj logodata.c /^NODE *make_caseobj(NODE *cstrnd, NODE *obj) {$/ make_colon logodata.c /^NODE *make_colon(NODE *cnd) {$/ make_cont coms.c /^NODE *make_cont(enum labels cont, NODE *val) {$/ make_floatnode logodata.c /^NODE *make_floatnode(FLONUM f) {$/ make_instance intern.c /^NODE *make_instance(NODE *casend, NODE *lownd) {$/ make_intnode logodata.c /^NODE *make_intnode(FIXNUM i) {$/ make_line paren.c /^void make_line(NODE *tree, NODE *line) {$/ make_object intern.c /^NODE *make_object(NODE *canonical, NODE *oproc, NODE *val,$/ make_procnode wrksp.c /^NODE *make_procnode(NODE *lst, NODE *wrds, int min, int df, int max) {$/ make_quote logodata.c /^NODE *make_quote(NODE *qnd) {$/ make_runparse logodata.c /^void make_runparse(NODE *ndi) {$/ make_static_strnode logodata.c /^NODE *make_static_strnode(char *strptr) {$/ make_strnode logodata.c /^NODE *make_strnode(char *strptr, struct string_block *strhead, int len,$/ make_tree paren.c /^void make_tree(NODE *list) {$/ make_tree_from_body paren.c /^void make_tree_from_body(NODE *body) {$/ map_oblist intern.c /^void map_oblist(void (*fcn)()) {$/ mark mem.c /^void mark(NODE* nd) {$/ mark_gc logo.h /^ long int mark_gc; \/* when marked *\/$/ mark_gcstack mem.c /^NODE **mark_gcstack = gcstack;$/ mark_gen_gc mem.c /^int mark_gen_gc;$/ matherr math.c /^int matherr(struct exception *x) {$/ max_gen mem.c /^int next_gen_gc = 0, max_gen = 0;$/ max_palette_slot graphics.c /^int max_palette_slot = 0;$/ maxargs init.c /^ short maxargs;$/ maxargs__procnode logo.h /^#define maxargs__procnode(/ maybe_quote logodata.c /^NODE *maybe_quote(NODE *nd) {$/ mem_allocated mem.c /^long int mem_allocated = 0, mem_freed = 0;$/ mem_freed mem.c /^long int mem_allocated = 0, mem_freed = 0;$/ mem_max mem.c /^long int mem_nodes = 0, mem_max = 0; \/* for Logo NODES primitive *\/$/ mem_nodes mem.c /^long int mem_nodes = 0, mem_max = 0; \/* for Logo NODES primitive *\/$/ memberp_help lists.c /^NODE *memberp_help(NODE *args, BOOLEAN notp, BOOLEAN substr) {$/ memcpy error.c /^void memcpy(char *to, char *from, size_t len) {$/ mend_nosemi logodata.c /^char *mend_nosemi(char *s1, char *s2, int n) {$/ mend_strnzcpy logodata.c /^char *mend_strnzcpy(char *s1, char *s2, int n) {$/ merge wrksp.c /^NODE *merge(NODE *a, NODE *b) {$/ mergepairs wrksp.c /^void mergepairs(NODE *nd) {$/ mergesrt wrksp.c /^NODE *mergesrt(NODE *nd) { \/* spelled funny to avoid library conflict *\/$/ message_texts error.c /^char *message_texts[MAX_MESSAGE+NUM_WORDS];$/ minargs init.c /^ short minargs;$/ minargs__procnode logo.h /^#define minargs__procnode(/ mmark mem.c /^#define mmark(/ mode_type logo.h /^typedef enum {wrapmode, fencemode, windowmode} mode_type;$/ mouse_x xgraphics.h /^#define mouse_x / mouse_y xgraphics.h /^#define mouse_y / move_to xgraphics.h /^#define move_to(/ ms_listlist wrksp.c /^void ms_listlist(NODE *nd) {$/ my_gen logo.h /^ int my_gen; \/* Nodes's Generation *\/ \/*GC*\/$/ n_array logo.h /^#define n_array / n_car logo.h /^#define n_car / n_cdr logo.h /^#define n_cdr / n_dim logo.h /^#define n_dim / n_float logo.h /^#define n_float / n_head logo.h /^#define n_head / n_int logo.h /^#define n_int / n_len logo.h /^#define n_len / n_obj logo.h /^#define n_obj / n_org logo.h /^#define n_org / n_pdef logo.h /^#define n_pdef / n_pfun logo.h /^#define n_pfun / n_pmax logo.h /^#define n_pmax / n_pmin logo.h /^#define n_pmin / n_ppri logo.h /^#define n_ppri / n_str logo.h /^#define n_str / name init.c /^ char *name;$/ name_arg wrksp.c /^NODE *name_arg(NODE *args) {$/ narray logo.h /^ } narray;$/ narray_data logo.h /^ struct logo_node **narray_data;$/ narray_dim logo.h /^ FIXNUM narray_dim;$/ narray_origin logo.h /^ FIXNUM narray_origin;$/ ncar logo.h /^ struct logo_node *ncar;$/ ncdr logo.h /^ struct logo_node *ncdr;$/ ncons logo.h /^ } ncons;$/ ndef_args logo.h /^ short ndef_args;$/ ndprintf print.c /^void ndprintf(FILE *strm, char *fmt, ...) {$/ new_line print.c /^void new_line(FILE *strm) {$/ newcont eval.c /^#define newcont(/ newnode mem.c /^NODE *newnode(NODETYPES type) {$/ next logo.h /^ struct segment *next;$/ next logo.h /^ struct logo_node *next; \/* Link together nodes of the same age *\/ \/*GC*\/$/ next_gen_gc mem.c /^int next_gen_gc = 0, max_gen = 0;$/ nfloat logo.h /^ FLONUM nfloat;$/ nint logo.h /^ FIXNUM nint;$/ nmax_args logo.h /^ short nmax_args;$/ nmin_args logo.h /^ short nmin_args;$/ nobj logo.h /^ struct logo_node *nobj; \/* used only for oblist etc *\/$/ node__colon logo.h /^#define node__colon(/ node__quote logo.h /^#define node__quote(/ node_type logo.h /^ NODETYPES node_type;$/ nodes logo.h /^ struct logo_node nodes[0];$/ nodes logo.h /^ struct logo_node nodes[1];$/ nodetype mem.c /^NODETYPES nodetype(NODE *nd) {$/ nop nographics.c /^void nop()$/ nop xgraphics.c /^void nop() {$/ noparity_strncmp logodata.c /^int noparity_strncmp(char *s1, char *s2, int n) {$/ noparity_strnzcpy logodata.c /^char *noparity_strnzcpy(char *s1, char *s2, int n) {$/ noparitylow_strncmp logodata.c /^int noparitylow_strncmp(char *s1, char *s2, int n) {$/ noparitylow_strnzcpy logodata.c /^char *noparitylow_strnzcpy(char *s1, char *s2, int n) {$/ not_local eval.c /^int not_local(NODE *name, NODE *sp) {$/ nprim logo.h /^ } nprim;$/ nprim_fun logo.h /^ struct logo_node * (*nprim_fun) ();$/ npriority logo.h /^ short npriority;$/ nstring logo.h /^ } nstring;$/ nstring_head logo.h /^ struct string_block *nstring_head;$/ nstring_len logo.h /^ FIXNUM nstring_len;$/ nstring_ptr logo.h /^ char *nstring_ptr;$/ num2restore eval.c /^#define num2restore(/ num2save eval.c /^#define num2save(/ num_examined mem.c /^long int num_examined;$/ num_saved_nodes eval.c /^int num_saved_nodes;$/ numberp math.c /^int numberp(NODE *snd) {$/ numeric_arg graphics.c /^NODE *numeric_arg(NODE *args) {$/ numpush eval.c /^void numpush(FIXNUM obj, NODE **stack) {$/ numrestore eval.c /^#define numrestore(/ numsave eval.c /^#define numsave(/ numstack eval.c /^ *numstack = NIL,\/* stack whose elements aren't objects *\/$/ nunion logo.h /^ } nunion;$/ obflags__caseobj logo.h /^#define obflags__caseobj(/ obflags__object logo.h /^#define obflags__object(/ object__caseobj logo.h /^#define object__caseobj(/ oflo_buf math.c /^jmp_buf oflo_buf;$/ oldyoung_next logo.h /^ struct logo_node *oldyoung_next;$/ oldyoungs mem.c /^NODE *oldyoungs = NIL;$/ one_list wrksp.c /^NODE *one_list(NODE *nd) {$/ open_file files.c /^FILE *open_file(NODE *arg, char *access) {$/ orig_pen graphics.c /^pen_info orig_pen;$/ ospeed term.c /^short ospeed;$/ out_of_bounds graphics.c /^BOOLEAN out_of_bounds = FALSE;$/ output_node eval.c /^*output_node = NIL, \/* the output of the current function *\/$/ output_unode eval.c /^*output_unode = NIL; \/* the unode in which we saw the output *\/$/ p_end parse.c /^char *p_line = 0, *p_end;$/ p_info_x xgraphics.h /^#define p_info_x(/ p_info_y xgraphics.h /^#define p_info_y(/ p_len parse.c /^int p_len = MAX_PHYS_LINE;$/ p_line parse.c /^char *p_line = 0, *p_end;$/ paren_expr paren.c /^NODE *paren_expr(NODE **expr, BOOLEAN inparen) {$/ paren_infix paren.c /^NODE *paren_infix(NODE *left_arg, NODE **rest, int old_pri, BOOLEAN inparen) {$/ paren_line paren.c /^NODE *paren_line(NODE *line) {$/ parens parse.c /^#define parens(/ parm eval.c /^ *parm = NIL, \/* the current formal *\/$/ parsed__runparse logo.h /^#define parsed__runparse(/ parser parse.c /^NODE *parser(NODE *nd, BOOLEAN semi) {$/ parser_iterate parse.c /^NODE *parser_iterate(char **inln, char *inlimit, struct string_block *inhead,$/ pc nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ pen_color xgraphics.h /^#define pen_color / pen_down xgraphics.h /^#define pen_down / pen_erase xgraphics.h /^#define pen_erase / pen_height xgraphics.h /^#define pen_height / pen_info xgraphics.h /^} pen_info;$/ pen_mode xgraphics.h /^#define pen_mode / pen_reverse xgraphics.h /^#define pen_reverse / pen_vis xgraphics.h /^#define pen_vis / pen_width xgraphics.h /^#define pen_width / pen_x xgraphics.h /^#define pen_x / pen_y xgraphics.h /^#define pen_y / pfmod graphics.c /^double pfmod(double x, double y) {$/ ph nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ ph xgraphics.h /^ int ph;$/ placate_x xgraphics.c /^void placate_x()$/ plain_xor_pen xgraphics.h /^#define plain_xor_pen(/ plist__caseobj logo.h /^#define plist__caseobj(/ plist__object logo.h /^#define plist__object(/ pm nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ pm xgraphics.h /^ GC pm;$/ po_helper wrksp.c /^NODE *po_helper(NODE *arg, int just_titles) {$/ pop logo.h /^#define pop(/ pos_int_arg coms.c /^NODE *pos_int_arg(NODE *args) {$/ pos_int_vector_arg graphics.c /^NODE *pos_int_vector_arg(NODE *args) {$/ prepare_to_draw xgraphics.h /^#define prepare_to_draw / prepare_to_draw_turtle xgraphics.h /^#define prepare_to_draw_turtle / prepare_to_exit coms.c /^void prepare_to_exit(BOOLEAN okay) {$/ prim init.c /^ NODE *(*prim) ();$/ priminfo init.c /^typedef struct priminfo {$/ prims init.c /^PRIMTYPE prims[] = {$/ print_char print.c /^void print_char(FILE *strm, char ch) {$/ print_help print.c /^void print_help(FILE *strm, NODE *nd) {$/ print_nobrak print.c /^void print_nobrak(FILE *strm, NODE *nd) {$/ print_node print.c /^void print_node(FILE *strm, NODE *nd) {$/ print_space print.c /^void print_space(FILE *strm) {$/ print_stringlen print.c /^int print_stringlen;$/ print_stringptr print.c /^char *print_stringptr;$/ priority init.c /^ short priority;$/ priority paren.c /^int priority(NODE *proc_obj) {$/ prname mem.c /^void prname(NODE *foo) {$/ proc logo.h /^#define proc / proc_name_arg wrksp.c /^NODE *proc_name_arg(NODE *args) {$/ procnode__caseobj logo.h /^#define procnode__caseobj(/ procnode__object logo.h /^#define procnode__object(/ ps_string graphics.c /^void ps_string(FILE *fp, char *p) {$/ push logo.h /^#define push(/ pv nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ pw nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ pw xgraphics.h /^ int pw;$/ px nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ py nographics.c /^int pw, ph, pc, pm, pv, px, py, bg;$/ qm_list logo.h /^#define qm_list / quote_strnzcpy logodata.c /^char *quote_strnzcpy(char *s1, char *s2, int n) {$/ r_argl logo.h /^ NODE *r_argl; \/* evaluated argument list *\/$/ r_current_unode logo.h /^ NODE *r_current_unode; \/* a pair to identify this proc call *\/$/ r_didnt_get_output logo.h /^ NODE *r_didnt_get_output; \/* procedure wanting output from EVAL *\/$/ r_didnt_output_name logo.h /^ NODE *r_didnt_output_name; \/* name of the proc that didn't OP *\/$/ r_formals logo.h /^ NODE *r_formals; \/* list of formal parameters *\/$/ r_fun logo.h /^ NODE *r_fun; \/* current function name *\/$/ r_ift_iff_flag logo.h /^ FIXNUM r_ift_iff_flag;$/ r_last_line logo.h /^ NODE *r_last_line; \/* the line that called this one *\/$/ r_last_ufun logo.h /^ NODE *r_last_ufun; \/* the function that called this one *\/$/ r_proc logo.h /^ NODE *r_proc; \/* the procedure definition *\/$/ r_qm_list logo.h /^ NODE *r_qm_list; \/* question mark list *\/$/ r_repcount logo.h /^ FIXNUM r_repcount; \/* count for repeat *\/$/ r_tailcall logo.h /^ FIXNUM r_tailcall; \/* 0 in sequence, 1 for tail, -1 for arg *\/$/ r_this_line logo.h /^ NODE *r_this_line; \/* the current instruction line *\/$/ r_ufun logo.h /^ NODE *r_ufun; \/* current user-defined function name *\/$/ r_unev logo.h /^ NODE *r_unev; \/* list of unevaluated expressions *\/$/ r_user_repcount logo.h /^ FIXNUM r_user_repcount;$/ r_val_status logo.h /^ FIXNUM r_val_status; \/* tells what EVAL_SEQUENCE should do: *\/$/ r_var logo.h /^ NODE *r_var; \/* frame pointer into var_stack *\/$/ r_vsp logo.h /^ NODE *r_vsp; \/* temp ptr into var_stack *\/$/ rd_getc parse.c /^int rd_getc(FILE *strm) {$/ rd_print_prompt parse.c /^void rd_print_prompt(char *str) {$/ rd_putc globals.h /^#define rd_putc / reader parse.c /^NODE *reader(FILE *strm, char *prompt) {$/ reader_name files.c /^NODE *reader_name = NIL, *writer_name = NIL, *file_prefix = NIL;$/ readstream parse.c /^FILE *readstream;$/ real_print_help print.c /^void real_print_help(FILE *strm, NODE *ndlist, int depth, int width) {$/ real_print_node print.c /^void real_print_node(FILE *strm, NODE *nd, int depth, int width) {$/ real_window_init xgraphics.c /^void real_window_init()$/ record graphics.c /^char record[GR_SIZE];$/ record_index graphics.c /^FIXNUM record_index = 0;$/ redraw_graphics graphics.c /^void redraw_graphics(void) {$/ refresh_p graphics.c /^BOOLEAN refresh_p = TRUE;$/ registers logo.h /^struct registers {$/ regs eval.c /^struct registers regs;$/ repcount logo.h /^#define repcount / reserve_tank mem.c /^NODE *reserve_tank = NIL;$/ reset_args eval.c /^void reset_args(NODE *old_stack) {$/ restline eval.c /^NODE *restname, *restline;$/ restname eval.c /^NODE *restname, *restline;$/ restore eval.c /^#define restore(/ restore2 eval.c /^#define restore2(/ restore_palette graphics.c /^void restore_palette(FILE *fp) {$/ restore_pen xgraphics.c /^void restore_pen(pen_info *p) {$/ reverse eval.c /^NODE *reverse(NODE *list) {$/ reverse_gc xgraphics.c /^ reverse_gc; \/* GC to reverse things. *\/$/ rgb_arg graphics.c /^NODE *rgb_arg(NODE *args) {$/ rgbprint graphics.c /^void rgbprint(FILE *fp, int cnum) {$/ right graphics.c /^void right(FLONUM a) {$/ runnable_arg coms.c /^NODE *runnable_arg(NODE *args) {$/ runparse parse.c /^NODE *runparse(NODE *ndlist) {$/ runparse_node parse.c /^NODE *runparse_node(NODE *nd, NODE **ndsptr) {$/ runparsed logo.h /^#define runparsed(/ runstartup files.c /^void runstartup(NODE *oldst) {$/ safe_to_save graphics.c /^BOOLEAN safe_to_save(void) {$/ save eval.c /^#define save(/ save2 eval.c /^#define save2(/ save_arc graphics.c /^void save_arc(FLONUM count, FLONUM ang, FLONUM radius, FLONUM delta,$/ save_argc xgraphics.c /^int save_argc;$/ save_argv xgraphics.c /^char ** save_argv;$/ save_color graphics.c /^void save_color(void) {$/ save_line graphics.c /^void save_line(void) {$/ save_lm_helper graphics.c /^void save_lm_helper (void) {$/ save_mode graphics.c /^void save_mode(void) {$/ save_move graphics.c /^void save_move(void) {$/ save_palette graphics.c /^void save_palette(FILE *fp) {$/ save_pattern graphics.c /^void save_pattern(void) {$/ save_pen xgraphics.c /^void save_pen(pen_info *p) {$/ save_size graphics.c /^void save_size(void) {$/ save_string graphics.c /^void save_string(char *s, int len) {$/ save_vis graphics.c /^void save_vis(void) {$/ screen xgraphics.c /^int screen;$/ screen_bottom xgraphics.h /^#define screen_bottom / screen_height xgraphics.c /^int screen_height = DEFAULT_HEIGHT;$/ screen_left xgraphics.h /^#define screen_left / screen_mode graphics.c /^enum {SCREEN_TEXT, SCREEN_SPLIT, SCREEN_FULL} screen_mode = SCREEN_TEXT;$/ screen_right xgraphics.h /^#define screen_right / screen_top xgraphics.h /^#define screen_top / screen_width xgraphics.c /^int screen_width = DEFAULT_WIDTH;$/ screen_x_center xgraphics.h /^#define screen_x_center / screen_x_coord xgraphics.h /^#define screen_x_coord / screen_y_center xgraphics.h /^#define screen_y_center / screen_y_coord xgraphics.h /^#define screen_y_coord / se_arr term.c /^char se_arr[40];$/ seg_size mem.c /^FIXNUM seg_size = SEG_SIZE;$/ segment logo.h /^struct segment {$/ segment_list mem.c /^struct segment *segment_list = NULL; \/* global ptr to segment list *\/$/ separator libloc.c /^char *separator="\/";$/ set_back_ground xgraphics.h /^#define set_back_ground(/ set_list_pen_pattern xgraphics.h /^#define set_list_pen_pattern(/ set_palette xgraphics.c /^void set_palette(int n, unsigned int r, unsigned int g, unsigned int b) {$/ set_pen_color xgraphics.h /^#define set_pen_color(/ set_pen_height xgraphics.h /^#define set_pen_height(/ set_pen_mode xgraphics.h /^#define set_pen_mode(/ set_pen_pattern xgraphics.h /^#define set_pen_pattern(/ set_pen_vis xgraphics.h /^#define set_pen_vis(/ set_pen_width xgraphics.h /^#define set_pen_width(/ set_pen_x xgraphics.h /^#define set_pen_x(/ set_pen_y xgraphics.h /^#define set_pen_y(/ setarrdim logo.h /^#define setarrdim(/ setarrorg logo.h /^#define setarrorg(/ setarrptr logo.h /^#define setarrptr(/ setbodywords__procnode logo.h /^#define setbodywords__procnode(/ setcar mem.c /^void setcar(NODE *nd, NODE *newcar) {$/ setcdr mem.c /^void setcdr(NODE *nd, NODE *newcdr) {$/ setflag__caseobj logo.h /^#define setflag__caseobj(/ setfloat logo.h /^#define setfloat(/ setgeneration__tree logo.h /^#define setgeneration__tree(/ setint logo.h /^#define setint(/ setitem_helper lists.c /^NODE *setitem_helper(NODE *args, BOOLEAN safe) {$/ setobject mem.c /^void setobject(NODE *nd, NODE *newobj) {$/ setparity logo.h /^#define setparity(/ setplist__caseobj logo.h /^#define setplist__caseobj(/ setplist__object logo.h /^#define setplist__object(/ setpos_bynumber graphics.c /^void setpos_bynumber(FLONUM target_x, FLONUM target_y) {$/ setpos_commonpart graphics.c /^void setpos_commonpart(FLONUM target_x, FLONUM target_y) {$/ setpos_helper graphics.c /^void setpos_helper(NODE *xnode, NODE *ynode) {$/ setprimdflt logo.h /^#define setprimdflt(/ setprimfun logo.h /^#define setprimfun(/ setprimmax logo.h /^#define setprimmax(/ setprimmin logo.h /^#define setprimmin(/ setprimpri logo.h /^#define setprimpri(/ setprocnode__caseobj logo.h /^#define setprocnode__caseobj(/ setprocnode__object logo.h /^#define setprocnode__object(/ setstrhead logo.h /^#define setstrhead(/ setstrlen logo.h /^#define setstrlen(/ setstrptr logo.h /^#define setstrptr(/ setstrrefcnt logo.h /^#define setstrrefcnt(/ settree__tree logo.h /^#define settree__tree(/ settreepair__tree logo.h /^#define settreepair__tree(/ settype logo.h /^#define settype(/ setvalnode__caseobj logo.h /^#define setvalnode__caseobj(/ setvalnode__object logo.h /^#define setvalnode__object(/ sig_arg main.c /^#define sig_arg / sig_arg math.c /^#define sig_arg / sig_arg xgraphics.c /^#define sig_arg / silent_load files.c /^void silent_load(NODE *arg, char *prefix) {$/ size logo.h /^ FIXNUM size;$/ so_arr term.c /^char so_arr[40];$/ special_chars logodata.c /^char special_chars[] = " \\t\\n(?????+++~)[]-*\/=<>\\"\\\\:;|{}";$/ split_screen xgraphics.h /^#define split_screen / sq graphics.c /^#define sq(/ stack eval.c /^ *stack = NIL, \/* register stack *\/$/ stopping_flag eval.c /^CTRLTYPE stopping_flag = RUN;$/ str_refcnt logo.h /^ unsigned FIXNUM str_refcnt;$/ str_str logo.h /^ char str_str[1]; \/* This array will be of variable length really *\/$/ string_arg lists.c /^NODE *string_arg(NODE *args) {$/ string_block logo.h /^struct string_block {$/ strnode__caseobj logo.h /^#define strnode__caseobj(/ strnzcpy logodata.c /^char *strnzcpy(char *s1, char *s2, int n) {$/ tailcall logo.h /^#define tailcall / tell_shadow eval.c /^void tell_shadow(NODE *arg) {$/ tempdir wrksp.c /^char *editor, *editorname, *tempdir;$/ temploc libloc.c /^char *temploc="\/tmp";$/ term_init term.c /^void term_init(void) {$/ termcap_getter term.c /^void termcap_getter(char *cap, char *buf) {$/ termcap_ptr term.c /^char *termcap_ptr;$/ termcap_putter term.c /^int termcap_putter(char ch) {$/ text__procnode logo.h /^#define text__procnode(/ text_screen xgraphics.h /^#define text_screen / theName logodata.c /^NODE *theName(enum words wd) {$/ the_generation paren.c /^NODE *the_generation;$/ this_line logo.h /^#define this_line / three_lists wrksp.c /^void three_lists(NODE *arg, NODE **proclst, NODE **varlst, NODE **plistlst) {$/ throw_node error.c /^NODE *throw_node = NIL;$/ tmp_filename wrksp.c /^char tmp_filename[500] = "";$/ to_helper wrksp.c /^NODE *to_helper(NODE *args, BOOLEAN macro_flag) {$/ to_pending wrksp.c /^int to_pending = 0;$/ tone xgraphics.h /^#define tone(/ torf math.c /^NODE *torf(BOOLEAN tf) {$/ torf_arg coms.c /^int torf_arg(NODE *args) {$/ total_turtle_bottom_max graphics.c /^#define total_turtle_bottom_max / towards_helper graphics.c /^FLONUM towards_helper(FLONUM x, FLONUM y, FLONUM from_x, FLONUM from_y) {$/ trace_level eval.c /^static int trace_level = 0; \/* indentation level when tracing *\/$/ translations init.c /^struct wdtrans translations[NUM_WORDS];$/ tree__line logo.h /^#define tree__line(/ tree__tree logo.h /^#define tree__tree(/ tree_dk_how paren.c /^BOOLEAN tree_dk_how;$/ treepair__tree logo.h /^#define treepair__tree(/ tty_cbreak term.c /^struct sgttyb tty_cooked, tty_cbreak;$/ tty_cbreak term.c /^struct termio tty_cooked, tty_cbreak;$/ tty_charmode term.c /^int interactive, tty_charmode;$/ tty_cooked term.c /^struct sgttyb tty_cooked, tty_cbreak;$/ tty_cooked term.c /^struct termio tty_cooked, tty_cbreak;$/ turtle_bottom_max xgraphics.h /^#define turtle_bottom_max / turtle_half_bottom xgraphics.h /^#define turtle_half_bottom / turtle_heading graphics.c /^FLONUM turtle_x = 0.0, turtle_y = 0.0, turtle_heading = 0.0;$/ turtle_height xgraphics.h /^#define turtle_height / turtle_left_max xgraphics.h /^#define turtle_left_max / turtle_right_max xgraphics.h /^#define turtle_right_max / turtle_shown graphics.c /^BOOLEAN turtle_shown = TRUE;$/ turtle_side xgraphics.h /^#define turtle_side / turtle_top_max xgraphics.h /^#define turtle_top_max / turtle_x graphics.c /^FLONUM turtle_x = 0.0, turtle_y = 0.0, turtle_heading = 0.0;$/ turtle_y graphics.c /^FLONUM turtle_x = 0.0, turtle_y = 0.0, turtle_heading = 0.0;$/ type_help print.c /^void type_help(NODE *args, int sp) {$/ ufun logo.h /^#define ufun / unblock_input main.c /^void unblock_input(void) {$/ unbury_helper wrksp.c /^NODE *unbury_helper(NODE *arg, int flag) {$/ uncapital logodata.c /^#define uncapital(/ unev logo.h /^#define unev / unix logo.h /^#define unix$/ unparsed__line logo.h /^#define unparsed__line(/ unparsed__runparse logo.h /^#define unparsed__runparse(/ unparsed__tree logo.h /^#define unparsed__tree(/ untreeify paren.c /^void untreeify(NODE *node) {$/ untreeify_body paren.c /^void untreeify_body(NODE *body) {$/ untreeify_line paren.c /^void untreeify_line(NODE *line) {$/ untreeify_proc paren.c /^void untreeify_proc(NODE *tproc) {$/ up_gc xgraphics.c /^ up_gc, \/* Do nothing gc. *\/$/ update_coords print.c /^void update_coords(char ch) {$/ upper_p logodata.c /^#define upper_p(/ use_reserve_tank mem.c /^void use_reserve_tank(void) {$/ user_repcount logo.h /^#define user_repcount / val eval.c /^ *val = NIL, \/* the value of the last expression *\/$/ val__cont logo.h /^#define val__cont(/ val_status logo.h /^#define val_status / valid_pointer mem.c /^BOOLEAN valid_pointer (volatile NODE *ptr_val) {$/ valnode__caseobj logo.h /^#define valnode__caseobj(/ valnode__colon logo.h /^#define valnode__colon(/ valnode__object logo.h /^#define valnode__object(/ var logo.h /^#define var / varTrue logodata.c /^int varTrue(NODE *varb) {$/ var_stack eval.c /^*var_stack = NIL, \/* the stack of variables and their bindings *\/$/ vec_arg_helper graphics.c /^NODE *vec_arg_helper(NODE *args, BOOLEAN floatok, BOOLEAN three) {$/ vector_arg graphics.c /^NODE *vector_arg(NODE *args) {$/ vis xgraphics.h /^ int vis;$/ vs_print eval.c /^void vs_print() {$/ vsp logo.h /^#define vsp / wanna_x graphics.c /^FLONUM wanna_x = 0.0, wanna_y = 0.0;$/ wanna_y graphics.c /^FLONUM wanna_x = 0.0, wanna_y = 0.0;$/ want_buried wrksp.c /^int want_buried = 0;$/ wd_copy init.c /^#define wd_copy(/ wd_enum logo.h /^#define wd_enum(/ wdtrans logo.h /^struct wdtrans {$/ white_space parse.c /^#define white_space(/ win xgraphics.c /^Window win; \/* Window ID *\/$/ windowmode logo.h /^typedef enum {wrapmode, fencemode, windowmode} mode_type;$/ word_strnzcpy logodata.c /^char *word_strnzcpy(char *s1, NODE *kludge, int n) { \/* KLUDGE! *\/$/ words logo.h /^enum words {$/ wrap_down graphics.c /^FLONUM wrap_down(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) {$/ wrap_left graphics.c /^FLONUM wrap_left(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) {$/ wrap_right graphics.c /^FLONUM wrap_right(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) {$/ wrap_up graphics.c /^FLONUM wrap_up(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2) {$/ wrapmode logo.h /^typedef enum {wrapmode, fencemode, windowmode} mode_type;$/ write_buf files.c /^char *write_buf = 0;$/ writer_name files.c /^NODE *reader_name = NIL, *writer_name = NIL, *file_prefix = NIL;$/ writestream parse.c /^FILE *writestream;$/ x_coord term.c /^int x_coord, y_coord, x_max, y_max;$/ x_margin print.c /^int x_margin=0, y_margin=0;$/ x_max term.c /^int x_coord, y_coord, x_max, y_max;$/ x_mouse_x xgraphics.c /^int x_mouse_x, x_mouse_y;$/ x_mouse_y xgraphics.c /^int x_mouse_x, x_mouse_y;$/ x_scale graphics.c /^FLONUM x_scale = 1.0, y_scale = 1.0;$/ x_win_resize xgraphics.c /^RETSIGTYPE x_win_resize()$/ x_window logo.h /^#define x_window$/ x_window_init xgraphics.c /^void x_window_init(int argc, char **argv)$/ xgr_pen xgraphics.c /^pen_info xgr_pen;$/ xpos xgraphics.h /^ int xpos;$/ xwmh xgraphics.c /^XWMHints xwmh = {$/ y_coord term.c /^int x_coord, y_coord, x_max, y_max;$/ y_margin print.c /^int x_margin=0, y_margin=0;$/ y_max term.c /^int x_coord, y_coord, x_max, y_max;$/ y_scale graphics.c /^FLONUM x_scale = 1.0, y_scale = 1.0;$/ ypos xgraphics.h /^ int ypos;$/ zrd_print_prompt parse.c /^#define zrd_print_prompt / zrd_print_prompt parse.c /^void zrd_print_prompt(char *str) {$/ ucblogo-5.5/win32trm.h0100644000161300001330000001174710217721470012601 0ustar bhdoe/* -*-C-*- * Win32trm.h * * Function prototypes &c for Win32 API (Win95, WinNT) compliant * procedures. * * $Id$ * * $Log$ * * (c) 1996 UC Regents, etc. * */ #include #include "logo.h" #ifndef _WIN32TRM_H /* set to 1000 for debugging, should normally be ~10k */ #define GR_SIZE 60000 #define prepare_to_draw win32_prepare_draw() #define done_drawing #define prepare_to_draw_turtle win32_turtle_prep() #define done_drawing_turtle win32_turtle_end() #define screen_left 0 #define screen_right win32_screen_right() #define screen_top 0 #define screen_bottom win32_screen_bottom() #define max_screen_bottom win32_screen_bottom() #define screen_height (1 + screen_bottom - screen_top) #define screen_width (1 + screen_right - screen_left) #define screen_x_center (screen_left + (screen_width)/2) #define screen_y_center (screen_top + (screen_height)/2) #define turtle_left_max ((screen_left) - (screen_x_center)) #define turtle_right_max ((screen_right) - (screen_x_center)) #define turtle_top_max ((screen_y_center) - (screen_top)) #define turtle_bottom_max ((screen_y_center) - (screen_bottom)) #define screen_x_coord ((screen_x_center) + turtle_x) #define screen_y_coord ((screen_y_center) - turtle_y) #define turtle_height (FIXNUM) 18 #define turtle_half_bottom (FLONUM) 6.0 #define turtle_side (FLONUM) 19.0 #define clear_screen win32_erase_screen() #define line_to(x,y) {\ if (pen_vis==0) \ lineto((int)x,(int)y); \ else \ moveto((int)x,(int)y);\ } #define move_to(x,y) moveto((int)x,(int)y) /* #define draw_string(s) outtext((char *)s) function */ #define set_pen_vis(v) { turtlePen.vis = v; } /* functionified */ #define set_pen_mode(m) win32_set_pen_mode(m) /* functionified */ #define set_pen_color(c) win32_set_pen_color(c) #define set_back_ground(c) win32_set_bg(c) /* Now functions instead of macros */ #define set_pen_width(w) win32_set_pen_width(w) #define set_pen_height(h) win32_set_pen_width(h) #define set_pen_x(x) moveto((int)x, pen_y) #define set_pen_y(y) moveto(pen_x, (int)y) #define erase_screen() win32_erase_screen() /* pen_info is a stucture type with fields for the various pen characteristics including the location, size, color, mode (e.g. XOR or COPY), pattern, visibility (0 = visible) */ typedef struct { int h; int v; int vis; int width; int color; char pattern[8]; int mode; #ifdef WIN32 HPEN hpen; #endif } pen_info; #define p_info_x(p) p.h #define p_info_y(p) p.v #define pen_width (int) turtlePen.width #define pen_height (int) turtlePen.width #define pen_mode turtlePen.mode #define pen_vis turtlePen.vis #define pen_x turtlePen.h #define pen_y turtlePen.v #define get_node_pen_pattern win32_get_node_pen_pattern() #define pen_reverse win32_pen_reverse() #define pen_erase win32_pen_erase() #define pen_down win32_pen_down() #define button (w_button) #define full_screen win32_con_full_screen() #define split_screen win32_con_split_screen() #define text_screen win32_con_text_screen() /* definitions from term.c and math.c for ibmterm.c */ extern int x_coord, y_coord, x_max, y_max, tty_charmode; extern char so_arr[], se_arr[]; extern FLONUM degrad; /* Forward declarations for graphics.c */ extern void gr_mode(), draw_turtle(); extern void win32_pen_erase(), win32_pen_down(), win32_pen_xor(); extern void win32_set_pen_mode(int), win32_set_pen_color(), win32_set_bg(); extern int get_win32_pen_mode(), win32_set_pen_width(int); extern void save_pen(pen_info*), restore_pen(pen_info*), set_pen_pattern(); extern void plain_xor_pen(); extern void set_list_pen_pattern(), get_pen_pattern(), erase_screen(); extern void label(), logofill(); extern void t_screen(), s_screen(), f_screen(), tone(); extern FIXNUM mickey_x(), mickey_y(); extern NODE *win32_get_node_pen_pattern(); extern FIXNUM t_height(); extern FIXNUM pen_color, back_ground; extern FLONUM t_half_bottom(), t_side(); extern BOOLEAN in_erase_mode; extern void win32_init_palette(), win32_pen_reverse(); extern void win32_turtle_prep(), win32_turtle_end(); extern void win32_con_text_screen(), win32_con_split_screen(); extern void win32_prepare_draw(void); extern void win32_con_full_screen(), win32_clear_text(); extern NODE* win32_lsetcursor(NODE *); extern int win32_screen_right(); extern pen_info turtlePen; extern void MoveCursor(int, int), win32_receive_char(char); extern void win32_parse_line(char*); extern FIXNUM mouse_x, mouse_y; extern int w_button; /* prototypes added by sowings */ extern BOOLEAN safe_to_save(); extern void save_lm_helper(), save_line(), save_move(); extern void save_mode(), save_color(), save_pattern(); extern void save_size(), save_vis(); extern void set_palette(int, unsigned int, unsigned int, unsigned int); extern void get_palette(int, unsigned int*, unsigned int*, unsigned int*); #define nop() {} #define WIN_PEN_ERASE 1 #define WIN_PEN_DOWN 2 #define WIN_PEN_REVERSE 3 #define NUM_LINES 100 #define CHARS_PER_LINE 200 LRESULT CALLBACK MainFunc(HWND, UINT, WPARAM, LPARAM); #define _WIN32TRM_H #endif /* !_WIN32TRM_H */ ucblogo-5.5/libloc.c.mac0100644000161300001330000000016310150241357013075 0ustar bhdoechar *libloc=":logolib"; char *helploc=":helpfiles"; char *cslsloc=":csls"; char *temploc=""; char *separator=":"; ucblogo-5.5/logolib/0040755000161300001330000000000010271251116012356 5ustar bhdoeucblogo-5.5/logolib/#0100644000161300001330000000014410275746620012434 0ustar bhdoe;;; -*- logo -*- to # if not namep "template.number [op repcount] op :template.number end bury "# ucblogo-5.5/logolib/`0100644000161300001330000000525010275746620012534 0ustar bhdoe;;; -*- logo -*- to ` :backq.list [:backq.depth 0] if emptyp :backq.list [op []] if equalp first :backq.list "` ~ [op fput "` fput (` first bf :backq.list :backq.depth+1) (` bf bf :backq.list :backq.depth)] if equalp first first :backq.list ", ~ [op backq.unquote (bf first :backq.list) (bf :backq.list) :backq.depth] if memberp first first :backq.list [" :] ~ [op backq.word (first first :backq.list) (bf first :backq.list) (bf :backq.list) :backq.depth] if wordp first :backq.list ~ [op fput first :backq.list (` bf :backq.list :backq.depth)] op fput (` first :backq.list :backq.depth) (` bf :backq.list :backq.depth) end to backq.word :backq.symbol :backq.word :backq.rest :backq.depth if emptyp :backq.word ~ [output fput :backq.symbol (` :backq.rest :backq.depth)] if not equalp first :backq.word ", ~ [output fput (word :backq.symbol :backq.word) (` :backq.rest :backq.depth)] localmake "result backq.unquote (bf :backq.word) :backq.rest :backq.depth if wordp :result [output word :backq.symbol :result] output fput (word :backq.symbol first :result) bf :result end to backq.unquote :unquote.symbol :unquote.rest :unquote.depth localmake "unquote.splicing "false if not emptyp :unquote.symbol [ if equalp first :unquote.symbol "@ [ make "unquote.splicing "true make "unquote.symbol butfirst :unquote.symbol ]] if :unquote.depth=0 [ if emptyp :unquote.symbol [output backq.combine run first :unquote.rest (` bf :unquote.rest :unquote.depth)] output backq.combine run :unquote.symbol (` :unquote.rest :unquote.depth) ] if emptyp :unquote.symbol ~ [output fput (ifelse :unquote.splicing [",@] [",]) fput (` first :unquote.rest :unquote.depth-1) (` bf :unquote.rest :unquote.depth)] if backq.all.commas :unquote.symbol ~ [output fput (ifelse :unquote.splicing [",@] [",]) fput (` (list :unquote.symbol first :unquote.rest) :unquote.depth-1) (` bf :unquote.rest :unquote.depth)] output fput (ifelse :unquote.splicing [",@] [",]) ~ fput (` (list :unquote.symbol) :unquote.depth-1) ~ (` :unquote.rest :unquote.depth) end to backq.combine :this :those output ifelse :unquote.splicing [se :this :those] [fput :this :those] end to backq.all.commas :word if emptyp :word [output "true] if equalp first :word ", ~ [if emptyp butfirst :word [output "true] if equalp first butfirst :word "@ [output backq.all.commas bf bf :word] output backq.all.commas butfirst :word] output "false end bury [` backq.word backq.unquote backq.combine backq.all.commas] ucblogo-5.5/logolib/Messages0100644000161300001330000000524310275746620014066 0ustar bhdoe; UCBLogo message file version 5.5 ; Error messages -- position in this file corresponds to error number ; Lines starting with semicolon don't count in the line numbering ; and may be added at will. Logo: Fatal Internal Error. out of space stack overflow turtle out of bounds %p doesn't like %s as input %p didn't output to %p not enough inputs to %p %p doesn't like %s as input too many inputs to %p You don't say what to do with %s too many ('s %s has no value unexpected ')' I don't know how to %p Can't find catch tag for %p %p is already defined Stopping... Already dribbling File system error: %p Assuming you mean IFELSE, not IF %p shadowed by local in procedure call Throw "Error %p is a primitive Can't use TO inside a procedure I don't know how to %p %p without TEST unexpected ']' unexpected '}' couldn't initialize graphics Macro returned %s instead of a list You don't say what to do with %s Can only use %p inside a procedure APPLY doesn't like %s as input END inside multi-line instruction in %p Logo: Out of Memory. %p END inside multi-line instruction Bad default expression for optional input: %s Can't use OUTPUT or STOP inside RUNRESULT Assuming you meant '%p', not %p I can't open file %p File %p already open File %p not open ; Variable name %s is defined both dynamically and in current object ; Non-error messages (no numeric error code for these) Thank you for using Logo. Have a nice day. Sorry, no shell on the Mac. Type EXIT to return to Logo. in %s\n%s Erract loop Pausing... stops outputs File not found: %t\n Can't KEYP, no FIONREAD on this system Not enough memory I can't open that file File already open File not open Pprop Welcome to Berkeley Logo version %t You must be in a procedure to use OUTPUT or STOP. Warning: Not enough memory to run garbage collector. GC disabled - Save important data and exit! %s defined\n Make %s %s to %p\nend\n\n Plist %s = %s\n No help available.\n No help available on %p.\n --more-- ; Logo special words, used mostly in Logo-generated messages ; TRUE and FALSE are generated by predicates and accepted by IF etc. true false ; End of a procedure end ; Some names of primitives treated specially in the evaluator ; (You still have to COPYDEF them to match any changes here.) output stop goto tag if ifelse to .macro ; Special CATCH tags toplevel system error ; How no-value prints in error messages nothing ; Outputs from SCREENMODE textscreen splitscreen fullscreen ; Outputs from PENMODE paint erase reverse ; Outputs from TURTLEMODE wrap fence window ; HELP turns infix operators +-*/=<> into these sum difference product quotient equalp lessp greaterp lessequalp greaterequalp notequalp ; Object stuff name class self licenseplate initlist exist ucblogo-5.5/logolib/buryall0100644000161300001330000000007610275746620013770 0ustar bhdoe;;; -*- logo -*- to buryall bury contents end bury "buryall ucblogo-5.5/logolib/buryname0100644000161300001330000000011610275746620014133 0ustar bhdoe;;; -*- logo -*- to buryname :names bury namelist :names end bury "buryname ucblogo-5.5/logolib/cascade0100644000161300001330000000221410275746620013675 0ustar bhdoe;;; -*- logo -*- to cascade :cascade.limit [:cascade.inputs] 3 if numberp :cascade.limit ~ [if lessp :cascade.limit 0 ~ [(throw "error (se [cascade doesn't like] :cascade.limit [as input]))] ~ make "cascade.limit `[greaterp :template.number ,[int :cascade.limit]]] local [cascade.templates template.vars cascade.final] make "cascade.templates [] make "template.vars [] make "cascade.final [?1] cascade.setup :cascade.inputs op cascade1 1 :template.vars end to cascade.setup :inputs if emptyp :inputs [stop] if emptyp bf :inputs [make "cascade.final first :inputs stop] make "cascade.templates lput first :inputs :cascade.templates make "template.vars lput first bf :inputs :template.vars cascade.setup bf bf :inputs end to cascade1 :template.number :template.vars if apply :cascade.limit :template.vars [op apply :cascade.final :template.vars] op cascade1 (:template.number+1) (cascade.eval :cascade.templates) end to cascade.eval :cascade.templates if emptyp :cascade.templates [op []] op fput (apply first :cascade.templates :template.vars) ~ (cascade.eval bf :cascade.templates) end bury [cascade cascade.setup cascade1 cascade.eval] ucblogo-5.5/logolib/cascade.20100644000161300001330000000015410275746620014036 0ustar bhdoe;;; -*- logo -*- to cascade.2 [:cascade2.inputs] 5 op apply "cascade :cascade2.inputs end bury "cascade.2 ucblogo-5.5/logolib/closeall0100644000161300001330000000011410275746620014105 0ustar bhdoe;;; -*- logo -*- to closeall foreach allopen [close ?] end bury "closeall ucblogo-5.5/logolib/combine0100644000161300001330000000020110275746620013720 0ustar bhdoe;;; -*- logo -*- to combine :this :those if wordp :those [output word :this :those] output fput :this :those end bury "combine ucblogo-5.5/logolib/crossmap0100644000161300001330000000077510275746620014153 0ustar bhdoe;;; -*- logo -*- to crossmap :cm.template [:cm.lists] 2 if emptyp bf :cm.lists [op cm1 first :cm.lists 1 []] op cm1 :cm.lists 1 [] end to cm1 :cm.lists :cm.level :template.vars if emptyp :cm.lists [op (list apply :cm.template :template.vars)] op cm2 first :cm.lists end to cm2 :cm.thislist if emptyp :cm.thislist [op []] local :cm.level make :cm.level first :cm.thislist op se (cm1 bf :cm.lists :cm.level+1 lput first :cm.thislist :template.vars) ~ (cm2 bf :cm.thislist) end bury [crossmap cm1 cm2] ucblogo-5.5/logolib/dequeue0100644000161300001330000000027210275746620013751 0ustar bhdoe;;; -*- logo -*- to dequeue :the.queue.name local "result make "result first thing :the.queue.name make :the.queue.name butfirst thing :the.queue.name output :result end bury "dequeue ucblogo-5.5/logolib/do.until0100644000161300001330000000021110275746620014041 0ustar bhdoe;;; -*- logo -*- .macro do.until :until.instr :until.cond op se :until.instr (list "until :until.cond :until.instr) end bury "do.until ucblogo-5.5/logolib/do.while0100644000161300001330000000021110275746620014016 0ustar bhdoe;;; -*- logo -*- .macro do.while :while.instr :while.cond op se :while.instr (list "while :while.cond :while.instr) end bury "do.while ucblogo-5.5/logolib/edall0100644000161300001330000000007210275746620013373 0ustar bhdoe;;; -*- logo -*- to edall edit contents end bury "edall ucblogo-5.5/logolib/edn0100644000161300001330000000010410275746620013054 0ustar bhdoe;;; -*- logo -*- to edn :names edit namelist :names end bury "edn ucblogo-5.5/logolib/edns0100644000161300001330000000006510275746620013245 0ustar bhdoe;;; -*- logo -*- to edns edit names end bury "edns ucblogo-5.5/logolib/edpl0100644000161300001330000000010410275746620013232 0ustar bhdoe;;; -*- logo -*- to edpl :names edit pllist :names end bury "edpl ucblogo-5.5/logolib/edpls0100644000161300001330000000007010275746620013417 0ustar bhdoe;;; -*- logo -*- to edpls edit plists end bury "edpls ucblogo-5.5/logolib/edps0100644000161300001330000000007210275746620013245 0ustar bhdoe;;; -*- logo -*- to edps edit procedures end bury "edps ucblogo-5.5/logolib/ern0100644000161300001330000000010510275746620013073 0ustar bhdoe;;; -*- logo -*- to ern :names erase namelist :names end bury "ern ucblogo-5.5/logolib/erpl0100644000161300001330000000010510275746620013251 0ustar bhdoe;;; -*- logo -*- to erpl :names erase pllist :names end bury "erpl ucblogo-5.5/logolib/emacs.debug0100644000161300001330000000162610275746620014475 0ustar bhdoe;;; -*- logo -*- to emacs.debug :file_elisp_code :trace_or_step localmake "wr_elisp_code writer if namep "printwidthlimit [ localmake "pw_elisp_code :printwidthlimit ern "printwidthlimit] openwrite :file_elisp_code setwrite :file_elisp_code bury [[] [wr_elisp_code pw_elisp_code file_elisp_code trace_or_step] []] (foreach contents run (list :trace_or_step) [PROCEDURES: VARIABLES: PROPERTIES:] [[names debugged title] [pr :title pr [] pr map [[name] [op ifelse memberp :name :debugged [(word "\( :name "\))] [:name]]] :names pr []]]) close :file_elisp_code setwrite :wr_elisp_code if namep "pw_elisp_code [make "printwidthlimit :pw_elisp_code] end bury "emacs.debug ucblogo-5.5/logolib/filter0100644000161300001330000000077310275746620013607 0ustar bhdoe;;; -*- logo -*- to filter :filter.template :template.list [:template.number 1] ~ [:template.lists (list :template.list)] if emptyp :template.list [op :template.list] if apply :filter.template (list first :template.list) ~ [op combine (first :template.list) ~ (filter :filter.template bf :template.list :template.number+1)] op (filter :filter.template bf :template.list :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [filter ?rest] ucblogo-5.5/logolib/find0100644000161300001330000000060210275746620013231 0ustar bhdoe;;; -*- logo -*- to find :find.template :template.list [:template.number 1] ~ [:template.lists (list :template.list)] if emptyp :template.list [op []] if apply :find.template (list first :template.list) [op first :template.list] op (find :find.template bf :template.list :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [find ?rest] ucblogo-5.5/logolib/for0100644000161300001330000000155310275746620013105 0ustar bhdoe;;; -*- logo -*- .macro for :for.values :for.instr ~ [:for.var first :for.values] ~ [:for.initial run first bf :for.values] ~ [:for.final run first bf bf :for.values] ~ [:for.step forstep] ~ [:for.tester (ifelse :for.step < 0 ~ [[:for.initial < :for.final]] ~ [[:for.initial > :for.final]])] local :for.var catch "for.catchtag [op for.done runresult [forloop :for.initial]] op [] end to forloop :for.initial make :for.var :for.initial if run :for.tester [throw "for.catchtag] run :for.instr .maybeoutput forloop (:for.initial + :for.step) end to for.done :for.result if emptyp :for.result [op [stop]] op (list "output "first (list first :for.result)) end to forstep if equalp count :for.values 4 [op run last :for.values] op ifelse :for.initial > :for.final [-1] [1] end bury [for forstep forloop for.done] ucblogo-5.5/logolib/foreach0100644000161300001330000000131010275746620013715 0ustar bhdoe;;; -*- logo -*- .macro foreach [:foreach.inputs] 2 catch "foreach.catchtag ~ [op foreach.done runresult ~ [foreach1 butlast :foreach.inputs last :foreach.inputs 1]] op [] end to foreach1 :template.lists :foreach.template :template.number if emptyp first :template.lists [throw "foreach.catchtag] apply :foreach.template firsts :template.lists .maybeoutput foreach1 butfirsts :template.lists ~ :foreach.template :template.number+1 end to foreach.done :foreach.result if emptyp :foreach.result [op [stop]] op (list "output "first (list first :foreach.result)) end to ?rest [:which 1] output butfirst item :which :template.lists end bury [foreach foreach1 foreach.done ?rest] ucblogo-5.5/logolib/gensym0100644000161300001330000000027210275746620013616 0ustar bhdoe;;; -*- logo -*- to gensym if not namep "gensym.number [make "gensym.number 0] make "gensym.number :gensym.number + 1 output word "g :gensym.number end bury [[gensym] [gensym.number]] ucblogo-5.5/logolib/ignore0100644000161300001330000000006510275746620013577 0ustar bhdoe;;; -*- logo -*- to ignore :stuff end bury "ignore ucblogo-5.5/logolib/invoke0100644000161300001330000000020710275746620013605 0ustar bhdoe;;; -*- logo -*- to invoke :invoked.function [:invoke.inputs] 2 .maybeoutput apply :invoked.function :invoke.inputs end bury "invoke ucblogo-5.5/logolib/macroexpand0100644000161300001330000000054610275746620014621 0ustar bhdoe;;; -*- logo -*- to macroexpand :expr local [name inputlist macro.result] make "name first :expr make "inputlist bf :expr if not macrop :name [(throw "error (se :name [is not a macro.]))] define "%%%$%macro.procedure text :name make "macro.result run fput "%%%$%macro.procedure :inputlist erase "%%%$%macro.procedure op :macro.result end bury "macroexpand ucblogo-5.5/logolib/map0100644000161300001330000000062710275746620013075 0ustar bhdoe;;; -*- logo -*- to map :map.template [:template.lists] 2 op map1 :template.lists 1 end to map1 :template.lists :template.number if emptyp first :template.lists [output first :template.lists] output combine (apply :map.template firsts :template.lists) ~ (map1 bfs :template.lists :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [map map1 ?rest] ucblogo-5.5/logolib/map.se0100644000161300001330000000063610275746620013503 0ustar bhdoe;;; -*- logo -*- to map.se :map.se.template [:template.lists] 2 op map.se1 :template.lists 1 end to map.se1 :template.lists :template.number if emptyp first :template.lists [output []] output sentence (apply :map.se.template firsts :template.lists) ~ (map.se1 bfs :template.lists :template.number+1) end to ?rest [:which 1] output bf item :which :template.lists end bury [map.se map.se1 ?rest] ucblogo-5.5/logolib/mdarray0100644000161300001330000000041710275746620013754 0ustar bhdoe;;; -*- logo -*- to mdarray :sizes [:origin 1] local "array make "array (array first :sizes :origin) if not emptyp bf :sizes ~ [for [i :origin [:origin + (first :sizes) - 1]] ~ [setitem :i :array (mdarray bf :sizes :origin)]] output :array end bury "mdarray ucblogo-5.5/logolib/mditem0100644000161300001330000000020610275746620013570 0ustar bhdoe;;; -*- logo -*- to mditem :index :array if emptyp :index [op :array] op mditem bf :index item first :index :array end bury "mditem ucblogo-5.5/logolib/mdsetitem0100644000161300001330000000017710275746620014313 0ustar bhdoe;;; -*- logo -*- to mdsetitem :index :array :val setitem last :index (mditem butlast :index :array) :val end bury "mdsetitem ucblogo-5.5/logolib/name0100644000161300001330000000017510275746620013236 0ustar bhdoe;;; -*- logo -*- to name :name.value.input :name.variable.input make :name.variable.input :name.value.input end bury "name ucblogo-5.5/logolib/namelist0100644000161300001330000000017610275746620014133 0ustar bhdoe;;; -*- logo -*- to namelist :names if wordp :names [output list [] (list :names)] output list [] :names end bury "namelist ucblogo-5.5/logolib/pen0100644000161300001330000000021010275746620013066 0ustar bhdoe;;; -*- logo -*- to pen op (list (ifelse pendownp ["pendown] ["penup]) ~ penmode pensize pencolor penpattern) end bury [pen] ucblogo-5.5/logolib/pick0100644000161300001330000000013110275746620013234 0ustar bhdoe;;; -*- logo -*- to pick :list output item (1+random count :list) :list end bury "pick ucblogo-5.5/logolib/pllist0100644000161300001330000000020410275746620013616 0ustar bhdoe;;; -*- logo -*- to pllist :names if wordp :names [output (list [] [] (list :names))] output (list [] [] :names) end bury "pllist ucblogo-5.5/logolib/poall0100644000161300001330000000007010275746620013417 0ustar bhdoe;;; -*- logo -*- to poall po contents end bury "poall ucblogo-5.5/logolib/pon0100644000161300001330000000025310275746620013107 0ustar bhdoe;;; -*- logo -*- to pon :names ignore error catch "error [po namelist :names] local "err make "err error if not emptyp :err [(throw "error first bf :err)] end bury "pon ucblogo-5.5/logolib/pons0100644000161300001330000000006310275746620013271 0ustar bhdoe;;; -*- logo -*- to pons po names end bury "pons ucblogo-5.5/logolib/pop0100644000161300001330000000026210275746620013111 0ustar bhdoe;;; -*- logo -*- to pop :the.stack.name local "result make "result first thing :the.stack.name make :the.stack.name butfirst thing :the.stack.name output :result end bury "pop ucblogo-5.5/logolib/popl0100644000161300001330000000025310275746620013265 0ustar bhdoe;;; -*- logo -*- to popl :names ignore error catch "error [po pllist :names] local "err make "err error if not emptyp :err [(throw "error first bf :err)] end bury "popl ucblogo-5.5/logolib/popls0100644000161300001330000000006610275746620013452 0ustar bhdoe;;; -*- logo -*- to popls po plists end bury "popls ucblogo-5.5/logolib/pops0100644000161300001330000000007010275746620013271 0ustar bhdoe;;; -*- logo -*- to pops po procedures end bury "pops ucblogo-5.5/logolib/pots0100644000161300001330000000007110275746620013276 0ustar bhdoe;;; -*- logo -*- to pots pot procedures end bury "pots ucblogo-5.5/logolib/push0100644000161300001330000000021210275746620013265 0ustar bhdoe;;; -*- logo -*- to push :the.stack.name :the.item.value make :the.stack.name fput :the.item.value thing :the.stack.name end bury "push ucblogo-5.5/logolib/queue0100644000161300001330000000021410275746620013434 0ustar bhdoe;;; -*- logo -*- to queue :the.queue.name :the.item.value make :the.queue.name lput :the.item.value thing :the.queue.name end bury "queue ucblogo-5.5/logolib/quoted0100644000161300001330000000014310275746620013612 0ustar bhdoe;;; -*- logo -*- to quoted :stuff if wordp :stuff [op word "" :stuff] op :stuff end bury "quoted ucblogo-5.5/logolib/reduce0100644000161300001330000000040010275746620013554 0ustar bhdoe;;; -*- logo -*- to reduce :reduce.function :reduce.list if emptyp bf :reduce.list [op first :reduce.list] op apply :reduce.function (list (first :reduce.list) ~ (reduce :reduce.function bf :reduce.list)) end bury "reduce ucblogo-5.5/logolib/remdup0100644000161300001330000000013610275746620013607 0ustar bhdoe;;; -*- logo -*- to remdup :list output filter [not memberp ? ?rest] :list end bury "remdup ucblogo-5.5/logolib/remove0100644000161300001330000000014510275746620013610 0ustar bhdoe;;; -*- logo -*- to remove :thing :list output filter [not equalp ? :thing] :list end bury "remove ucblogo-5.5/logolib/reverse0100644000161300001330000000024010275746620013762 0ustar bhdoe;;; -*- logo -*- to reverse :in [:out ifelse listp :in [[]] ["]] if emptyp :in [output :out] output (reverse bf :in combine first :in :out) end bury "reverse ucblogo-5.5/logolib/savel0100644000161300001330000000021410275746620013422 0ustar bhdoe;;; -*- logo -*- to savel :cont :file [:oldwr writer] openwrite :file setwrite :file po :cont setwrite :oldwr close :file end bury "savel ucblogo-5.5/logolib/setpen0100644000161300001330000000061310275746620013611 0ustar bhdoe;;; -*- logo -*- to setpen :pen_data ifelse equalp first bf :pen_data "reverse ~ [penreverse] ~ [ifelse equalp first bf :pen_data "erase ~ [penerase] ~ [penpaint]] ifelse equalp first :pen_data "penup [penup] [pendown] setpensize first bf bf :pen_data setpencolor first bf bf bf :pen_data setpenpattern first bf bf bf bf :pen_data end bury [setpen] ucblogo-5.5/logolib/transfer0100644000161300001330000000101510275746620014134 0ustar bhdoe;;; -*- logo -*- to transfer :transfer.limit :transfer.template :transfer.init output cascade.2 (ifelse emptyp :transfer.limit ~ [[emptyp ?2]] ~ [list "transfer.end.test :transfer.limit]) ~ :transfer.template [] [butfirst ?2] :transfer.init end to transfer.end.test :the.condition.expression if emptyp ?2 [output "true] output run :the.condition.expression end to ?in output first ?2 end to ?out output ?1 end bury [transfer transfer.end.test ?in ?out] ucblogo-5.5/logolib/unburyall0100644000161300001330000000006110275746620014325 0ustar bhdoe;;; -*- logo -*- to unburyall unbury buried end ucblogo-5.5/logolib/unburyname0100644000161300001330000000012410275746620014475 0ustar bhdoe;;; -*- logo -*- to unburyname :names unbury namelist :names end bury "unburyname ucblogo-5.5/logolib/until0100644000161300001330000000023610275746620013447 0ustar bhdoe;;; -*- logo -*- .macro until :until.cond :until.instr if run :until.cond [op []] op se :until.instr (list "until :until.cond :until.instr) end bury "until ucblogo-5.5/logolib/while0100644000161300001330000000024210275746620013421 0ustar bhdoe;;; -*- logo -*- .macro while :while.cond :while.instr if not run :while.cond [op []] op se :while.instr (list "while :while.cond :while.instr) end bury "while ucblogo-5.5/logolib/xcor0100644000161300001330000000007310275746620013266 0ustar bhdoe;;; -*- logo -*- to xcor output first pos end bury "xcor ucblogo-5.5/logolib/ycor0100644000161300001330000000007210275746620013266 0ustar bhdoe;;; -*- logo -*- to ycor output last pos end bury "ycor ucblogo-5.5/logolib/localmake0100644000161300001330000000021410275746620014240 0ustar bhdoe;;; -*- logo -*- .macro localmake :name :value output (list "local (word "" :name) "apply ""make (list :name :value)) end bury "localmake ucblogo-5.5/logolib/filep0100644000161300001330000000021110275746620013404 0ustar bhdoe;;; -*- logo -*- to filep :filename ignore error catch "error [openread :filename close :filename] output emptyp error end bury "filep ucblogo-5.5/logolib/iseq0100644000161300001330000000033210275746620013252 0ustar bhdoe;;; -*- logo -*- to iseq :a :b if not (:a > :b) [output iseq1 :a :b] output map [[x] -1 * :x] iseq1 (-1 * :a) (-1 * :b) end to iseq1 :a :b if :a > :b [output []] output fput :a iseq1 :a + 1 :b end bury [iseq iseq1] ucblogo-5.5/logolib/rseq0100644000161300001330000000016110275746620013263 0ustar bhdoe;;; -*- logo -*- to rseq :a :b :n output map [[x] :a + :x * (:b - :a) / (:n - 1)] iseq 0 :n - 1 end bury "rseq ucblogo-5.5/logolib/file?0100644000161300001330000000021510275746620013327 0ustar bhdoe;;; -*- logo -*- to file? :filename ignore error catch "error [openread :filename close :filename] output not emptyp error end bury "file? ucblogo-5.5/logolib/?rest0100644000161300001330000000013510275746620013366 0ustar bhdoe;;; -*- logo -*- to ?rest [:which 1] output bf item :which :template.lists end bury "?rest ucblogo-5.5/logolib/case0100644000161300001330000000102710275746620013226 0ustar bhdoe;;; -*- logo -*- .macro case :case.value :case.clauses [:caseignoredp "true] catch "case.error [output case.helper :case.value :case.clauses] (throw "error [Empty CASE clause]) end to case.helper :case.value :case.clauses if emptyp :case.clauses [output []] if emptyp first :case.clauses [throw "case.error] if or equalp first first :case.clauses "else ~ memberp :case.value first first :case.clauses ~ [output butfirst first :case.clauses] output case.helper :case.value butfirst :case.clauses end bury [case case.helper] ucblogo-5.5/logolib/cond0100644000161300001330000000150510275746620013237 0ustar bhdoe;;; -*- logo -*- .macro cond :cond.clauses localmake "cond.result cond.helper :cond.clauses if equalp first :cond.result "error [(throw "error last :cond.result)] output last :cond.result end to cond.helper :cond.clauses if emptyp :cond.clauses [output [[] []]] if emptyp first :cond.clauses [output [error [Empty COND clause]]] if equalp first first :cond.clauses "else ~ [output list [] butfirst first :cond.clauses] ignore error catch "error [localmake "cond.result run first first :cond.clauses] localmake "cond.error error if not emptyp :cond.error [output list "error item 2 :cond.error] if not memberp :cond.result [true false] ~ [output list "error fput :cond.result [not TRUE or FALSE]] if :cond.result [output list [] butfirst first :cond.clauses] output cond.helper butfirst :cond.clauses end bury [cond cond.helper] ucblogo-5.5/logolib/Messages.fr0100644000161300001330000000463510275746620014500 0ustar bhdoe; French version of Berkeley Logo messages file 5.5 Logo : erreur interne fatale Plus assez de mémoire Débordement de pile Tortue en dehors des limites %p n'aime pas l'argument %s %p ne donne pas de valeur à %p Pas assez d'arguments pour %p %p n'aime pas l'argument %s Trop de choses entre les ( ) Vous ne dites pas ce qu'il faut faire de %s Trop de '(' %s n'a pas de valeur ')' inattendue Je ne connais pas la procédure %p Pas de CATCH correspondant à l'étiquette (tag) %p %p est déjà définie Arrêt... Déjà en train d'appliquer DRIBBLE Erreur système de fichiers: %p Supposant que vous voulez dire SINON (IFELSE) et non SI (IF) %p masquée dans un appel de procédure Throw "Error %p est une primitive Impossible d'utiliser POUR (TO) dans une procédure Je ne connais pas la procédure %p %p sans TEST ']' inattendu '}' inattendu Impossible d'initialiser le graphisme La macro retourne %s au lieu d'une liste Vous ne dites pas ce qu'il faut faire de %s Ne peux utiliser %p que dans une procédure APPLY n'accepte pas l'argument %s FIN (END) dans une instruction multi-ligne dans %p Plus de mémoire (fatal) %p FIN (END) dans une instruction multi-ligne Expression par défaut de l'argument optionnel erronée: %S Ne peux utiliser RETOURNE (OUTPUT) ou STOPPE (STOP) dans RUNRESULT Supposant que vous voulez dire '%p' et non %p Impossible d'ouvrir fichier %p Fichier %p déjà ouvert Fichier %p non ouvert Merci d'utiliser Logo. Bonne journée! Désolé, pas de shell sur le Mac. Tapez EXIT pour revenir à Logo dans %s\n%s ERRACT boucle Pause... arrête sort Fichier non trouvé: %t\n KEYP impossible, pas de FIONREAD sur ce système Mémoire insuffisante Impossible d'ouvrir ce fichier Fichier déjà ouvert Fichier non ouvert Pprop Bienvenue dans Berkeley Logo version %t Vous devez être dans une procédure pour utiliser RETOURNE (OUTPUT) ou STOPPE (STOP) Attention: mémoire insuffisante pour lancer le ramasse-miette Ramasse-miette désactivé - Enregistrez vos données et quittez! %s définie\n Faire %s %s pour %p\nfin\n\n Plist %s = %s\n Aide indisponible.\n Pas d'aide disponible pour %p.\n --plus-- vrai faux fin retourne stoppe goto étiquette si sinon pour .macro toplevel system error rien ; Outputs from SCREENMODE textscreen splitscreen fullscreen ; Outputs from PENMODE paint erase reverse ; Outputs from TURTLEMODE wrap fence window ; HELP turns infix operators +-*/=<> into these sum difference product quotient equalp lessp greaterp lessequalp greaterequalp notequalp ucblogo-5.5/logolib/Messages.sp0100644000161300001330000000462710275746620014514 0ustar bhdoe; Spanish version of Berkeley Logo messages file 5.5 Logo: Error Interno Fatal. no hay espacio desborde de pila tortuga fuera de los límites a %p no le gustó recibir %s %p no entregó nada a %p %p necesita recibir más cosas a %p no le gustó recibir %s demasiadas cosas entre paréntesis () No dices qué debo hacer con %s demasiados paréntesis '(' %s no tiene un valor todavía paréntesis ')' inesperado no sé cómo realizar %p no puedo encontrar la etiqueta LANZA para %p %p ya está definida Parando... DRIBBLE está activado Error del sistema de archivos: %p Asumo que querías decir SIOTRO, no SI %p cubierta por local en llamada a procedimiento ATRAPA "Error %p es una primitiva No puedes usar PARA dentro de un procedimiento no se cómo realizar %p %p sin PRUEBA corchete ']' inesperado llave '}' inesperada no pude inicializar gráficas Macro entregó %s en lugar de una lista No dices qué debo hacer con %s Solo puedes usar %p dentro de un procedimiento a APLICA no le gustó recibir %s FIN dentro de una instrucción multi-línea en %p Logo: Falta de Memoria. %p FIN dentro de una instrucción multi-línea Mala expresión por defecto para parámetro opcional: %s No puedes usar RESPUESTA o ALTO dentro de ACTIVARESULTADO Asumo que querías decir '%p', no %p No puedo abrir archivo %p Archivo %p ya está abierto Archivo %p no está abierto Gracias por usar Logo. Que tengas un buen día. Lo lamento, no hay 'shell' en la Mac. Escribe EXIT para retornar a Logo. en %s\n%s Lazo ERRACT Pausando... se detuvo responde Archivo no encontrado: %t\n No se puede usar TECLAP, no hay FIONREAD en este sistema No hay suficiente memoria No puedo abrir ese archivo Archivo ya está abierto Archivo no está abierto Pprop Bienvenido a Berkeley Logo versión %t Debes estar dentro de un procedimiento para usar REPUESTA o ALTO. Advertencia: No hay suficiente memoria para ejecutar el recolector de basura. GC deshabilitado - Guarda información importante a disco y sal! %s definido\n DA %s %s PARA %p\nFIN\n\n Plista %s = %s\n No hay ayuda disponible.\n No hay ayuda disponible para %p.\n --más-- cierto falso fin respuesta alto saltoa etiqueta si siotro para .macro toplevel sistema error nada ; Outputs from SCREENMODE textscreen splitscreen fullscreen ; Outputs from PENMODE paint erase reverse ; Outputs from TURTLEMODE wrap fence window ; HELP turns infix operators +-*/=<> into these sum difference product quotient equalp lessp greaterp lessequalp greaterequalp notequalp ucblogo-5.5/logolib/havemake0100644000161300001330000000021107665743370014076 0ustar bhdoe;;; -*- logo -*- .macro havemake :name :value output (list "have (word "" :name) "apply ""make (list :name :value)) end bury "havemake ucblogo-5.5/logolib/extract0100644000161300001330000000037707666725206014003 0ustar bhdoe;;; -*- logo -*- to extract :name :initlist :default.value if emptyp :initlist [output :default.value] if equalp :name first :initlist [output first butfirst :initlist] output extract :name (butfirst butfirst :initlist) :default.value end bury "extract ucblogo-5.5/logolib/logo-logo0100644000161300001330000001377010275746620014221 0ustar bhdoe;;; -*- logo -*- ;; a logo for logo written in logo ;-) ;; version 0.1 ;; by AKFoerster Make "Startup [UCBLogo wait 300 ucblogo.reset] to ucblogo.reset cs SetPen [pendown paint [0 0] 7 [-1]] setbg 0 clearScreen ShowTurtle Wrap TextScreen erase [ucblogo ucblogo.DrawUCBLogo ucblogo.StartPos ucblogo.DrawUCB] erase [ucblogo.DrawLogo ucblogo.LetterSpace ucblogo.HalfWidth ucblogo.Next] erase [ucblogo.DrawU ucblogo.DrawC ucblogo.DrawB] erase [ucblogo.DrawL ucblogo.DrawO ucblogo.DrawG ucblogo.reset] ern "Startup end ;; Homeposition: Turtle at bottom/center of letter/Line to UCBLogo Localmake "Title word "Berkeley\ Logo\ version\ :LogoVersion Localmake "LetterHeight 70 Localmake "LetterWidth 30 Localmake "LetterSpace 25 Localmake "HalfLineSpace 15 Localmake "MyPenSize 10 Localmake "FontColor 4 Localmake "ShadowColor 0 Localmake "BorderColor 2 Localmake "FillColor 6 Localmake "LabelColor 0 ;; just guessing: (!!!) Localmake "LabelLetterWidth ifelse equalp LogoPlatform "Windows [4] [3] HideTurtle ClearScreen Window FullScreen setPenSize list :MyPenSize :MyPenSize ;; Background ;; "Q should also be dependant on "LetterHeight (!!!) localMake "Q Product ucblogo.LetterSpace 4 setbg :fillcolor setpc 0 fill setPenColor :BorderColor PenUp setXY :Q 0 PenDown setXY 0 :Q setXY -:Q 0 setXY 0 -:Q setXY :Q 0 PenUp Home setPenColor :FillColor fill ;; shadow setXY :myPenSize*0.7 -:myPenSize*0.7 setPenColor :ShadowColor ucblogo.DrawUCBLogo ;; coloured Logo Home setPenColor :FontColor ucblogo.DrawUCBLogo ;; Label - doesn't work on windows (!!!) PenUp Home Back :LetterHeight repeat 3 [Back :HalfLineSpace] setPenColor :LabelColor setX minus product count :Title :LabelLetterWidth setPenSize [1 1] label :Title wait 30 setx 0 fd 15 rt 120 setpc :FontColor setPenSize [7 7] pd arc 120 :LetterHeight pu seth 0 bk 30 setx -20 pd fd 2 bk 2 pu setx 20 pd fd 2 bk 2 pu print :Title end to ucblogo.DrawUCBLogo localMake "HomePos Pos PenUp SetHeading 0 Forward :HalfLineSpace ucblogo.DrawUCB setPos :HomePos SetHeading 0 PenUp back :HalfLineSpace back :LetterHeight ucblogo.DrawLogo end to ucblogo.StartPos "Letters ;; assume Turtle in center of text PenUp setheading 270 Forward quotient ( product :Letters ucblogo.LetterSpace ) 2 back quotient ucblogo.LetterSpace 2 wait 30 end to ucblogo.DrawUCB ucblogo.StartPos 3 ucblogo.DrawU ucblogo.Next ucblogo.DrawC ucblogo.Next ucblogo.DrawB end to ucblogo.DrawLogo ucblogo.StartPos 4 ucblogo.DrawL ucblogo.Next ucblogo.DrawO ucblogo.Next ucblogo.DrawG ucblogo.Next ucblogo.DrawO end to ucblogo.LetterSpace output sum :LetterWidth :LetterSpace end to ucblogo.HalfWidth output quotient :LetterWidth 2 end to ucblogo.Next PenUp setheading 90 Forward ucblogo.LetterSpace wait 30 end to ucblogo.DrawU ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight ucblogo.HalfWidth ;; Left side PenUp Left 90 Forward :LetterWidth PenDown Left 90 Forward difference :LetterHeight ucblogo.HalfWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end to ucblogo.DrawC ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth Left 90 Forward difference :LetterHeight :LetterWidth ;; upper arc PenUp Left 90 Forward ucblogo.HalfWidth PenDown arc 180 ucblogo.HalfWidth ;; Left side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end to ucblogo.DrawB localMake "QuaterHeight Quotient :LetterHeight 4 ;; Move to startposition setheading 270 PenUp ;; the width is equal :QuaterHeight Forward Quotient :QuaterHeight 2 ;; Draw PenDown Right 90 Forward :LetterHeight back :QuaterHeight arc 175 :QuaterHeight back :QuaterHeight back :QuaterHeight arc 175 :QuaterHeight ;; Move to Homeposition PenUp back :QuaterHeight Right 90 Forward Quotient :QuaterHeight 2 end to ucblogo.DrawL ;; Move to top of L setheading 270 PenUp Forward ucblogo.HalfWidth Right 90 Forward :LetterHeight Right 180 ;; Draw PenDown Forward :LetterHeight Left 90 Forward :LetterWidth ;; Move to Homeposition PenUp back ucblogo.HalfWidth end to ucblogo.DrawO ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; upper arc PenUp Left 90 Forward ucblogo.HalfWidth PenDown arc 180 ucblogo.HalfWidth ;; Left side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end to ucblogo.DrawG ;; lower arc setheading 0 PenUp Forward ucblogo.HalfWidth Right 90 PenDown arc 180 ucblogo.HalfWidth ;; Right side PenUp Forward ucblogo.HalfWidth PenDown Right 90 Forward ucblogo.HalfWidth back ucblogo.HalfWidth Right 90 Forward ucblogo.HalfWidth back ucblogo.HalfWidth PenUp Right 90 Forward difference :LetterHeight :LetterWidth ;; upper arc PenUp Left 90 Forward ucblogo.HalfWidth PenDown arc 180 ucblogo.HalfWidth ;; Left side PenUp Forward ucblogo.HalfWidth PenDown Left 90 Forward difference :LetterHeight :LetterWidth ;; Move to Homeposition PenUp Forward ucblogo.HalfWidth Left 90 Forward ucblogo.HalfWidth end ucblogo-5.5/xgraphics.c0100644000161300001330000002265210276007302013070 0ustar bhdoe/* X window graphics for logo. Nov. 1991. */ /* Note: logo uses True and False as variables to hold references to the nodes containing the values true and false. X uses them as macros serving the functions often served by the more standard TRUE and FALSE. To avoid a conflict, don't use True and False in this file. */ #ifndef X_DISPLAY_MISSING #include #include "logo.h" #include "xgraphics.h" #include "globals.h" char *LogoPlatformName="X11"; int clearing_screen = 0; #ifdef SIGWINCH #ifdef SIG_TAKES_ARG #define sig_arg 0 RETSIGTYPE x_win_resize(int sig) #else #define sig_arg RETSIGTYPE x_win_resize() #endif { signal(SIGWINCH, x_win_resize); placate_x(); SIGRET } #endif /* SIGWINCH */ int have_x = -1; XWMHints xwmh = { (InputHint|StateHint), /* flags */ FALSE, /* input */ NormalState, /* initial_state */ 0, /* icon pixmap */ 0, /* icon window */ 0, 0, /* icon location */ 0, /* icon mask */ 0, /* Window group */ }; int screen_height = DEFAULT_HEIGHT; int screen_width = DEFAULT_WIDTH; int x_mouse_x, x_mouse_y, x_buttondown=0; /* We'll use 16 named colors for now (see xgraphics.h). The ordering here corresponds to the zero-based argument to setpencolor that gives that color -- pink is 12, turquoise is 10 etc. */ char *colorname[NUMINITCOLORS] = { "black", "blue" , "green" , "cyan" , "red" , "magenta", "yellow", "white", "brown", "tan", "dark green", /* Should be 'forest' */ "aquamarine", /* Should be 'aqua' */ "salmon", "purple", "orange", "grey" }; XColor color[NUMCOLORS+2]; XColor dummy; void nop() { } pen_info xgr_pen; int back_ground; Display *dpy; /* X server connection */ Window win; /* Window ID */ GC draw_gc, /* GC to draw with */ up_gc, /* Do nothing gc. */ erase_gc, /* Erase gc. */ reverse_gc; /* GC to reverse things. */ int screen; int save_argc; char ** save_argv; void x_window_init(int argc, char **argv) { save_argc = argc; save_argv = argv; } void real_window_init() { unsigned long fth, pad; /* Font size parameters */ unsigned long fg, bg, bd; /* Pixel values */ unsigned long bw; /* Border width */ XFontStruct *fontstruct; /* Font descriptor */ XGCValues gcv; /* Struct for creating GC */ XEvent event; /* Event received */ XSizeHints xsh; /* Size hints for window manager */ XSetWindowAttributes xswa; /* Temporary Set Window Attribute struct */ int n; /* Open X display. */ if ((dpy = XOpenDisplay(NULL)) == NULL) { have_x = 0; return; } else have_x = 1; screen = DefaultScreen(dpy); /* Load default font. */ if ((fontstruct = XLoadQueryFont(dpy, FONT)) == NULL) { have_x = 0; return; } fth = fontstruct->max_bounds.ascent + fontstruct->max_bounds.descent; /* * Select colors. */ for(n = 0; n < NUMINITCOLORS; n++) XAllocNamedColor(dpy, DefaultColormap(dpy, screen), colorname[n], &color[n+2], &dummy); for (n = NUMINITCOLORS; n < NUMCOLORS; n++) color[n+2] = color[(n+2) % NUMINITCOLORS]; xgr_pen.color = 7; /* Not much alternative to the following, because of the use of the xor operation to erase the turtle. The background HAS to be the zero pixel or the scheme won't work. */ bg = BlackPixel(dpy, screen); fg = bd = WhitePixel(dpy, screen); /* * Set the border width of the window, and the gap between the text * and the edge of the window, "pad". */ pad = BORDER; bw = 1; /* Set up size/position hints. */ xsh.flags = (PPosition | PSize); xsh.height = DEFAULT_HEIGHT; xsh.width = DEFAULT_WIDTH; xsh.x = (DisplayWidth(dpy, DefaultScreen(dpy)) - xsh.width) / 2; xsh.y = (DisplayHeight(dpy, DefaultScreen(dpy)) - xsh.height) / 2; win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), xsh.x, xsh.y, xsh.width, xsh.height, bw, bd, bg); /* Label window. */ XSetStandardProperties(dpy, win, "BXLogo", "BXLogo", None, save_argv, save_argc, &xsh); XSetWMHints(dpy, win, &xwmh); /* Set up default color map. */ xswa.colormap = DefaultColormap(dpy, DefaultScreen(dpy)); xswa.backing_store = Always; XChangeWindowAttributes(dpy, win, CWColormap | CWBackingStore, &xswa); /* * Create GCs. */ /* Make the foreground and background fields in the GC match the fg and bg variables that were passed to the window. */ gcv.font = fontstruct->fid; gcv.background = BlackPixel(dpy, screen); gcv.foreground = WhitePixel(dpy, screen); gcv.plane_mask = AllPlanes; /* Normal drawing GC. */ draw_gc = XCreateGC(dpy, win, (GCPlaneMask | GCFont | GCForeground | GCBackground), &gcv); /* Create GC for erasing/drawing turtle. */ gcv.function = GXxor; reverse_gc = XCreateGC(dpy, win, (GCPlaneMask | GCFont | GCFunction | GCForeground | GCBackground), &gcv); /* Erase gc just draws the bacground color. */ gcv.foreground = bg; gcv.function = GXcopy; erase_gc = XCreateGC(dpy, win, (GCPlaneMask | GCFont | GCForeground | GCBackground), &gcv); gcv.function = GXnoop; up_gc = XCreateGC(dpy, win, (GCPlaneMask | GCFunction | GCForeground | GCBackground), &gcv); xgr_pen.pm = draw_gc; xgr_pen.vis = 0; XSelectInput(dpy, win, EVENT_MASK); /* * Map the window to make it visible. See Section 3.5. */ XMapWindow(dpy, win); /* * Loop, examining each event. Exit when we get mapped. */ do { /* * Get the next event */ XWindowEvent(dpy, win, StructureNotifyMask, &event); /* * Wait for the map notify event. */ if (event.type == MapNotify) { XClearWindow(dpy, win); break; } } while(1); lclearscreen(NIL); move_to(screen_x_coord, screen_y_coord); /* if(turtle_shown) draw_turtle(); */ #ifdef SIGWINCH signal(SIGWINCH, x_win_resize); #endif } void save_pen(pen_info *p) { memcpy(((char *)(p)),((char *)(&xgr_pen)),sizeof(pen_info)); } void restore_pen(pen_info *p) { memcpy(((char *)(&xgr_pen)),((char *)(p)),sizeof(pen_info)); set_pen_width(p->pw); set_pen_height(p->ph); } void placate_x() { XEvent event; XConfigureEvent *xce; XMotionEvent *xme; XButtonEvent *xbe; checkX; while(XCheckWindowEvent(dpy, win, EVENT_MASK, (XEvent *)&event)) switch(event.type) { case ConfigureNotify: xce = (XConfigureEvent *)&event; screen_height = xce->height; screen_width = xce->width; XClearWindow(dpy, win); /* if (!clearing_screen) */ redraw_graphics(); break; case MotionNotify: xme = (XMotionEvent *)&event; x_mouse_x = xme->x; x_mouse_y = xme->y; break; case ButtonPress: xbe = (XButtonEvent *)&event; #undef button x_buttondown = xbe->button; mouse_click; break; case ButtonRelease: x_buttondown = 0; break; } } void check_X11_stop() { static int count=300; if (--count == 0) { count = 300; checkX; placate_x(); } } int get_button() { checkX; placate_x(); return( x_buttondown ); } int get_mouse_x() { checkX; placate_x(); return( x_mouse_x - (screen_width / 2)); } int get_mouse_y() { checkX; placate_x(); return((screen_height / 2) - x_mouse_y); } void floodfill( XImage *img, int x, int y, unsigned long oldColor, unsigned long newColor ) { int lastBorder; int leftLimit, rightLimit; int i; if (oldColor == newColor) { /* Nothing to be done */ return; } /* Seek left */ leftLimit = (-1); for (i = x; (i >= 0); i--) { if (XGetPixel(img, i, y) != oldColor) { break; } XPutPixel(img, i, y, newColor); leftLimit = i; } if (leftLimit == (-1)) { return; } /* Seek right */ rightLimit = x; for (i = (x+1); (i < screen_width); i++) { if (XGetPixel(img, i, y) != oldColor) { break; } XPutPixel(img, i, y, newColor); rightLimit = i; } /* Look at lines above and below and start paints */ /* Above */ if (y > 0) { lastBorder = 1; for (i = leftLimit; (i <= rightLimit); i++) { int c; c = XGetPixel(img, i, y-1); if (lastBorder) { if (c == oldColor) { floodfill(img, i, y-1, oldColor, newColor); lastBorder = 0; } } else if (c != oldColor) { lastBorder = 1; } } } /* Below */ if (y < screen_height - 1) { lastBorder = 1; for (i = leftLimit; (i <= rightLimit); i++) { int c; c = XGetPixel(img, i, y+1); if (lastBorder) { if (c == oldColor) { floodfill(img, i, y+1, oldColor, newColor); lastBorder = 0; } } else if (c != oldColor) { lastBorder = 1; } } } } void logofill() { XImage *img = XGetImage(dpy, win, 0, 0, screen_width, screen_height, -1, ZPixmap ); floodfill( img, xgr_pen.xpos, xgr_pen.ypos, XGetPixel( img, xgr_pen.xpos, xgr_pen.ypos ), color[(xgr_pen.color)+2].pixel ); XPutImage( dpy, win, draw_gc, img, 0, 0, 0, 0, screen_width, screen_height ); XDestroyImage( img ); } void set_palette(int n, unsigned int r, unsigned int g, unsigned int b) { n+=2; color[n].red = r; color[n].green = g; color[n].blue = b; color[n].flags = DoRed|DoGreen|DoBlue; /* unnecessary? */ XAllocColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &color[n]); } void get_palette(int n, unsigned int *r, unsigned int *g, unsigned int *b) { n+=2; *r = color[n].red; *g = color[n].green; *b = color[n].blue; } #endif ucblogo-5.5/xgraphics.h0100644000161300001330000001521610271577430013104 0ustar bhdoe/* X window system graphics header file. */ #include #include #include extern int have_x; extern int back_ground; extern void real_window_init(); void logofill(void); /* Some X-related defines. */ #define BORDER 1 #define FONT "fixed" #define NUMCOLORS 512 #define NUMINITCOLORS 16 #define EVENT_MASK (StructureNotifyMask | PointerMotionMask \ | ButtonPressMask | ButtonReleaseMask) #define DEFAULT_HEIGHT 500 #define DEFAULT_WIDTH 500 #define GR_SIZE 60000 #define checkX { \ if (have_x < 0) real_window_init(); \ if (!have_x) { \ err_logo(BAD_GRAPH_INIT,NIL); \ return; \ } \ } #define prepare_to_draw {checkX; placate_x();} #define done_drawing XFlush(dpy) extern void placate_x(); #define prepare_to_draw_turtle nop() #define done_drawing_turtle nop() #define screen_left 0 #define screen_right (screen_width-1) #define screen_top 0 #define screen_bottom (screen_height-1) /* #define screen_height (1 + screen_bottom - screen_top) */ /* #define screen_width (1 + screen_right - screen_left) */ #define screen_x_center (screen_left + (screen_width)/2) #define screen_y_center (screen_top + (screen_height)/2) #define turtle_left_max ((screen_left) - (screen_x_center)) #define turtle_right_max ((screen_right) - (screen_x_center)) #define turtle_top_max ((screen_y_center) - (screen_top)) #define turtle_bottom_max ((screen_y_center) - (screen_bottom)) #define screen_x_coord ((screen_x_center) + turtle_x) #define screen_y_coord ((screen_y_center) - turtle_y) #define turtle_height 18 #define turtle_half_bottom 6.0 #define turtle_side 19.0 #define clear_screen XClearWindow(dpy, win) #define erase_screen() XClearWindow(dpy, win) #define line_to(a,b) if(xgr_pen.vis==0)\ XDrawLine(dpy,win,xgr_pen.pm,\ xgr_pen.xpos,xgr_pen.ypos,\ (a),(b));\ xgr_pen.xpos=(a);\ xgr_pen.ypos=(b) #define move_to(a,b) xgr_pen.xpos=(a);\ xgr_pen.ypos=(b) #define draw_string(s) XDrawString(dpy,win,xgr_pen.pm,\ xgr_pen.xpos,xgr_pen.ypos,\ (s),strlen((s))); #define set_pen_vis(v) xgr_pen.vis=(v) #define set_pen_mode(m) xgr_pen.pm=(m) #define set_pen_color(c) draw_turtle();\ xgr_pen.color=c%NUMCOLORS;\ XSetForeground(dpy,draw_gc,color[2+xgr_pen.color].pixel);\ XSetForeground(dpy,reverse_gc,color[2+xgr_pen.color].pixel);\ draw_turtle(); #define set_back_ground(c) back_ground=c%NUMCOLORS;\ XSetBackground(dpy,draw_gc,color[2+back_ground].pixel);\ XSetBackground(dpy,reverse_gc,color[2+back_ground].pixel);\ XSetBackground(dpy,erase_gc,color[2+back_ground].pixel);\ XSetForeground(dpy,erase_gc,color[2+back_ground].pixel);\ XSetWindowBackground(dpy,win,color[2+back_ground].pixel);\ redraw_graphics(); #define set_pen_width(w) XSetLineAttributes(dpy, draw_gc, w, LineSolid, \ CapProjecting, JoinMiter);\ XSetLineAttributes(dpy, erase_gc, w, LineSolid, \ CapProjecting, JoinMiter);\ XSetLineAttributes(dpy, reverse_gc, w, LineSolid, \ CapProjecting, JoinMiter);\ xgr_pen.pw = w; #define set_pen_height(h) XSetLineAttributes(dpy, draw_gc, h, LineSolid, \ CapProjecting, JoinMiter);\ XSetLineAttributes(dpy, erase_gc, h, LineSolid, \ CapProjecting, JoinMiter);\ XSetLineAttributes(dpy, reverse_gc, h, LineSolid, \ CapProjecting, JoinMiter);\ xgr_pen.ph = h; #define set_pen_x(x) nop() #define set_pen_y(y) nop() /* pen_info is a stucture type with fields for the various pen characteristics including the location, size, color, mode (e.g. XOR or COPY), pattern, visibility (0 = visible) */ typedef struct { int color; int xpos; int ypos; int vis; int pw; int ph; GC pm; } pen_info; extern pen_info xgr_pen; #define p_info_x(p) (p.xpos) #define p_info_y(p) (p.ypos) /* All these should take an argument, like the two just above. Then we could support multiple turtles. */ #define pen_width xgr_pen.pw #define pen_height xgr_pen.ph #define pen_color xgr_pen.color #define pen_mode xgr_pen.pm #define pen_vis xgr_pen.vis #define pen_x (xgr_pen.xpos) #define pen_y (xgr_pen.ypos) #define get_node_pen_pattern (cons(make_intnode(-1), NIL)) #define pen_reverse pen_mode=reverse_gc #define pen_erase pen_mode=erase_gc #define pen_down pen_mode=draw_gc #define button get_button() #define mouse_x get_mouse_x() #define mouse_y get_mouse_y() /* There seems little point in implementing these unless we put everything in one window. (Possibly use a slave xterm?) */ #define full_screen nop() #define split_screen nop() #define text_screen nop() #define plain_xor_pen() pen_reverse #define label(s) XDrawImageString(dpy,win,xgr_pen.pm,\ xgr_pen.xpos,xgr_pen.ypos,\ (s), strlen(s)) #define tone(p,d) nop() #define get_pen_pattern(p) nop() #define set_pen_pattern(p) nop() #define set_list_pen_pattern(p) nop() extern void set_palette(int, unsigned int, unsigned int, unsigned int); extern void get_palette(int, unsigned int*, unsigned int*, unsigned int*); /* The sparc has fmod. So I use it. */ /* #define fmod(x,y) x */ extern void nop(); /* Global X variables. */ extern int screen_height, screen_width; extern Display *dpy; /* X server connection */ extern Window win; /* Window ID */ extern GC draw_gc, /* GC to draw with */ erase_gc, /* GC to draw with */ reverse_gc; /* GC to draw with */ extern XColor color[]; extern XColor dummy; extern int get_mouse_x(), get_mouse_y(); /* Avoid name conflicts. Note: if xgraphics.c uses True and False, bad things are likely to happen. */ #undef True #undef False ucblogo-5.5/ztcterm.c0100644000161300001330000004200110274565164012573 0ustar bhdoe/* * ztcterm.c IBM screen module mak * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "logo.h" #include "globals.h" #include #include #include #include #include #include #include #include #include "ztcterm.h" char *LogoPlatformName="DOS"; /************************************************************/ unsigned _stack = 8000; /* 5000 for debugging, 65000 for real */ BOOLEAN in_graphics_mode = FALSE, in_splitscreen = FALSE; BOOLEAN have_been_in_graphics_mode = FALSE, can_do_color = FALSE; BOOLEAN in_erase_mode = FALSE; /* NOTE NOTE NOTE: graphics.c really really believes that the top left * corner of the screen has hardware coords (0,0). Zortech has (0,0) * in the BOTTOM left. It's hopeless to fix graphics.c so instead we * use the following kludge: go ahead and think the screen is upside down, * and switch to Zortech coords only in draw_line! */ int ibm_screen_bottom; int current_write_mode = FG_MODE_SET; int current_vis = 0; fg_color_t turtle_color, bg_color; fg_color_t dull, bright; fg_coord_t texth; fg_coord_t MaxX, MaxY; int ztc_penwidth = 1, ztc_linepattern = -1; fg_box_t ztc_box, ztc_textbox, text_scroll_box, text_last_line_box, clear_box; void rgb_init(void); int scrunching = FALSE; fg_line_t the_line; fg_coord_t ztc_x, ztc_y; fg_color_t ztc_textcolor; fg_color_t ztc_text_bgcolor = 0; fg_coord_t ztc_graph_textx, ztc_graph_texty; FIXNUM pen_color = 0, back_ground = 7; void moveto(int x, int y) { ztc_x = (fg_coord_t)x; ztc_y = (fg_coord_t)y; } void lineto(int x, int y) { msm_hidecursor(); fg_make_line(the_line, ztc_x, MaxY-ztc_y, (fg_coord_t)x, MaxY-(fg_coord_t)y); fg_drawthickline((in_erase_mode ? bg_color : turtle_color), current_write_mode, ~0, FG_LINE_SOLID, the_line, ztc_box, ztc_penwidth); moveto(x, y); msm_showcursor(); } void outtext(char *s) { msm_hidecursor(); fg_puts((in_erase_mode ? bg_color : turtle_color), current_write_mode, ~0, FG_ROT0, ztc_x, MaxY-ztc_y, s, fg.displaybox); msm_showcursor(); } void gr_mode(void) { int errorcode; if (!in_graphics_mode) { msm_hidecursor(); x_coord = x_margin; y_coord = y_margin; errorcode = fg_init(); if (have_been_in_graphics_mode) { in_graphics_mode = TRUE; if (turtle_shown && !refresh_p) draw_turtle(); redraw_graphics(); } else { if (errorcode == 0) err_logo(BAD_GRAPH_INIT, NIL); else { in_graphics_mode = have_been_in_graphics_mode = TRUE; if (can_do_color = (fg.nsimulcolor > 16 /* != fg.ncolormap */ )) { rgb_init(); dull = fg.nsimulcolor-1; bright = 7; } else { turtle_color = FG_HIGHLIGHT; dull = FG_WHITE; bright = FG_HIGHLIGHT; } bg_color = FG_BLACK; ztc_set_penc(7); if (ztc_textcolor == FG_WHITE) ztc_textcolor = dull; back_ground = 0; ztc_box[FG_X1] = ztc_textbox[FG_X1] = text_scroll_box[FG_X1] = text_last_line_box[FG_X1] = clear_box[FG_X1] = fg.displaybox[FG_X1]; ztc_textbox[FG_Y1] = fg.displaybox[FG_Y1]; ztc_box[FG_X2] = ztc_textbox[FG_X2] = text_scroll_box[FG_X2] = text_last_line_box[FG_X2] = clear_box[FG_X2] = MaxX = fg.displaybox[FG_X2]; ztc_box[FG_Y2] = MaxY = clear_box[FG_Y2] = fg.displaybox[FG_Y2]; y_scale = (double)fg.pixelx/(double)fg.pixely; { FILE *fp = fopen("scrunch.dat","r"); if (fp != NULL) { scrunching = TRUE; if (filelength(fileno(fp)) > 0) { fread(&x_scale, sizeof(FLONUM), 1, fp); fread(&y_scale, sizeof(FLONUM), 1, fp); } fclose(fp); } } if (MaxY == 479) texth = 16; else texth = (MaxY+1)/25; ztc_box[FG_Y1] = 4*texth+1; clear_box[FG_Y1] = 4*texth; ibm_screen_bottom = MaxY - (ztc_box[FG_Y1]); ztc_textbox[FG_Y2] = 4*texth-1; text_scroll_box[FG_Y2] = 3*texth-1; text_scroll_box[FG_Y1] = 0; text_last_line_box[FG_Y2] = texth-1; lclearscreen(NIL); lcleartext(NIL); in_splitscreen = TRUE; } } msm_showcursor(); } } void nop() { } void init_ibm_memory(void) { } volatile int ctrl_c_count = 0; BOOLEAN check_ibm_stop(void) { int key; int __ss *p; /* if (kbhit()) getch(); */ /* allow DOS to test for control-C */ p = &key; if ((int)p < 500) { err_logo(STACK_OVERFLOW, NIL); return(1); } if (((key = bioskey(1)) == (4113)) || ctrl_c_count > 0) { /* control-q */ if (ctrl_c_count == 0) getch(); ctrl_c_count = 0; err_logo(STOP_ERROR,NIL); return(1); } if (key == (4375)) { /* control-w */ getch(); to_pending = 0; lpause(NIL); } return (0); } void term_init_ibm(void) { disp_open(); msm_init(); msm_setareay(0,(disp_numrows-1)*8); msm_showcursor(); ztc_textcolor = FG_WHITE; tty_charmode = 0; x_max = 80; y_max = 25; x_coord = y_coord = 0; so_arr[0] = '\1'; so_arr[1] = '\0'; se_arr[0] = '\2'; se_arr[1] = '\0'; } void ibm_gotoxy(int x, int y) { if (in_graphics_mode) { if (!in_splitscreen) lsplitscreen(NIL); if (y >= 4) y = 3; ztc_graph_texty = texth*(3-y); fg_adjustxy(FG_ROT0, x, &ztc_graph_textx, &ztc_graph_texty, fg.charbox); } else { disp_move(y, x); msm_hidecursor(); disp_flush(); msm_showcursor(); } } fg_color_t color_table[8] = {0, 9, 10, 11, 12, 13, 14, 15}; FIXNUM hw_color(FIXNUM c) { if (can_do_color) return c; if (c >= 0 && c < 8) return color_table[c]; if (c < 0) return c; return c-8; } void ibm_clear_text(void) { if (in_graphics_mode) { if (in_splitscreen) erase_graphics_top(); } else { disp_move(0,0); disp_eeop(); msm_hidecursor(); disp_flush(); msm_showcursor(); } } void ibm_clear_screen(void) { msm_hidecursor(); fg_fillbox(bg_color, FG_MODE_SET, ~0, clear_box); msm_showcursor(); } void ibm_plain_mode(void) { if (in_graphics_mode) ztc_textcolor = dull; else disp_endstand(); } void ibm_bold_mode(void) { if (in_graphics_mode) ztc_textcolor = bright; else disp_startstand(); } NODE *set_text_color(NODE *args) { int fore, back; fore = getint(pos_int_arg(args)); if (NOT_THROWING) { back = getint(pos_int_arg(cdr(args))); if (NOT_THROWING) { ztc_textcolor = hw_color(fore); ztc_text_bgcolor = hw_color(back); disp_setattr((back&07)<<4 | (fore&07)); } } return UNBOUND; } void erase_graphics_top(void) { msm_hidecursor(); fg_fillbox(FG_BLACK, FG_MODE_SET, ~0, ztc_textbox); msm_showcursor(); ztc_graph_textx = 0; ztc_graph_texty = 3*texth; } /************************************************************/ /* These are the machine-specific graphics definitions. All versions must provide a set of functions analogous to these. */ void save_pen(pen_info *p) { p->h = ztc_x; p->v = ztc_y; p->vis = current_vis; p->width = ztc_penwidth; p->color = turtle_color; get_pen_pattern(p->pattern); p->mode = get_ibm_pen_mode(); } void restore_pen(pen_info *p) { moveto(p->h, p->v); current_vis = p->vis; ztc_penwidth = p->width; set_ibm_pen_mode(p->mode); /* must restore mode before color */ turtle_color = p->color; set_pen_pattern(p->pattern); } struct rgbcolor { int red, green, blue; } the_palette[256] = { {0,0,0}, {0,0,0}, /* entries -2 and -1 */ {0, 0, 0}, {0, 0, 255}, {0, 255, 0}, {0, 255, 255}, {255, 0, 0}, {255, 0, 255}, {255, 255, 0}, {255, 255, 255}, {155, 96, 59}, {197, 136, 18}, {100, 162, 64}, {120, 187, 187}, {255, 149, 119}, {144, 113, 208}, {255, 163, 0}, {183, 183, 183}}; void rgb_init(void) { int i,j; for (i=0; i<16; i++) { fg_setpalette(i+2, the_palette[i+2].red, the_palette[i+2].green, the_palette[i+2].blue); for (j=i+16; j= 255) return; the_palette[slot].red = (r+128)/256; the_palette[slot].green = (g+128)/256; the_palette[slot].blue = (b+128)/256; fg_setpalette(slot-1, the_palette[slot].red, the_palette[slot].green, the_palette[slot].blue); } void get_palette(int slot, unsigned int *r, unsigned int *g, unsigned int *b) { slot+=2; *r = the_palette[slot % 256].red * 256; *g = the_palette[slot % 256].green * 256; *b = the_palette[slot % 256].blue * 256; } void ibm_pen_down(void) { current_write_mode = FG_MODE_SET; turtle_color = hw_color(pen_color); in_erase_mode = FALSE; } void ibm_pen_xor(void) { current_write_mode = FG_MODE_XOR; turtle_color = hw_color(pen_color)^bg_color; in_erase_mode = FALSE; } void ibm_pen_erase(void) { if (!in_erase_mode) { current_write_mode = FG_MODE_SET; turtle_color = hw_color(pen_color); in_erase_mode = TRUE; } } int get_ibm_pen_mode(void) { if (in_erase_mode) return 2; else return current_write_mode; } void set_ibm_pen_mode(int m) { switch (m) { case 2: ibm_pen_erase(); break; case FG_MODE_SET: ibm_pen_down(); break; case FG_MODE_XOR: ibm_pen_xor(); break; } } int get_ibm_pen_width(void) { return ztc_penwidth; } void set_pen_pattern(char *pat) { ztc_linepattern = *(int *)pat; } void set_list_pen_pattern(NODE *arg) { NODE *temp; temp = cnv_node_to_numnode(car(arg)); ztc_linepattern = getint(temp); } void get_pen_pattern(char *pat) { *(int *)pat = ztc_linepattern; } NODE *Get_node_pen_pattern(void) { return(cons(make_intnode(0-1L), NIL)); } void label(char *s) { gr_mode(); moveto(g_round(screen_x_coord), g_round(screen_y_coord)); outtext(s); } void logofill(void) { msm_hidecursor(); fg_fill(ztc_x, MaxY-ztc_y, turtle_color, turtle_color); msm_showcursor(); } void erase_screen(void) { ibm_clear_screen(); } void t_screen(void) { if (in_graphics_mode) { fg_term(); in_graphics_mode = FALSE; in_splitscreen = FALSE; y_max = 25; } } void s_screen(void) { int save_vis; if (in_graphics_mode && !in_splitscreen) { if (turtle_shown && (screen_y_coord > (MaxY - (4*texth+1)))) { save_vis = current_vis; current_vis = -1; lhome(NIL); current_vis = save_vis; } erase_graphics_top(); } if (!have_been_in_graphics_mode) gr_mode(); in_splitscreen = TRUE; ztc_box[FG_Y1] = 4*texth+1; clear_box[FG_Y1] = 4*texth; ibm_screen_bottom = MaxY - (ztc_box[FG_Y1]); y_max = 4; gr_mode(); } void f_screen(void) { if (in_graphics_mode && in_splitscreen) erase_graphics_top(); in_splitscreen = FALSE; ztc_box[FG_Y1] = clear_box[FG_Y1] = 0; ibm_screen_bottom = MaxY; gr_mode(); } FIXNUM mickey_x(void) { int x,y; (void)msm_getstatus(&x,&y); return x-screen_x_center; } #define screen_x_coord ((screen_x_center) + turtle_x) #define screen_y_coord ((screen_y_center) - turtle_y) FIXNUM mickey_y(void) { int x,y; (void)msm_getstatus(&x,&y); return screen_y_center-y; } BOOLEAN Button(void) { int x,y,b; b = msm_getstatus(&x,&y); if (b&1) return 1; if (b&2) return 2; if (b&4) return 3; return 0; } void tone(FIXNUM pitch, FIXNUM duration) { FIXNUM period = 2400000L/pitch; /* 200000 */ FIXNUM cycles = duration * pitch/60; if (cycles > 0) sound_tone((int)cycles, (int)period, (int)period); } FIXNUM t_height(void) { return 18; } FLONUM t_half_bottom(void) { return 6.0; } FLONUM t_side(void) { return 19.0; } void check_scroll(void) { msm_hidecursor(); fg_blit(text_scroll_box, 0, texth, fg.activepage, fg.activepage); fg_fillbox(FG_BLACK, FG_MODE_SET, ~0, text_last_line_box); msm_showcursor(); } void ztc_put_char(int ch) { fg_box_t temp_box; msm_hidecursor(); if (in_graphics_mode && !in_splitscreen) lsplitscreen(NIL); if (ch != '\1' && ch != '\2') { if (in_graphics_mode) { if (ch == '\n') { ztc_graph_textx = 0; if (ztc_graph_texty - texth >= 0) ztc_graph_texty -= texth; else check_scroll(); } else if (ch == '\b') { if (ztc_graph_textx > 0) fg_adjustxy(FG_ROT180, 1, &ztc_graph_textx, &ztc_graph_texty, fg.charbox); } else if (ch == '\t') { fg_adjustxy(FG_ROT0, 8 - (x_coord&07), &ztc_graph_textx, &ztc_graph_texty, fg.charbox); if (ztc_graph_textx >= MaxX) print_char(stdout,'\n'); } else { if (ztc_text_bgcolor != 0) { temp_box[FG_X1] = temp_box[FG_X2] = ztc_graph_textx; temp_box[FG_Y1] = temp_box[FG_Y2] = ztc_graph_texty; fg_adjustxy(FG_ROT0, 2, &temp_box[FG_X2], &temp_box[FG_Y2], fg.charbox); temp_box[FG_Y2] += texth-1; fg_fillbox(ztc_text_bgcolor, FG_MODE_SET, ~0, temp_box); } fg_putc(ztc_textcolor, FG_MODE_SET, ~0, FG_ROT0, ztc_graph_textx, ztc_graph_texty, ch, fg.displaybox); fg_adjustxy(FG_ROT0, 1, &ztc_graph_textx, &ztc_graph_texty, fg.charbox); if (ztc_graph_textx >= MaxX) print_char(stdout,'\n'); } } else disp_putc(ch); } msm_showcursor(); } BOOLEAN cursor_off = 0; void fix_cursor(void) { if (!cursor_off && !in_graphics_mode) { msm_hidecursor(); disp_hidecursor(); msm_showcursor(); cursor_off++; } } void zflush(void) { msm_hidecursor(); if (in_graphics_mode) fg_flush(); else { disp_flush(); if (cursor_off) disp_showcursor(); cursor_off = 0; } msm_showcursor(); } void newline_bugfix(void) { msm_hidecursor(); if (!in_graphics_mode) { if (disp_cursorrow+1 < disp_numrows) new_line(stdout); else disp_move(disp_numrows-1,0); disp_flush(); } msm_showcursor(); y_coord--; } char graph_line_buffer[200]; char *graph_line_pointer = NULL; int ztc_getc(FILE *strm) { int ch; fg_color_t save_textcolor; if (strm != stdin || !interactive || !in_graphics_mode) return getc(strm); if (graph_line_pointer != NULL) { ch = *graph_line_pointer++; if (ch == '\t') graph_line_pointer += 2; if (ch != '\0') return ch; } graph_line_pointer = graph_line_buffer; do { msm_hidecursor(); fg_putc(dull, FG_MODE_XOR, ~0, FG_ROT0, ztc_graph_textx, ztc_graph_texty, '_', fg.displaybox); msm_showcursor(); ch = getch(); msm_hidecursor(); fg_putc(dull, FG_MODE_XOR, ~0, FG_ROT0, ztc_graph_textx, ztc_graph_texty, '_', fg.displaybox); if (ch == '\r' || ch == '\n') { ch = '\n'; *graph_line_pointer++ = ch; print_char(stdout,'\n'); *graph_line_pointer = '\0'; graph_line_pointer = graph_line_buffer; msm_showcursor(); return *graph_line_pointer++; } else if (ch == '\t') { int i = 8 - (x_coord & 07); *graph_line_pointer++ = '\t'; *graph_line_pointer++ = (char)i; *graph_line_pointer++ = '\t'; print_char(stdout, '\t'); } else if (ch == 0177 || ch == '\b') { if (graph_line_pointer != graph_line_buffer) { graph_line_pointer--; if (*graph_line_pointer == '\t') { int i = (int)*--graph_line_pointer; --graph_line_pointer; while (i-- > 0) print_char(stdout, '\b'); } else { print_char(stdout, '\b'); save_textcolor = ztc_textcolor; ztc_textcolor = ztc_text_bgcolor; print_char(stdout, *graph_line_pointer); ztc_textcolor = save_textcolor; print_char(stdout, '\b'); } } } else if (ch == 17 || ch == 23) { print_char(stdout,'\n'); graph_line_pointer = NULL; msm_showcursor(); return ch; } else { *graph_line_pointer++ = ch; print_char(stdout, ch); } msm_showcursor(); } while (ch != '\n'); graph_line_pointer = graph_line_buffer; return *graph_line_pointer++; } void ztc_getcr(void) { (void) ztc_getc(stdin); graph_line_pointer = NULL; } ucblogo-5.5/ztcterm.h0100644000161300001330000001055107550753334012606 0ustar bhdoe/* * ztcterm.h IBM-specific graphics macros mak * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define GR_SIZE 15000 #define prepare_to_draw gr_mode() #define done_drawing nop() #define prepare_to_draw_turtle nop() #define done_drawing_turtle nop() #define screen_left 0 #define screen_right (MaxX) #define screen_top 0 #define screen_bottom (ibm_screen_bottom) #define max_screen_bottom (MaxY) #define screen_height (1 + screen_bottom - screen_top) #define max_screen_height (1 + max_screen_bottom - screen_top) #define screen_width (1 + screen_right - screen_left) #define screen_x_center (screen_left + (screen_width)/2) #define screen_y_center (screen_top + (max_screen_height)/2) #define turtle_left_max ((screen_left) - (screen_x_center)) #define turtle_right_max ((screen_right) - (screen_x_center)) #define turtle_top_max ((screen_y_center) - (screen_top)) #define turtle_bottom_max ((screen_y_center) - (screen_bottom)) #define screen_x_coord ((screen_x_center) + turtle_x) #define screen_y_coord ((screen_y_center) - turtle_y) #define turtle_height t_height() #define turtle_half_bottom t_half_bottom() #define turtle_side t_side() #define clear_screen erase_screen() #define line_to(x,y) {if (current_vis==0) lineto((int)x,(int)y); else moveto((int)x,(int)y);} #define move_to(x,y) moveto((int)x,(int)y) #define draw_string(s) outtext((char *)s) #define set_pen_vis(v) current_vis = v #define set_pen_mode(m) set_ibm_pen_mode(m) #define set_pen_color(c) {ztc_set_penc(c);} #define set_back_ground(c) {ztc_set_bg(c);} #define set_pen_width(w) {ztc_penwidth = w;} #define set_pen_height(h) {ztc_penwidth = h;} #define set_pen_x(x) moveto((int)x, ztc_y) #define set_pen_y(y) moveto(ztc_x, (int)y) /* pen_info is a stucture type with fields for the various pen characteristics including the location, size, color, mode (e.g. XOR or COPY), pattern, visibility (0 = visible) */ typedef struct { int h; int v; int vis; int width; int color; char pattern[8]; int mode; } pen_info; #define p_info_x(p) p.h #define p_info_y(p) p.v #define pen_width ztc_penwidth #define pen_height ztc_penwidth #define pen_mode get_ibm_pen_mode() #define pen_vis current_vis #define pen_x ztc_x #define pen_y ztc_y #define get_node_pen_pattern Get_node_pen_pattern() #define pen_reverse ibm_pen_xor() #define pen_erase ibm_pen_erase() #define pen_down ibm_pen_down() #define button Button() #define mouse_x mickey_x() #define mouse_y mickey_y() #define full_screen f_screen() #define split_screen s_screen() #define text_screen t_screen() /* definitions from term.c and math.c for ibmterm.c */ extern int x_coord, y_coord, x_max, y_max, tty_charmode; extern char so_arr[], se_arr[]; /* definitions from ibmterm.c for graphics.c */ extern void gr_mode(); extern void ibm_pen_erase(), ibm_pen_down(), ibm_pen_xor(); extern void set_ibm_pen_mode(); extern int get_ibm_pen_mode(); extern void save_pen(), restore_pen(), set_pen_pattern(); extern void plain_xor_pen(); extern void set_list_pen_pattern(), get_pen_pattern(), erase_screen(); extern void label(), logofill(); extern void t_screen(), s_screen(), f_screen(), tone(); extern FIXNUM mickey_x(), mickey_y(); extern NODE *Get_node_pen_pattern(); extern FIXNUM t_height(); extern FIXNUM pen_color, back_ground; extern FLONUM t_half_bottom(), t_side(); extern int current_vis, ibm_screen_bottom; extern BOOLEAN in_erase_mode; extern int ztc_penwidth; extern fg_coord_t ztc_x, ztc_y; extern void get_palette(int slot, unsigned int *r, unsigned int *g, unsigned int *b); extern void set_palette(int slot, unsigned int r, unsigned int g, unsigned int b); ucblogo-5.5/libloc.c.unix0100644000161300001330000000026010207172146013320 0ustar bhdoechar *libloc="/usr/local/lib/logo/logolib"; char *helploc="/usr/local/lib/logo/helpfiles"; char *cslsloc="/usr/local/lib/logo/csls"; char *temploc="/tmp"; char *separator="/"; ucblogo-5.5/helpfiles/0040755000161300001330000000000010276165606012717 5ustar bhdoeucblogo-5.5/helpfiles/readword0100644000161300001330000000156610276165605014455 0ustar bhdoeREADWORD RW reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READWORD outputs the empty list (not the empty word). READWORD processes backslash, vertical bar, and tilde characters in the read stream. In the case of a tilde used for line continuation, the output word DOES include the tilde and the newline characters, so that the user program can tell exactly what the user entered. Vertical bars in the line are also preserved in the output. Backslash characters are not preserved in the output, but the character following the backslash has 128 added to its representation. Programs can use BACKSLASHEDP to check for this code. (Backslashedness is preserved only for certain characters. See BACKSLASHEDP.) ucblogo-5.5/helpfiles/arity0100644000161300001330000000040710276165606013770 0ustar bhdoeARITY procedurename outputs a list of three numbers: the minimum, default, and maximum number of inputs for the procedure whose name is the input. It is an error if there is no such procedure. A maximum of -1 means that the number of inputs is unlimited. ucblogo-5.5/helpfiles/dsetsegmentsize0100644000161300001330000000100010276165606016043 0ustar bhdoe.SETSEGMENTSIZE num command. Sets the number of nodes that Logo allocates from the operating system at once to num, which mush be a positive integer. The name is dotted because bad things will happen if you use a number that's too small or too large for your computer. The initial value is 16,000 for most systems, but is smaller for 68000-based Macs. Making it larger will speed up computations (by reducing the number of garbage collections) at the cost of allocating more memory than necessary. ucblogo-5.5/helpfiles/case0100644000161300001330000000147210276165606013556 0ustar bhdoeCASE value clauses (library procedure) command or operation. The second input is a list of lists (clauses); each clause is a list whose first element is either a list of values or the word ELSE and whose butfirst is a Logo expression or instruction. CASE examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. If the first input to CASE is a member of the first element of a clause, then the butfirst of that clause is evaluated and CASE outputs its value, if any. If neither of these conditions is met, then CASE goes on to the next clause. If no clause is satisfied, CASE does nothing. Example: to vowelp :letter output case :letter [ [[a e i o u] "true] [else "false] ] end ucblogo-5.5/helpfiles/cond0100644000161300001330000000202710276165606013563 0ustar bhdoeCOND clauses (library procedure) command or operation. The input is a list of lists (clauses); each clause is a list whose first element is either an expression whose value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo expression or instruction. COND examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. Otherwise, the first element of the clause is evaluated; the resulting value must be TRUE or FALSE. If it's TRUE, then the butfirst of that clause is evaluated and COND outputs its value, if any. If the value is FALSE, then COND goes on to the next clause. If no clause is satisfied, COND does nothing. Example: to evens :numbers ; select even numbers from a list op cond [ [[emptyp :numbers] []] [[evenp first :numbers] ; assuming EVENP is defined fput first :numbers evens butfirst :numbers] [else evens butfirst :numbers] ] end ucblogo-5.5/helpfiles/usealternatenames0100644000161300001330000000022410276165606016355 0ustar bhdoeUSEALTERNATENAMES (variable) if TRUE, causes Logo to generate non-English words (from the Messages file) instead of TRUE, FALSE, END, etc. ucblogo-5.5/helpfiles/mousepos0100644000161300001330000000065710276165606014521 0ustar bhdoeMOUSEPOS outputs the coordinates of the mouse, provided that it's within the graphics window, in turtle coordinates. If the mouse is outside the graphics window, then the last position within the window is returned. Exception: If a mouse button is pressed within the graphics window and held while the mouse is dragged outside the window, the mouse's position is returned as if the window were big enough to include it. ucblogo-5.5/helpfiles/screenmode0100644000161300001330000000015510276165606014764 0ustar bhdoeSCREENMODE outputs the word TEXTSCREEN, SPLITSCREEN, or FULLSCREEN depending on the current screen mode. ucblogo-5.5/helpfiles/turtlemode0100644000161300001330000000013610276165606015023 0ustar bhdoeTURTLEMODE outputs the word WRAP, FENCE, or WINDOW depending on the current turtle mode. ucblogo-5.5/helpfiles/global0100644000161300001330000000104510276165606014077 0ustar bhdoeGLOBAL varname GLOBAL varnamelist (GLOBAL varname1 varname2 ...) command. Accepts as inputs one or more words, or a list of words. A global variable is created for each of these words, with that word as its name. The only reason this is necessary is that you might want to use the "setter" notation SETXYZ for a variable XYZ that does not already have a value; GLOBAL "XYZ makes that legal. Note: If there is currently a local variable of the same name, this command does *not* make Logo use the global value instead of the local one. ucblogo-5.5/helpfiles/seteditor0100644000161300001330000000025310276165606014641 0ustar bhdoeSETEDITOR path command. Tells Logo to use the specified program as its editor instead of the default editor. The format of a path depends on your operating system. ucblogo-5.5/helpfiles/setlibloc0100644000161300001330000000050410276165606014616 0ustar bhdoeSETLIBLOC path command. Tells Logo to use the specified directory as its library instead of the default. (Note that many Logo "primitive" procedures are actually found in the library, so they may become unavailable if your new library does not include them!) The format of a path depends on your operating system. ucblogo-5.5/helpfiles/sethelploc0100644000161300001330000000033110276165606014776 0ustar bhdoeSETHELPLOC path command. Tells Logo to look in the specified directory for the information provided by the HELP command, instead of the default directory. The format of a path depends on your operating system. ucblogo-5.5/helpfiles/settemploc0100644000161300001330000000037010276165606015016 0ustar bhdoeSETTEMPLOC path command. Tells Logo to write editor temporary files in the specified directory rather than in the default directory. You must have write permission for this directory. The format of a path depends on your operating system. ucblogo-5.5/helpfiles/setpalette0100644000161300001330000000076410276165606015020 0ustar bhdoeSETPALETTE colornumber rgblist sets the actual color corresponding to a given number, if allowed by the hardware and operating system. Colornumber must be an integer greater than or equal to 8. (Logo tries to keep the first 8 colors constant.) The second input is a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color. The actual color resolution on any screen is probably less than 64K, but Logo scales as needed. ucblogo-5.5/helpfiles/setpensize0100644000161300001330000000040410276165606015026 0ustar bhdoeSETPENSIZE size sets the thickness of the pen. The input is either a single positive integer or a list of two positive integers (for horizontal and vertical thickness). Some versions pay no attention to the second number, but always have a square pen. ucblogo-5.5/helpfiles/setpenpattern0100644000161300001330000000024210276165606015531 0ustar bhdoeSETPENPATTERN pattern sets hardware-dependent pen characteristics. This command is not guaranteed compatible between implementations on different machines. ucblogo-5.5/helpfiles/setpen0100644000161300001330000000034410276165606014136 0ustar bhdoeSETPEN list (library procedure) sets the pen's position, mode, thickness, and hardware-dependent characteristics according to the information in the input list, which should be taken from an earlier invocation of PEN. ucblogo-5.5/helpfiles/setbackground0100644000161300001330000000024210276165606015470 0ustar bhdoeSETBACKGROUND colornumber.or.rgblist SETBG colornumber.or.rgblist set the screen background color by slot number or RGB values. See SETPENCOLOR for details. ucblogo-5.5/helpfiles/setbg0100644000161300001330000000024210276165606013741 0ustar bhdoeSETBACKGROUND colornumber.or.rgblist SETBG colornumber.or.rgblist set the screen background color by slot number or RGB values. See SETPENCOLOR for details. ucblogo-5.5/helpfiles/pendownp0100644000161300001330000000011010276165606014461 0ustar bhdoePENDOWNP PENDOWN? outputs TRUE if the pen is down, FALSE if it's up. ucblogo-5.5/helpfiles/penmode0100644000161300001330000000014110276165606014262 0ustar bhdoePENMODE outputs one of the words PAINT, ERASE, or REVERSE according to the current pen mode. ucblogo-5.5/helpfiles/pencolor0100644000161300001330000000075110276165606014463 0ustar bhdoePENCOLOR PC outputs a color number, a nonnegative integer that is associated with a particular color, or a list of RGB values if such a list was used as the most recent input to SETPENCOLOR. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. ucblogo-5.5/helpfiles/pc0100644000161300001330000000075110276165606013244 0ustar bhdoePENCOLOR PC outputs a color number, a nonnegative integer that is associated with a particular color, or a list of RGB values if such a list was used as the most recent input to SETPENCOLOR. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. ucblogo-5.5/helpfiles/palette0100644000161300001330000000026510276165606014300 0ustar bhdoePALETTE colornumber outputs a list of three integers, each in the range 0-65535, representing the amount of red, green, and blue in the color associated with the given number. ucblogo-5.5/helpfiles/pensize0100644000161300001330000000027210276165606014315 0ustar bhdoePENSIZE outputs a list of two positive integers, specifying the horizontal and vertical thickness of the turtle pen. (In some implementations the two numbers may always be equal.) ucblogo-5.5/helpfiles/penpattern0100644000161300001330000000007110276165606015015 0ustar bhdoePENPATTERN outputs hardware-specific pen information. ucblogo-5.5/helpfiles/pen0100644000161300001330000000023310276165606013417 0ustar bhdoePEN (library procedure) outputs a list containing the pen's position, mode, thickness, and hardware-specific characteristics, for use by SETPEN. ucblogo-5.5/helpfiles/background0100644000161300001330000000022010276165606014750 0ustar bhdoeBACKGROUND BG outputs the graphics background color, either as a slot number or as an RGB list, whichever way it was set. (See PENCOLOR.) ucblogo-5.5/helpfiles/bg0100644000161300001330000000022010276165606013221 0ustar bhdoeBACKGROUND BG outputs the graphics background color, either as a slot number or as an RGB list, whichever way it was set. (See PENCOLOR.) ucblogo-5.5/helpfiles/savepict0100644000161300001330000000061510276165606014457 0ustar bhdoeSAVEPICT filename command. Writes a file with the specified name containing the state of the graphics window, including any nonstandard color palette settings, in Logo's internal format. This picture can be restored to the screen using LOADPICT. The format is not portable between platforms, nor is it readable by other programs. See EPSPICT to export Logo graphics for other programs. ucblogo-5.5/helpfiles/loadpict0100644000161300001330000000040010276165606014430 0ustar bhdoeLOADPICT filename command. Reads the specified file, which must have been written by a SAVEPICT command, and restores the graphics window and color palette settings to the values stored in the file. Any drawing previously on the screen is cleared. ucblogo-5.5/helpfiles/epspict0100644000161300001330000000061610276165606014311 0ustar bhdoeEPSPICT filename command. Writes a file with the specified name, containing an Encapsulated Postscript (EPS) representation of the state of the graphics window. This file can be imported into other programs that understand EPS format. Restrictions: the drawing cannot use ARC, FILL, PENERASE, or PENREVERSE; any such instructions will be ignored in the translation to Postscript form. ucblogo-5.5/helpfiles/to0100644000161300001330000000725610276165606013273 0ustar bhdoeTO procname :input1 :input2 ... (special form) command. Prepares Logo to accept a procedure definition. The procedure will be named "procname" and there must not already be a procedure by that name. The inputs will be called "input1" etc. Any number of inputs are allowed, including none. Names of procedures and inputs are case-insensitive. Unlike every other Logo procedure, TO takes as its inputs the actual words typed in the instruction line, as if they were all quoted, rather than the results of evaluating expressions to provide the inputs. (That's what "special form" means.) This version of Logo allows variable numbers of inputs to a procedure. After the procedure name come four kinds of things, *in this order*: 1. 0 or more REQUIRED inputs :FOO :FROBOZZ 2. 0 or more OPTIONAL inputs [:BAZ 87] [:THINGO 5+9] 3. 0 or 1 REST input [:GARPLY] 4. 0 or 1 DEFAULT number 5 Every procedure has a MINIMUM, DEFAULT, and MAXIMUM number of inputs. (The latter can be infinite.) The MINIMUM number of inputs is the number of required inputs, which must come first. A required input is indicated by the :inputname notation. After all the required inputs can be zero or more optional inputs, each of which is represented by the following notation: [:inputname default.value.expression] When the procedure is invoked, if actual inputs are not supplied for these optional inputs, the default value expressions are evaluated to set values for the corresponding input names. The inputs are processed from left to right, so a default value expression can be based on earlier inputs. Example: to proc :inlist [:startvalue first :inlist] If the procedure is invoked by saying proc [a b c] then the variable INLIST will have the value [A B C] and the variable STARTVALUE will have the value A. If the procedure is invoked by saying (proc [a b c] "x) then INLIST will have the value [A B C] and STARTVALUE will have the value X. After all the required and optional input can come a single "rest" input, represented by the following notation: [:inputname] This is a rest input rather than an optional input because there is no default value expression. There can be at most one rest input. When the procedure is invoked, the value of this input will be a list containing all of the actual inputs provided that were not used for required or optional inputs. Example: to proc :in1 [:in2 "foo] [:in3 "baz] [:in4] If this procedure is invoked by saying proc "x then IN1 has the value X, IN2 has the value FOO, IN3 has the value BAZ, and IN4 has the value [] (the empty list). If it's invoked by saying (proc "a "b "c "d "e) then IN1 has the value A, IN2 has the value B, IN3 has the value C, and IN4 has the value [D E]. The MAXIMUM number of inputs for a procedure is infinite if a rest input is given; otherwise, it is the number of required inputs plus the number of optional inputs. The DEFAULT number of inputs for a procedure, which is the number of inputs that it will accept if its invocation is not enclosed in parentheses, is ordinarily equal to the minimum number. If you want a different default number you can indicate that by putting the desired default number as the last thing on the TO line. example: to proc :in1 [:in2 "foo] [:in3] 3 This procedure has a minimum of one input, a default of three inputs, and an infinite maximum. Logo responds to the TO command by entering procedure definition mode. The prompt character changes from "?" to ">" and whatever instructions you type become part of the definition until you type a line containing only the word END. ucblogo-5.5/helpfiles/define0100644000161300001330000000147610276165606014101 0ustar bhdoeDEFINE procname text command. Defines a procedure with name "procname" and text "text". If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.) It is an error to redefine a primitive procedure unless the variable REDEFP has the value TRUE. ucblogo-5.5/helpfiles/text0100644000161300001330000000055010276165606013623 0ustar bhdoeTEXT procname outputs the text of the procedure named "procname" in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces. ucblogo-5.5/helpfiles/fulltext0100644000161300001330000000122010276165606014501 0ustar bhdoeFULLTEXT procname outputs a representation of the procedure "procname" in which formatting information is preserved. If the procedure was defined with TO, EDIT, or LOAD, then the output is a list of words. Each word represents one entire line of the definition in the form output by READWORD, including extra spaces and continuation lines. The last member of the output represents the END line. If the procedure was defined with DEFINE, then the output is a list of lists. If these lists are printed, one per line, the result will look like a definition using TO. Note: the output from FULLTEXT is not suitable for use as input to DEFINE! ucblogo-5.5/helpfiles/copydef0100644000161300001330000000066210276165606014274 0ustar bhdoeCOPYDEF newname oldname command. Makes "newname" a procedure identical to "oldname". The latter may be a primitive. If "newname" was already defined, its previous definition is lost. If "newname" was already a primitive, the redefinition is not permitted unless the variable REDEFP has the value TRUE. Note: dialects of Logo differ as to the order of inputs to COPYDEF. This dialect uses "MAKE order," not "NAME order." ucblogo-5.5/helpfiles/make0100644000161300001330000000043610276165606013557 0ustar bhdoeMAKE varname value command. Assigns the value "value" to the variable named "varname", which must be a word. Variable names are case-insensitive. If a variable with the same name already exists, the value of that variable is changed. If not, a new global variable is created. ucblogo-5.5/helpfiles/name0100644000161300001330000000015310276165606013556 0ustar bhdoeNAME value varname (library procedure) command. Same as MAKE but with the inputs in reverse order. ucblogo-5.5/helpfiles/local0100644000161300001330000000107610276165606013735 0ustar bhdoeLOCAL varname LOCAL varnamelist (LOCAL varname1 varname2 ...) command. Accepts as inputs one or more words, or a list of words. A variable is created for each of these words, with that word as its name. The variables are local to the currently running procedure. Logo variables follow dynamic scope rules; a variable that is local to a procedure is available to any subprocedure invoked by that procedure. The variables created by LOCAL have no initial value; they must be assigned a value (e.g., with MAKE) before the procedure attempts to read their value. ucblogo-5.5/helpfiles/localmake0100644000161300001330000000022410276165606014565 0ustar bhdoeLOCALMAKE varname value (library procedure) command. Makes the named variable local, like LOCAL, and assigns it the given value, like MAKE. ucblogo-5.5/helpfiles/thing0100644000161300001330000000047010276165606013751 0ustar bhdoeTHING varname :quoted.varname outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination thing " so that :FOO means THING "FOO. ucblogo-5.5/helpfiles/pprop0100644000161300001330000000020610276165606013775 0ustar bhdoePPROP plistname propname value command. Adds a property to the "plistname" property list with name "propname" and value "value". ucblogo-5.5/helpfiles/gprop0100644000161300001330000000023410276165606013765 0ustar bhdoeGPROP plistname propname outputs the value of the "propname" property in the "plistname" property list, or the empty list if there is no such property. ucblogo-5.5/helpfiles/remprop0100644000161300001330000000017110276165606014322 0ustar bhdoeREMPROP plistname propname command. Removes the property named "propname" from the property list named "plistname". ucblogo-5.5/helpfiles/plist0100644000161300001330000000050210276165606013767 0ustar bhdoePLIST plistname outputs a list whose odd-numbered members are the names, and whose even-numbered members are the values, of the properties in the property list named "plistname". The output is a copy of the actual property list; changing properties later will not magically change a list output earlier by PLIST. ucblogo-5.5/helpfiles/procedurep0100644000161300001330000000013110276165606015002 0ustar bhdoePROCEDUREP name PROCEDURE? name outputs TRUE if the input is the name of a procedure. ucblogo-5.5/helpfiles/primitivep0100644000161300001330000000034010276165606015024 0ustar bhdoePRIMITIVEP name PRIMITIVE? name outputs TRUE if the input is the name of a primitive procedure (one built into Logo). Note that some of the procedures described in this document are library procedures, not primitives. ucblogo-5.5/helpfiles/definedp0100644000161300001330000000034310276165606014415 0ustar bhdoeDEFINEDP name DEFINED? name outputs TRUE if the input is the name of a user-defined procedure, including a library procedure. (However, Logo does not know about a library procedure until that procedure has been invoked.) ucblogo-5.5/helpfiles/namep0100644000161300001330000000011610276165606013735 0ustar bhdoeNAMEP name NAME? name outputs TRUE if the input is the name of a variable. ucblogo-5.5/helpfiles/contents0100644000161300001330000000033110276165606014471 0ustar bhdoeCONTENTS outputs a "contents list," i.e., a list of three lists containing names of defined procedures, variables, and property lists respectively. This list includes all unburied named items in the workspace. ucblogo-5.5/helpfiles/buried0100644000161300001330000000012610276165606014110 0ustar bhdoeBURIED outputs a contents list including all buried named items in the workspace. ucblogo-5.5/helpfiles/procedures0100644000161300001330000000036410276165606015015 0ustar bhdoePROCEDURES outputs a list of the names of all unburied user-defined procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.) ucblogo-5.5/helpfiles/names0100644000161300001330000000024310276165606013741 0ustar bhdoeNAMES outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace. ucblogo-5.5/helpfiles/plists0100644000161300001330000000026710276165606014162 0ustar bhdoePLISTS outputs a contents list consisting of two empty lists (indicating no procedures or variables) followed by a list of all unburied nonempty property lists in the workspace. ucblogo-5.5/helpfiles/namelist0100644000161300001330000000043010276165606014450 0ustar bhdoeNAMELIST varname (library procedure) NAMELIST varnamelist outputs a contents list consisting of an empty list followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. ucblogo-5.5/helpfiles/pllist0100644000161300001330000000042610276165606014150 0ustar bhdoePLLIST plname (library procedure) PLLIST plnamelist outputs a contents list consisting of two empty lists followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. ucblogo-5.5/helpfiles/nodes0100644000161300001330000000146310276165606013753 0ustar bhdoeNODES outputs a list of two numbers. The first represents the number of nodes of memory currently in use. The second shows the maximum number of nodes that have been in use at any time since the last invocation of NODES. (A node is a small block of computer memory as used by Logo. Each number uses one node. Each non-numeric word uses one node, plus some non-node memory for the characters in the word. Each array takes one node, plus some non-node memory, as well as the memory required by its elements. Each list requires one node per element, as well as the memory within the elements.) If you want to track the memory use of an algorithm, it is best if you invoke GC at the beginning of each iteration, since otherwise the maximum will include storage that is unused but not yet collected. ucblogo-5.5/helpfiles/po0100644000161300001330000000026310276165606013256 0ustar bhdoePRINTOUT contentslist PO contentslist command. Prints to the write stream the definitions of all procedures, variables, and property lists named in the input contents list. ucblogo-5.5/helpfiles/poall0100644000161300001330000000017110276165606013745 0ustar bhdoePOALL (library procedure) command. Prints all unburied definitions in the workspace. Abbreviates PO CONTENTS. ucblogo-5.5/helpfiles/pops0100644000161300001330000000021510276165606013616 0ustar bhdoePOPS (library procedure) command. Prints the definitions of all unburied procedures in the workspace. Abbreviates PO PROCEDURES. ucblogo-5.5/helpfiles/pons0100644000161300001330000000020710276165606013615 0ustar bhdoePONS (library procedure) command. Prints the definitions of all unburied variables in the workspace. Abbreviates PO NAMES. ucblogo-5.5/helpfiles/popls0100644000161300001330000000022410276165606013772 0ustar bhdoePOPLS (library procedure) command. Prints the contents of all unburied nonempty property lists in the workspace. Abbreviates PO PLISTS. ucblogo-5.5/helpfiles/pon0100644000161300001330000000023310276165606013431 0ustar bhdoePON varname (library procedure) PON varnamelist command. Prints the definitions of the named variable(s). Abbreviates PO NAMELIST varname(list). ucblogo-5.5/helpfiles/popl0100644000161300001330000000023510276165606013611 0ustar bhdoePOPL plname (library procedure) POPL plnamelist command. Prints the definitions of the named property list(s). Abbreviates PO PLLIST plname(list). ucblogo-5.5/helpfiles/pot0100644000161300001330000000037710276165606013450 0ustar bhdoePOT contentslist command. Prints the title lines of the named procedures and the definitions of the named variables and property lists. For property lists, the entire list is shown on one line instead of as a series of PPROP instructions as in PO. ucblogo-5.5/helpfiles/random0100644000161300001330000000067410276165605014125 0ustar bhdoeRANDOM num (RANDOM start end) with one input, outputs a random nonnegative integer less than its input, which must be a positive integer. With two inputs, RANDOM outputs a random integer greater than or equal to the first input, and less than or equal to the second input. Both inputs must be integers, and the first must be less than the second. (RANDOM 0 9) is equivalent to RANDOM 10; (RANDOM 3 8) is equivalent to (RANDOM 6)+3. ucblogo-5.5/helpfiles/buriedp0100644000161300001330000000057610276165606014301 0ustar bhdoeBURIEDP contentslist BURIED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is buried, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can BURIEDP [[] [VARIABLE]] or BURIEDP [[] [] [PROPLIST]]. ucblogo-5.5/helpfiles/steppedp0100644000161300001330000000060310276165606014462 0ustar bhdoeSTEPPEDP contentslist STEPPED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is stepped, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can STEPPEDP [[] [VARIABLE]] or STEPPEDP [[] [] [PROPLIST]]. ucblogo-5.5/helpfiles/tracedp0100644000161300001330000000057610276165606014271 0ustar bhdoeTRACEDP contentslist TRACED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is traced, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can TRACEDP [[] [VARIABLE]] or TRACEDP [[] [] [PROPLIST]]. ucblogo-5.5/helpfiles/fullprintp0100644000161300001330000000067310276165606015044 0ustar bhdoeFULLPRINTP (variable) if TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.) ucblogo-5.5/helpfiles/allowgetset0100644000161300001330000000043710276165606015175 0ustar bhdoeALLOWGETSET (variable) if TRUE, indicates that an attempt to use a procedure that doesn't exist should be taken as an implicit getter or setter procedure (setter if the first three letters of the name are SET) for a variable of the same name (without the SET if appropriate). ucblogo-5.5/helpfiles/unburyonedit0100644000161300001330000000033710276165606015371 0ustar bhdoeUNBURYONEDIT (variable) if TRUE, causes any procedure defined during EDIT or LOAD to be unburied, so that it will be saved by a later SAVE. Files that want to define and bury procedures must do it in that order. ucblogo-5.5/helpfiles/plistp0100644000161300001330000000042610276165606014154 0ustar bhdoePLISTP name PLIST? name outputs TRUE if the input is the name of a *nonempty* property list. (In principle every word is the name of a property list; if you haven't put any properties in it, PLIST of that name outputs an empty list, rather than giving an error message.) ucblogo-5.5/helpfiles/ern0100644000161300001330000000025410276165606013424 0ustar bhdoeERN varname (library procedure) ERN varnamelist command. Erases from the workspace the variable(s) named in the input. Abbreviates ERASE NAMELIST varname(list). ucblogo-5.5/helpfiles/erpl0100644000161300001330000000025610276165606013604 0ustar bhdoeERPL plname (library procedure) ERPL plnamelist command. Erases from the workspace the property list(s) named in the input. Abbreviates ERASE PLLIST plname(list). ucblogo-5.5/helpfiles/bury0100644000161300001330000000050710276165606013622 0ustar bhdoeBURY contentslist command. Buries the procedures, variables, and property lists named in the input. A buried item is not included in the lists output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is included in the list output by BURIED. By implication, buried things are not printed by POALL or saved by SAVE. ucblogo-5.5/helpfiles/buryall0100644000161300001330000000011210276165606014303 0ustar bhdoeBURYALL (library procedure) command. Abbreviates BURY CONTENTS. ucblogo-5.5/helpfiles/buryname0100644000161300001330000000016410276165606014462 0ustar bhdoeBURYNAME varname (library procedure) BURYNAME varnamelist command. Abbreviates BURY NAMELIST varname(list). ucblogo-5.5/helpfiles/unbury0100644000161300001330000000026310276165606014164 0ustar bhdoeUNBURY contentslist command. Unburies the procedures, variables, and property lists named in the input. That is, the named items will be returned to view in CONTENTS, etc. ucblogo-5.5/helpfiles/unburyall0100644000161300001330000000011310276165606014647 0ustar bhdoeUNBURYALL (library procedure) command. Abbreviates UNBURY BURIED. ucblogo-5.5/helpfiles/unburyname0100644000161300001330000000017210276165606015024 0ustar bhdoeUNBURYNAME varname (library procedure) UNBURYNAME varnamelist command. Abbreviates UNBURY NAMELIST varname(list). ucblogo-5.5/helpfiles/trace0100644000161300001330000000061610276165606013740 0ustar bhdoeTRACE contentslist command. Marks the named items for tracing. A message is printed whenever a traced procedure is invoked, giving the actual input values, and whenever a traced procedure STOPs or OUTPUTs. A message is printed whenever a new value is assigned to a traced variable using MAKE. A message is printed whenever a new property is given to a traced property list using PPROP. ucblogo-5.5/helpfiles/untrace0100644000161300001330000000011110276165606014271 0ustar bhdoeUNTRACE contentslist command. Turns off tracing for the named items. ucblogo-5.5/helpfiles/step0100644000161300001330000000065710276165606013622 0ustar bhdoeSTEP contentslist command. Marks the named items for stepping. Whenever a stepped procedure is invoked, each instruction line in the procedure body is printed before being executed, and Logo waits for the user to type a newline at the terminal. A message is printed whenever a stepped variable name is "shadowed" because a local variable of the same name is created either as a procedure input or by the LOCAL command. ucblogo-5.5/helpfiles/unstep0100644000161300001330000000011110276165606014146 0ustar bhdoeUNSTEP contentslist command. Turns off stepping for the named items. ucblogo-5.5/helpfiles/edit0100644000161300001330000000233510276165606013567 0ustar bhdoeEDIT contentslist ED contentslist (EDIT) (ED) command. If invoked with an input, EDIT writes the definitions of the named items into a temporary file and edits that file, using your favorite editor as determined by the EDITOR environment variable. If you don't have an EDITOR variable, edits the definitions using jove. If invoked without an input, EDIT edits the same file left over from a previous EDIT or EDITFILE instruction. When you leave the editor, Logo reads the revised definitions and modifies the workspace accordingly. It is not an error if the input includes names for which there is no previous definition. If there is a variable LOADNOISILY whose value is TRUE, then, after leaving the editor, TO commands in the temporary file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. If there is an environment variable called TEMP, then Logo uses its value as the directory in which to write the temporary file used for editing. Exceptionally, the EDIT command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. ucblogo-5.5/helpfiles/ed0100644000161300001330000000233510276165606013232 0ustar bhdoeEDIT contentslist ED contentslist (EDIT) (ED) command. If invoked with an input, EDIT writes the definitions of the named items into a temporary file and edits that file, using your favorite editor as determined by the EDITOR environment variable. If you don't have an EDITOR variable, edits the definitions using jove. If invoked without an input, EDIT edits the same file left over from a previous EDIT or EDITFILE instruction. When you leave the editor, Logo reads the revised definitions and modifies the workspace accordingly. It is not an error if the input includes names for which there is no previous definition. If there is a variable LOADNOISILY whose value is TRUE, then, after leaving the editor, TO commands in the temporary file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. If there is an environment variable called TEMP, then Logo uses its value as the directory in which to write the temporary file used for editing. Exceptionally, the EDIT command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. ucblogo-5.5/helpfiles/editfile0100644000161300001330000000103210276165606014420 0ustar bhdoeEDITFILE filename command. Starts the Logo editor, like EDIT, but instead of editing a temporary file it edits the file specified by the input. When you leave the editor, Logo reads the revised file, as for EDIT. EDITFILE also remembers the filename, so that a subsequent EDIT command with no input will re-edit the same file. EDITFILE is intended as an alternative to LOAD and SAVE. You can maintain a workspace file yourself, controlling the order in which definitions appear, maintaining comments in the file, and so on. ucblogo-5.5/helpfiles/edall0100644000161300001330000000011010276165606013710 0ustar bhdoeEDALL (library procedure) command. Abbreviates EDIT CONTENTS. ucblogo-5.5/helpfiles/edps0100644000161300001330000000011110276165606013563 0ustar bhdoeEDPS (library procedure) command. Abbreviates EDIT PROCEDURES. ucblogo-5.5/helpfiles/edns0100644000161300001330000000010410276165606013563 0ustar bhdoeEDNS (library procedure) command. Abbreviates EDIT NAMES. ucblogo-5.5/helpfiles/edpls0100644000161300001330000000010610276165606013743 0ustar bhdoeEDPLS (library procedure) command. Abbreviates EDIT PLISTS. ucblogo-5.5/helpfiles/edn0100644000161300001330000000015310276165606013404 0ustar bhdoeEDN varname (library procedure) EDN varnamelist command. Abbreviates EDIT NAMELIST varname(list). ucblogo-5.5/helpfiles/edpl0100644000161300001330000000015010276165606013557 0ustar bhdoeEDPL plname (library procedure) EDPL plnamelist command. Abbreviates EDIT PLLIST plname(list). ucblogo-5.5/helpfiles/save0100644000161300001330000000050210276165606013572 0ustar bhdoeSAVE filename command. Saves the definitions of all unburied procedures, variables, and nonempty property lists in the named file. Equivalent to to save :filename local "oldwriter make "oldwriter writer openwrite :filename setwrite :filename poall setwrite :oldwriter close :filename end ucblogo-5.5/helpfiles/savel0100644000161300001330000000030310276165606013745 0ustar bhdoeSAVEL contentslist filename (library procedure) command. Saves the definitions of the procedures, variables, and property lists specified by "contentslist" to the file named "filename". ucblogo-5.5/helpfiles/load0100644000161300001330000000115010276165606013553 0ustar bhdoeLOAD filename command. Reads instructions from the named file and executes them. The file can include procedure definitions with TO, and these are accepted even if a procedure by the same name already exists. If the file assigns a list value to a variable named STARTUP, then that list is run as an instructionlist after the file is loaded. If there is a variable LOADNOISILY whose value is TRUE, then TO commands in the file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. ucblogo-5.5/helpfiles/help0100644000161300001330000000140110276165606013563 0ustar bhdoeHELP name (HELP) command. Prints information from the reference manual about the primitive procedure named by the input. With no input, lists all the primitives about which help is available. If there is an environment variable LOGOHELP, then its value is taken as the directory in which to look for help files, instead of the default help directory. If HELP is called with the name of a defined procedure for which there is no help file, it will print the title line of the procedure followed by lines from the procedure body that start with semicolon, stopping when a non-semicolon line is seen. Exceptionally, the HELP command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. ucblogo-5.5/helpfiles/gc0100644000161300001330000000164610276165606013237 0ustar bhdoeGC (GC anything) command. Runs the garbage collector, reclaiming unused nodes. Logo does this when necessary anyway, but you may want to use this command to control exactly when Logo does it. In particular, the numbers output by the NODES operation will not be very meaningful unless garbage has been collected. Another reason to use GC is that a garbage collection takes a noticeable fraction of a second, and you may want to schedule collections for times before or after some time-critical animation. If invoked with an input (of any value), GC runs a full garbage collection, including GCTWA (Garbage Collect Truly Worthless Atoms, which means that it removes from Logo's memory words that used to be procedure or variable names but aren't any more); without an input, GC does a generational garbage collection, which means that only recently created nodes are examined. (The latter is usually good enough.) ucblogo-5.5/helpfiles/run0100644000161300001330000000022610276165606013443 0ustar bhdoeRUN instructionlist command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs. ucblogo-5.5/helpfiles/runresult0100644000161300001330000000057310276165606014707 0ustar bhdoeRUNRESULT instructionlist runs the instructions in the input; outputs an empty list if those instructions produce no output, or a list whose only member is the output from running the input instructionlist. Useful for inventing command-or-operation control structures: local "result make "result runresult [something] if emptyp :result [stop] output first :result ucblogo-5.5/helpfiles/repeat0100644000161300001330000000013410276165606014115 0ustar bhdoeREPEAT num instructionlist command. Runs the "instructionlist" repeatedly, "num" times. ucblogo-5.5/helpfiles/forever0100644000161300001330000000023710276165606014311 0ustar bhdoeFOREVER instructionlist command. Runs the "instructionlist" repeatedly, until something inside the instructionlist (such as STOP or THROW) makes it stop. ucblogo-5.5/helpfiles/repcount0100644000161300001330000000023010276165606014471 0ustar bhdoeREPCOUNT outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs -1. ucblogo-5.5/helpfiles/if0100644000161300001330000000143510276165606013240 0ustar bhdoeIF tf instructionlist (IF tf instructionlist1 instructionlist2) command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE. For compatibility with earlier versions of Logo, if an IF instruction is not enclosed in parentheses, but the first thing on the instruction line after the second input expression is a literal list (i.e., a list in square brackets), the IF is treated as if it were IFELSE, but a warning message is given. If this aberrant IF appears in a procedure body, the warning is given only the first time the procedure is invoked in each Logo session. ucblogo-5.5/helpfiles/ifelse0100644000161300001330000000047210276165606014111 0ustar bhdoeIFELSE tf instructionlist1 instructionlist2 command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value. ucblogo-5.5/helpfiles/test0100644000161300001330000000042310276165606013615 0ustar bhdoeTEST tf command. Remembers its input, which must be TRUE or FALSE, for use by later IFTRUE or IFFALSE instructions. The effect of TEST is local to the procedure in which it is used; any corresponding IFTRUE or IFFALSE must be in the same procedure or a subprocedure. ucblogo-5.5/helpfiles/iftrue0100644000161300001330000000030310276165606014131 0ustar bhdoeIFTRUE instructionlist IFT instructionlist command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure. ucblogo-5.5/helpfiles/ift0100644000161300001330000000030310276165606013415 0ustar bhdoeIFTRUE instructionlist IFT instructionlist command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure. ucblogo-5.5/helpfiles/iffalse0100644000161300001330000000030510276165606014246 0ustar bhdoeIFFALSE instructionlist IFF instructionlist command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure. ucblogo-5.5/helpfiles/iff0100644000161300001330000000030510276165606013401 0ustar bhdoeIFFALSE instructionlist IFF instructionlist command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure. ucblogo-5.5/helpfiles/stop0100644000161300001330000000030310276165606013620 0ustar bhdoeSTOP command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value. ucblogo-5.5/helpfiles/output0100644000161300001330000000042510276165606014200 0ustar bhdoeOUTPUT value OP value command. Ends the running of the procedure in which it appears. That procedure outputs the value "value" to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation. ucblogo-5.5/helpfiles/op0100644000161300001330000000042510276165606013256 0ustar bhdoeOUTPUT value OP value command. Ends the running of the procedure in which it appears. That procedure outputs the value "value" to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation. ucblogo-5.5/helpfiles/catch0100644000161300001330000000172010276165606013721 0ustar bhdoeCATCH tag instructionlist command or operation. Runs its second input. Outputs if that instructionlist outputs. If, while running the instructionlist, a THROW instruction is executed with a tag equal to the first input (case-insensitive comparison), then the running of the instructionlist is terminated immediately. In this case the CATCH outputs if a value input is given to THROW. The tag must be a word. If the tag is the word ERROR, then any error condition that arises during the running of the instructionlist has the effect of THROW "ERROR instead of printing an error message and returning to toplevel. The CATCH does not output if an error is caught. Also, during the running of the instructionlist, the variable ERRACT is temporarily unbound. (If there is an error while ERRACT has a value, that value is taken as an instructionlist to be run after printing the error message. Typically the value of ERRACT, if any, is the list [PAUSE].) ucblogo-5.5/helpfiles/throw0100644000161300001330000000302010276165606013775 0ustar bhdoeTHROW tag (THROW tag value) command. Must be used within the scope of a CATCH with an equal tag. Ends the running of the instructionlist of the CATCH. If THROW is used with only one input, the corresponding CATCH does not output a value. If THROW is used with two inputs, the second provides an output for the CATCH. THROW "TOPLEVEL can be used to terminate all running procedures and interactive pauses, and return to the toplevel instruction prompt. Typing the system interrupt character (normally control-C for Unix, control-Q for DOS, or command-period for Mac) has the same effect. THROW "ERROR can be used to generate an error condition. If the error is not caught, it prints a message (THROW "ERROR) with the usual indication of where the error (in this case the THROW) occurred. If a second input is used along with a tag of ERROR, that second input is used as the text of the error message instead of the standard message. Also, in this case, the location indicated for the error will be, not the location of the THROW, but the location where the procedure containing the THROW was invoked. This allows user-defined procedures to generate error messages as if they were primitives. Note: in this case the corresponding CATCH "ERROR, if any, does not output, since the second input to THROW is not considered a return value. THROW "SYSTEM immediately leaves Logo, returning to the operating system, without printing the usual parting message and without deleting any editor temporary file written by EDIT. ucblogo-5.5/helpfiles/error0100644000161300001330000000061410276165606013771 0ustar bhdoeERROR outputs a list describing the error just caught, if any. If there was not an error caught since the last use of ERROR, the empty list will be output. The error list contains four members: an integer code corresponding to the type of error, the text of the error message, the name of the procedure in which the error occurred, and the instruction line on which the error occurred. ucblogo-5.5/helpfiles/pause0100644000161300001330000000144310276165606013756 0ustar bhdoePAUSE command or operation. Enters an interactive pause. The user is prompted for instructions, as at toplevel, but with a prompt that includes the name of the procedure in which PAUSE was invoked. Local variables of that procedure are available during the pause. PAUSE outputs if the pause is ended by a CONTINUE with an input. If the variable ERRACT exists, and an error condition occurs, the contents of that variable are run as an instructionlist. Typically ERRACT is given the value [PAUSE] so that an interactive pause will be entered on the event of an error. This allows the user to check values of local variables at the time of the error. Typing the system quit character (normally control-\ for Unix, control-W for DOS, or command-comma for Mac) will also enter a pause. ucblogo-5.5/helpfiles/continue0100644000161300001330000000066010276165606014465 0ustar bhdoeCONTINUE value CO value (CONTINUE) (CO) command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output. Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. ucblogo-5.5/helpfiles/co0100644000161300001330000000066010276165606013242 0ustar bhdoeCONTINUE value CO value (CONTINUE) (CO) command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output. Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. ucblogo-5.5/helpfiles/wait0100644000161300001330000000037010276165606013603 0ustar bhdoeWAIT time command. Delays further execution for "time" 60ths of a second. Also causes any buffered characters destined for the terminal to be printed immediately. WAIT 0 can be used to achieve this buffer flushing without actually waiting. ucblogo-5.5/helpfiles/bye0100644000161300001330000000010310276165606013410 0ustar bhdoeBYE command. Exits from Logo; returns to the operating system. ucblogo-5.5/helpfiles/dmaybeoutput0100644000161300001330000000137310276165606015365 0ustar bhdoe.MAYBEOUTPUT value (special form) works like OUTPUT except that the expression that provides the input value might not, in fact, output a value, in which case the effect is like STOP. This is intended for use in control structure definitions, for cases in which you don't know whether or not some expression produces a value. Example: to invoke :function [:inputs] 2 .maybeoutput apply :function :inputs end ? (invoke "print "a "b "c) a b c ? print (invoke "word "a "b "c) abc This is an alternative to RUNRESULT. It's fast and easy to use, at the cost of being an exception to Logo's evaluation rules. (Ordinarily, it should be an error if the expression that's supposed to provide an input to something doesn't have a value.) ucblogo-5.5/helpfiles/goto0100644000161300001330000000032610276165606013610 0ustar bhdoeGOTO word command. Looks for a TAG command with the same input in the same procedure, and continues running the procedure from the location of that TAG. It is meaningless to use GOTO outside of a procedure. ucblogo-5.5/helpfiles/tag0100644000161300001330000000026410276165606013414 0ustar bhdoeTAG quoted.word command. Does nothing. The input must be a literal word following a quotation mark ("), not the result of a computation. Tags are used by the GOTO command. ucblogo-5.5/helpfiles/ignore0100644000161300001330000000023710276165606014124 0ustar bhdoeIGNORE value (library procedure) command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant. ucblogo-5.5/helpfiles/word0100644000161300001330000000014410276165605013610 0ustar bhdoeWORD word1 word2 (WORD word1 word2 word3 ...) outputs a word formed by concatenating its inputs. ucblogo-5.5/helpfiles/list0100644000161300001330000000023010276165605013604 0ustar bhdoeLIST thing1 thing2 (LIST thing1 thing2 thing3 ...) outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array). ucblogo-5.5/helpfiles/sentence0100644000161300001330000000036310276165605014444 0ustar bhdoeSENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...) outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists. ucblogo-5.5/helpfiles/se0100644000161300001330000000036310276165605013247 0ustar bhdoeSENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...) outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists. ucblogo-5.5/helpfiles/fput0100644000161300001330000000035110276165605013613 0ustar bhdoeFPUT thing list outputs a list equal to its second input with one extra member, the first input, at the beginning. If the second input is a word, then the first input must be a one-letter word, and FPUT is equivalent to WORD. ucblogo-5.5/helpfiles/lput0100644000161300001330000000040610276165605013622 0ustar bhdoeLPUT thing list outputs a list equal to its second input with one extra member, the first input, at the end. If the second input is a word, then the first input must be a one-letter word, and LPUT is equivalent to WORD with its inputs in the other order. ucblogo-5.5/helpfiles/array0100644000161300001330000000106410276165605013755 0ustar bhdoeARRAY size (ARRAY size origin) outputs an array of "size" members (must be a positive integer), each of which initially is an empty list. Array members can be selected with ITEM and changed with SETITEM. The first member of the array is member number 1 unless an "origin" input (must be an integer) is given, in which case the first member of the array has that number as its index. (Typically 0 is used as the origin if anything.) Arrays are printed by PRINT and friends, and can be typed in, inside curly braces; indicate an origin with {a b c}@0. ucblogo-5.5/helpfiles/mdarray0100644000161300001330000000056410276165605014302 0ustar bhdoeMDARRAY sizelist (library procedure) (MDARRAY sizelist origin) outputs a multi-dimensional array. The first input must be a list of one or more positive integers. The second input, if present, must be a single integer that applies to every dimension of the array. Ex: (MDARRAY [3 5] 0) outputs a two-dimensional array whose members range from [0 0] to [2 4]. ucblogo-5.5/helpfiles/listtoarray0100644000161300001330000000022510276165605015212 0ustar bhdoeLISTTOARRAY list (LISTTOARRAY list origin) outputs an array of the same size as the input list, whose members are the members of the input list. ucblogo-5.5/helpfiles/arraytolist0100644000161300001330000000027310276165605015215 0ustar bhdoeARRAYTOLIST array outputs a list whose members are the members of the input array. The first member of the output is the first member of the array, regardless of the array's origin. ucblogo-5.5/helpfiles/combine0100644000161300001330000000022510276165605014251 0ustar bhdoeCOMBINE thing1 thing2 (library procedure) if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2. ucblogo-5.5/helpfiles/reverse0100644000161300001330000000017410276165605014313 0ustar bhdoeREVERSE list (library procedure) outputs a list whose members are the members of the input list, in reverse order. ucblogo-5.5/helpfiles/gensym0100644000161300001330000000017410276165605014142 0ustar bhdoeGENSYM (library procedure) outputs a unique word each time it's invoked. The words are of the form G1, G2, etc. ucblogo-5.5/helpfiles/first0100644000161300001330000000040210276165605013761 0ustar bhdoeFIRST thing if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array). ucblogo-5.5/helpfiles/firsts0100644000161300001330000000061410276165605014151 0ustar bhdoeFIRSTS list outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as to firsts :list output map "first :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. ucblogo-5.5/helpfiles/last0100644000161300001330000000022110276165605013574 0ustar bhdoeLAST wordorlist if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list. ucblogo-5.5/helpfiles/butfirst0100644000161300001330000000033510276165605014501 0ustar bhdoeBUTFIRST wordorlist BF wordorlist if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input. ucblogo-5.5/helpfiles/bf0100644000161300001330000000033510276165605013226 0ustar bhdoeBUTFIRST wordorlist BF wordorlist if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input. ucblogo-5.5/helpfiles/butfirsts0100644000161300001330000000065710276165605014673 0ustar bhdoeBUTFIRSTS list BFS list outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as to butfirsts :list output map "butfirst :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. ucblogo-5.5/helpfiles/bfs0100644000161300001330000000065710276165605013420 0ustar bhdoeBUTFIRSTS list BFS list outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as to butfirsts :list output map "butfirst :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. ucblogo-5.5/helpfiles/butlast0100644000161300001330000000033210276165605014312 0ustar bhdoeBUTLAST wordorlist BL wordorlist if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input. ucblogo-5.5/helpfiles/bl0100644000161300001330000000033210276165605013231 0ustar bhdoeBUTLAST wordorlist BL wordorlist if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input. ucblogo-5.5/helpfiles/item0100644000161300001330000000053610276165605013600 0ustar bhdoeITEM index thing if the "thing" is a word, outputs the "index"th character of the word. If the "thing" is a list, outputs the "index"th member of the list. If the "thing" is an array, outputs the "index"th member of the array. "Index" starts at 1 for words and lists; the starting index of an array is specified when the array is created. ucblogo-5.5/helpfiles/mditem0100644000161300001330000000022310276165605014112 0ustar bhdoeMDITEM indexlist array (library procedure) outputs the member of the multidimensional "array" selected by the list of numbers "indexlist". ucblogo-5.5/helpfiles/pick0100644000161300001330000000013210276165605013560 0ustar bhdoePICK list (library procedure) outputs a randomly chosen member of the input list. ucblogo-5.5/helpfiles/remove0100644000161300001330000000016210276165605014132 0ustar bhdoeREMOVE thing list (library procedure) outputs a copy of "list" with every member equal to "thing" removed. ucblogo-5.5/helpfiles/remdup0100644000161300001330000000033110276165605014127 0ustar bhdoeREMDUP list (library procedure) outputs a copy of "list" with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output. ucblogo-5.5/helpfiles/quoted0100644000161300001330000000020710276165605014136 0ustar bhdoeQUOTED thing (library procedure) outputs its input, if a list; outputs its input with a quotation mark prepended, if a word. ucblogo-5.5/helpfiles/setitem0100644000161300001330000000033310276165605014307 0ustar bhdoeSETITEM index array value command. Replaces the "index"th member of "array" with the new "value". Ensures that the resulting array is not circular, i.e., "value" may not be a list or array that contains "array". ucblogo-5.5/helpfiles/mdsetitem0100644000161300001330000000022010276165605014623 0ustar bhdoeMDSETITEM indexlist array value (library procedure) command. Replaces the member of "array" chosen by "indexlist" with the new "value". ucblogo-5.5/helpfiles/dsetfirst0100644000161300001330000000073010276165605014645 0ustar bhdoe.SETFIRST list value command. Changes the first member of "list" to be "value". WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; and the loss of memory if a circular structure is released. ucblogo-5.5/helpfiles/dsetbf0100644000161300001330000000103210276165605014101 0ustar bhdoe.SETBF list value command. Changes the butfirst of "list" to be "value". WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; Logo crashes and coredumps if the butfirst of a list is not itself a list; and the loss of memory if a circular structure is released. ucblogo-5.5/helpfiles/dsetitem0100644000161300001330000000066010276165605014456 0ustar bhdoe.SETITEM index array value command. Changes the "index"th member of "array" to be "value", like SETITEM, but without checking for circularity. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETITEM can lead to circular arrays, which will get some Logo primitives into infinite loops; and the loss of memory if a circular structure is released. ucblogo-5.5/helpfiles/push0100644000161300001330000000044310276165605013616 0ustar bhdoePUSH stackname thing (library procedure) command. Adds the "thing" to the stack that is the value of the variable whose name is "stackname". This variable must have a list as its value; the initial value should be the empty list. New members are added at the front of the list. ucblogo-5.5/helpfiles/pop0100644000161300001330000000030510276165605013432 0ustar bhdoePOP stackname (library procedure) outputs the most recently PUSHed member of the stack that is the value of the variable whose name is "stackname" and removes that member from the stack. ucblogo-5.5/helpfiles/queue0100644000161300001330000000044310276165605013763 0ustar bhdoeQUEUE queuename thing (library procedure) command. Adds the "thing" to the queue that is the value of the variable whose name is "queuename". This variable must have a list as its value; the initial value should be the empty list. New members are added at the back of the list. ucblogo-5.5/helpfiles/dequeue0100644000161300001330000000031210276165605014267 0ustar bhdoeDEQUEUE queuename (library procedure) outputs the least recently QUEUEd member of the queue that is the value of the variable whose name is "queuename" and removes that member from the queue. ucblogo-5.5/helpfiles/wordp0100644000161300001330000000012110276165605013763 0ustar bhdoeWORDP thing WORD? thing outputs TRUE if the input is a word, FALSE otherwise. ucblogo-5.5/helpfiles/listp0100644000161300001330000000012110276165605013763 0ustar bhdoeLISTP thing LIST? thing outputs TRUE if the input is a list, FALSE otherwise. ucblogo-5.5/helpfiles/arrayp0100644000161300001330000000012510276165605014132 0ustar bhdoeARRAYP thing ARRAY? thing outputs TRUE if the input is an array, FALSE otherwise. ucblogo-5.5/helpfiles/emptyp0100644000161300001330000000015610276165605014156 0ustar bhdoeEMPTYP thing EMPTY? thing outputs TRUE if the input is the empty word or the empty list, FALSE otherwise. ucblogo-5.5/helpfiles/equalp0100644000161300001330000000155510276165605014133 0ustar bhdoeEQUALP thing1 thing2 EQUAL? thing1 thing2 thing1 = thing2 outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named CASEIGNOREDP whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.) ucblogo-5.5/helpfiles/beforep0100644000161300001330000000056410276165605014265 0ustar bhdoeBEFOREP word1 word2 BEFORE? word1 word2 outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, BEFOREP 3 12 is false because 3 collates after 1. ucblogo-5.5/helpfiles/deq0100644000161300001330000000063310276165605013411 0ustar bhdoe.EQ thing1 thing2 outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of mutators can lead to circular data structures, infinite loops, or Logo crashes. ucblogo-5.5/helpfiles/memberp0100644000161300001330000000043710276165605014271 0ustar bhdoeMEMBERP thing1 thing2 MEMBER? thing1 thing2 if "thing2" is a list or an array, outputs TRUE if "thing1" is EQUALP to a member of "thing2", FALSE otherwise. If "thing2" is a word, outputs TRUE if "thing1" is a one-character word EQUALP to a character of "thing2", FALSE otherwise. ucblogo-5.5/helpfiles/substringp0100644000161300001330000000033510276165605015037 0ustar bhdoeSUBSTRINGP thing1 thing2 SUBSTRING? thing1 thing2 if "thing1" or "thing2" is a list or an array, outputs FALSE. If "thing2" is a word, outputs TRUE if "thing1" is EQUALP to a substring of "thing2", FALSE otherwise. ucblogo-5.5/helpfiles/numberp0100644000161300001330000000012710276165605014306 0ustar bhdoeNUMBERP thing NUMBER? thing outputs TRUE if the input is a number, FALSE otherwise. ucblogo-5.5/helpfiles/backslashedp0100644000161300001330000000052710276165605015266 0ustar bhdoeBACKSLASHEDP char BACKSLASHED? char outputs TRUE if the input character was originally entered into Logo with a backslash (\) before it or within vertical bars (|) to prevent its usual special syntactic meaning, FALSE otherwise. (Outputs TRUE only if the character is a backslashed space, tab, newline, or one of ()[]+-*/=<>":;\~?| ) ucblogo-5.5/helpfiles/count0100644000161300001330000000041110276165605013762 0ustar bhdoeCOUNT thing outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.) ucblogo-5.5/helpfiles/ascii0100644000161300001330000000045310276165605013730 0ustar bhdoeASCII char outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing backslashed punctuation, and returns the character code for the corresponding punctuation character without backslash. (Compare RAWASCII.) ucblogo-5.5/helpfiles/rawascii0100644000161300001330000000036610276165605014445 0ustar bhdoeRAWASCII char outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing themselves. To find out the ASCII code of an arbitrary keystroke, use RAWASCII RC. ucblogo-5.5/helpfiles/char0100644000161300001330000000017310276165605013554 0ustar bhdoeCHAR int outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255. ucblogo-5.5/helpfiles/member0100644000161300001330000000051510276165605014106 0ustar bhdoeMEMBER thing1 thing2 if "thing2" is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of "thing2" from the first instance of "thing1" to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of "thing2". It is an error for "thing2" to be an array. ucblogo-5.5/helpfiles/lowercase0100644000161300001330000000020310276165605014615 0ustar bhdoeLOWERCASE word outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter. ucblogo-5.5/helpfiles/uppercase0100644000161300001330000000020310276165605014620 0ustar bhdoeUPPERCASE word outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter. ucblogo-5.5/helpfiles/standout0100644000161300001330000000203210276165605014474 0ustar bhdoeSTANDOUT thing outputs a word that, when printed, will appear like the input but displayed in standout mode (boldface, reverse video, or whatever your terminal does for standout). The word contains terminal-specific magic characters at the beginning and end; in between is the printed form (as if displayed using TYPE) of the input. The output is always a word, even if the input is of some other type, but it may include spaces and other formatting characters. Note: a word output by STANDOUT while Logo is running on one terminal will probably not have the desired effect if printed on another type of terminal. On the Macintosh, the way that standout works is incompatible with the use of characters whose ASCII code is greater than 127. Therefore, you have a choice to make: The instruction CANINVERSE 0 disables standout, but enables the display of ASCII codes above 127, and the instruction CANINVERSE 1 restores the default situation in which standout is enabled and the extra graphic characters cannot be printed. ucblogo-5.5/helpfiles/parse0100644000161300001330000000031510276165605013747 0ustar bhdoePARSE word outputs the list that would result if the input word were entered in response to a READLIST operation. That is, PARSE READWORD has the same value as READLIST for the same characters read. ucblogo-5.5/helpfiles/runparse0100644000161300001330000000043210276165605014474 0ustar bhdoeRUNPARSE wordorlist outputs the list that would result if the input word or list were entered as an instruction line; characters such as infix operators and parentheses are separate members of the output. Note that sublists of a runparsed list are not themselves runparsed. ucblogo-5.5/helpfiles/print0100644000161300001330000000063110276165605013772 0ustar bhdoePRINT thing PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...) command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays. ucblogo-5.5/helpfiles/pr0100644000161300001330000000063110276165605013257 0ustar bhdoePRINT thing PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...) command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays. ucblogo-5.5/helpfiles/type0100644000161300001330000000205410276165605013620 0ustar bhdoeTYPE thing (TYPE thing1 thing2 ...) command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces. Note: printing to the terminal is ordinarily "line buffered"; that is, the characters you print using TYPE will not actually appear on the screen until either a newline character is printed (for example, by PRINT or SHOW) or Logo tries to read from the keyboard (either at the request of your program or after an instruction prompt). This buffering makes the program much faster than it would be if each character appeared immediately, and in most cases the effect is not disconcerting. To accommodate programs that do a lot of positioned text display using TYPE, Logo will force printing whenever SETCURSOR is invoked. This solves most buffering problems. Still, on occasion you may find it necessary to force the buffered characters to be printed explicitly; this can be done using the WAIT command. WAIT 0 will force printing without actually waiting. ucblogo-5.5/helpfiles/show0100644000161300001330000000024210276165605013614 0ustar bhdoeSHOW thing (SHOW thing1 thing2 ...) command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets. ucblogo-5.5/helpfiles/readlist0100644000161300001330000000110210276165605014437 0ustar bhdoeREADLIST RL reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character. ucblogo-5.5/helpfiles/rl0100644000161300001330000000110210276165605013245 0ustar bhdoeREADLIST RL reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character. ucblogo-5.5/helpfiles/rw0100644000161300001330000000156610276165605013276 0ustar bhdoeREADWORD RW reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READWORD outputs the empty list (not the empty word). READWORD processes backslash, vertical bar, and tilde characters in the read stream. In the case of a tilde used for line continuation, the output word DOES include the tilde and the newline characters, so that the user program can tell exactly what the user entered. Vertical bars in the line are also preserved in the output. Backslash characters are not preserved in the output, but the character following the backslash has 128 added to its representation. Programs can use BACKSLASHEDP to check for this code. (Backslashedness is preserved only for certain characters. See BACKSLASHEDP.) ucblogo-5.5/helpfiles/readrawline0100644000161300001330000000071410276165605015135 0ustar bhdoeREADRAWLINE reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters. ucblogo-5.5/helpfiles/readchar0100644000161300001330000000073410276165605014413 0ustar bhdoeREADCHAR RC reads a single character from the read stream and outputs that character as a word. If the read stream is a file, and the end of file is reached, READCHAR outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHAR is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. ucblogo-5.5/helpfiles/rc0100644000161300001330000000073410276165605013246 0ustar bhdoeREADCHAR RC reads a single character from the read stream and outputs that character as a word. If the read stream is a file, and the end of file is reached, READCHAR outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHAR is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. ucblogo-5.5/helpfiles/readchars0100644000161300001330000000075010276165605014574 0ustar bhdoeREADCHARS num RCS num reads "num" characters from the read stream and outputs those characters as a word. If the read stream is a file, and the end of file is reached, READCHARS outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHARS is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. ucblogo-5.5/helpfiles/rcs0100644000161300001330000000075010276165605013427 0ustar bhdoeREADCHARS num RCS num reads "num" characters from the read stream and outputs those characters as a word. If the read stream is a file, and the end of file is reached, READCHARS outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHARS is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. ucblogo-5.5/helpfiles/shell0100644000161300001330000000221110276165605013741 0ustar bhdoeSHELL command (SHELL command wordflag) Under Unix, outputs the result of running "command" as a shell command. (The command is sent to /bin/sh, not csh or other alternatives.) If the command is a literal list in the instruction line, and if you want a backslash character sent to the shell, you must use \\ to get the backslash through Logo's reader intact. The output is a list containing one member for each line generated by the shell command. Ordinarily each such line is represented by a list in the output, as though the line were read using READLIST. If a second input is given, regardless of the value of the input, each line is represented by a word in the output as though it were read with READWORD. Example: to dayofweek output first first shell [date] end This is "first first" to extract the first word of the first (and only) line of the shell output. Under DOS, SHELL is a command, not an operation; it sends its input to a DOS command processor but does not collect the result of the command. The Macintosh, of course, is not programmable (unless you are running the Unix version of UCBLogo under OS X). ucblogo-5.5/helpfiles/setprefix0100644000161300001330000000071510276165605014652 0ustar bhdoeSETPREFIX string command. Sets a prefix that will be used as the implicit beginning of filenames in OPENREAD, OPENWRITE, OPENAPPEND, OPENUPDATE, LOAD, and SAVE commands. Logo will put the appropriate separator character (slash for Unix, backslash for DOS/Windows, colon for MacOS) between the prefix and the filename entered by the user. The input to SETPREFIX must be a word, unless it is the empty list, to indicate that there should be no prefix. ucblogo-5.5/helpfiles/prefix0100644000161300001330000000013010276165605014125 0ustar bhdoePREFIX outputs the current file prefix, or [] if there is no prefix. See SETPREFIX. ucblogo-5.5/helpfiles/openread0100644000161300001330000000020010276165605014423 0ustar bhdoeOPENREAD filename command. Opens the named file for reading. The read position is initially at the beginning of the file. ucblogo-5.5/helpfiles/openwrite0100644000161300001330000000162610276165605014657 0ustar bhdoeOPENWRITE filename command. Opens the named file for writing. If the file already existed, the old version is deleted and a new, empty file created. OPENWRITE, but not the other OPEN variants, will accept as input a two-element list, in which the first element must be a variable name, and the second must be a positive integer. A character buffer of the specified size will be created. When a SETWRITE is done with this same list (in the sense of .EQ, not a copy, so you must do something like ? make "buf [foo 100] ? openwrite :buf ? setwrite :buf [...] ? close :buf and not just ? openwrite [foo 100] ? setwrite [foo 100] and so on), the printed characters are stored in the buffer; when a CLOSE is done with the same list as input, the characters from the buffer (treated as one long word, even if spaces and newlines are included) become the value of the specified variable. ucblogo-5.5/helpfiles/openappend0100644000161300001330000000032510276165605014767 0ustar bhdoeOPENAPPEND filename command. Opens the named file for writing. If the file already exists, the write position is initially set to the end of the old file, so that newly written data will be appended to it. ucblogo-5.5/helpfiles/openupdate0100644000161300001330000000101410276165605014776 0ustar bhdoeOPENUPDATE filename command. Opens the named file for reading and writing. The read and write position is initially set to the end of the old file, if any. Note: each open file has only one position, for both reading and writing. If a file opened for update is both READER and WRITER at the same time, then SETREADPOS will also affect WRITEPOS and vice versa. Also, if you alternate reading and writing the same file, you must SETREADPOS between a write and a read, and SETWRITEPOS between a read and a write. ucblogo-5.5/helpfiles/close0100644000161300001330000000032510276165605013743 0ustar bhdoeCLOSE filename command. Closes the named file. If the file was currently the reader or writer, then the reader or writer is changed to the keyboard or screen, as if SETREAD [] or SETWRITE [] had been done. ucblogo-5.5/helpfiles/allopen0100644000161300001330000000021110276165605014262 0ustar bhdoeALLOPEN outputs a list whose members are the names of all files currently open. This list does not include the dribble file, if any. ucblogo-5.5/helpfiles/closeall0100644000161300001330000000015610276165605014436 0ustar bhdoeCLOSEALL (library procedure) command. Closes all open files. Abbreviates FOREACH ALLOPEN [CLOSE ?] ucblogo-5.5/helpfiles/erasefile0100644000161300001330000000017410276165605014577 0ustar bhdoeERASEFILE filename ERF filename command. Erases (deletes, removes) the named file, which should not currently be open. ucblogo-5.5/helpfiles/erf0100644000161300001330000000017410276165605013414 0ustar bhdoeERASEFILE filename ERF filename command. Erases (deletes, removes) the named file, which should not currently be open. ucblogo-5.5/helpfiles/dribble0100644000161300001330000000057210276165605014245 0ustar bhdoeDRIBBLE filename command. Creates a new file whose name is the input, like OPENWRITE, and begins recording in that file everything that is read from the keyboard or written to the terminal. That is, this writing is in addition to the writing to WRITER. The intent is to create a transcript of a Logo session, including things like prompt characters and interactions. ucblogo-5.5/helpfiles/nodribble0100644000161300001330000000013610276165605014576 0ustar bhdoeNODRIBBLE command. Stops copying information into the dribble file, and closes the file. ucblogo-5.5/helpfiles/setread0100644000161300001330000000057010276165605014267 0ustar bhdoeSETREAD filename command. Makes the named file the read stream, used for READLIST, etc. The file must already be open with OPENREAD or OPENUPDATE. If the input is the empty list, then the read stream becomes the terminal, as usual. Changing the read stream does not close the file that was previously the read stream, so it is possible to alternate between files. ucblogo-5.5/helpfiles/setwrite0100644000161300001330000000242110276165605014503 0ustar bhdoeSETWRITE filename command. Makes the named file the write stream, used for PRINT, etc. The file must already be open with OPENWRITE, OPENAPPEND, or OPENUPDATE. If the input is the empty list, then the write stream becomes the terminal, as usual. Changing the write stream does not close the file that was previously the write stream, so it is possible to alternate between files. If the input is a list, then its first element must be a variable name, and its second and last element must be a positive integer; a buffer of that many characters will be allocated, and will become the writestream. If the same list (same in the .EQ sense, not a copy) has been used as input to OPENWRITE, then the already-allocated buffer will be used, and the writer can be changed to and from this buffer, with all the characters accumulated as in a file. When the same list is used as input to CLOSE, the contents of the buffer (as an unparsed word, which may contain newline characters) will become the value of the named variable. For compatibility with earlier versions, if the list has not been opened when the SETWRITE is done, it will be opened implicitly, but the first SETWRITE after this one will implicitly close it, setting the variable and freeing the allocated buffer. ucblogo-5.5/helpfiles/reader0100644000161300001330000000016310276165605014100 0ustar bhdoeREADER outputs the name of the current read stream file, or the empty list if the read stream is the terminal. ucblogo-5.5/helpfiles/writer0100644000161300001330000000016510276165605014154 0ustar bhdoeWRITER outputs the name of the current write stream file, or the empty list if the write stream is the terminal. ucblogo-5.5/helpfiles/setreadpos0100644000161300001330000000047610276165605015016 0ustar bhdoeSETREADPOS charpos command. Sets the file pointer of the read stream file so that the next READLIST, etc., will begin reading at the "charpos"th character in the file, counting from 0. (That is, SETREADPOS 0 will start reading from the beginning of the file.) Meaningless if the read stream is the terminal. ucblogo-5.5/helpfiles/setwritepos0100644000161300001330000000047710276165605015236 0ustar bhdoeSETWRITEPOS charpos command. Sets the file pointer of the write stream file so that the next PRINT, etc., will begin writing at the "charpos"th character in the file, counting from 0. (That is, SETWRITEPOS 0 will start writing from the beginning of the file.) Meaningless if the write stream is the terminal. ucblogo-5.5/helpfiles/readpos0100644000161300001330000000010610276165605014270 0ustar bhdoeREADPOS outputs the file position of the current read stream file. ucblogo-5.5/helpfiles/writepos0100644000161300001330000000011010276165605014502 0ustar bhdoeWRITEPOS outputs the file position of the current write stream file. ucblogo-5.5/helpfiles/eofp0100644000161300001330000000017310276165605013570 0ustar bhdoeEOFP EOF? predicate, outputs TRUE if there are no more characters to be read in the read stream file, FALSE otherwise. ucblogo-5.5/helpfiles/filep0100644000161300001330000000023510276165605013735 0ustar bhdoeFILEP filename FILE? filename (library procedure) predicate, outputs TRUE if a file of the specified name exists and can be read, FALSE otherwise. ucblogo-5.5/helpfiles/keyp0100644000161300001330000000105110276165605013603 0ustar bhdoeKEYP KEY? predicate, outputs TRUE if there are characters waiting to be read from the read stream. If the read stream is a file, this is equivalent to NOT EOFP. If the read stream is the terminal, then echoing is turned off and the terminal is set to CBREAK (character at a time instead of line at a time) mode. It remains in this mode until some line-mode reading is requested (e.g., READLIST). The Unix operating system forgets about any pending characters when it switches modes, so the first KEYP invocation will always output FALSE. ucblogo-5.5/helpfiles/cleartext0100644000161300001330000000010210276165605014622 0ustar bhdoeCLEARTEXT CT command. Clears the text screen of the terminal. ucblogo-5.5/helpfiles/ct0100644000161300001330000000010210276165605013235 0ustar bhdoeCLEARTEXT CT command. Clears the text screen of the terminal. ucblogo-5.5/helpfiles/setcursor0100644000161300001330000000047310276165605014673 0ustar bhdoeSETCURSOR vector command. The input is a list of two numbers, the x and y coordinates of a screen position (origin in the upper left corner, positive direction is southeast). The screen cursor is moved to the requested position. This command also forces the immediate printing of any buffered characters. ucblogo-5.5/helpfiles/cursor0100644000161300001330000000042310276165605014152 0ustar bhdoeCURSOR outputs a list containing the current x and y coordinates of the screen cursor. Logo may get confused about the current cursor position if, e.g., you type in a long line that wraps around or your program prints escape codes that affect the terminal strangely. ucblogo-5.5/helpfiles/setmargins0100644000161300001330000000136510276165605015017 0ustar bhdoeSETMARGINS vector command. The input must be a list of two numbers, as for SETCURSOR. The effect is to clear the screen and then arrange for all further printing to be shifted down and to the right according to the indicated margins. Specifically, every time a newline character is printed (explicitly or implicitly) Logo will type x_margin spaces, and on every invocation of SETCURSOR the margins will be added to the input x and y coordinates. (CURSOR will report the cursor position relative to the margins, so that this shift will be invisible to Logo programs.) The purpose of this command is to accommodate the display of terminal screens in lecture halls with inadequate TV monitors that miss the top and left edges of the screen. ucblogo-5.5/helpfiles/settextcolor0100644000161300001330000000131310276165605015373 0ustar bhdoeSETTEXTCOLOR foreground background SETTC foreground background command (Windows and DOS extended only). The inputs are color numbers, as for turtle graphics. Future printing to the text window will use the specified colors for foreground (the characters printed) and background (the space under those characters). Using STANDOUT will revert to the default text window colors. In the DOS extended (ucblogo.exe) version, colors in textscreen mode are limited to numbers 0-7, and the coloring applies only to text printed by the program, not to the echoing of text typed by the user. Neither limitation applies to the text portion of splitscreen mode, which is actually drawn as graphics internally. ucblogo-5.5/helpfiles/settc0100644000161300001330000000131310276165605013756 0ustar bhdoeSETTEXTCOLOR foreground background SETTC foreground background command (Windows and DOS extended only). The inputs are color numbers, as for turtle graphics. Future printing to the text window will use the specified colors for foreground (the characters printed) and background (the space under those characters). Using STANDOUT will revert to the default text window colors. In the DOS extended (ucblogo.exe) version, colors in textscreen mode are limited to numbers 0-7, and the coloring applies only to text printed by the program, not to the echoing of text typed by the user. Neither limitation applies to the text portion of splitscreen mode, which is actually drawn as graphics internally. ucblogo-5.5/helpfiles/sum0100644000161300001330000000012510276165605013440 0ustar bhdoeSUM num1 num2 (SUM num1 num2 num3 ...) num1 + num2 outputs the sum of its inputs. ucblogo-5.5/helpfiles/difference0100644000161300001330000000040010276165605014722 0ustar bhdoeDIFFERENCE num1 num2 num1 - num2 outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.) ucblogo-5.5/helpfiles/product0100644000161300001330000000014110276165605014312 0ustar bhdoePRODUCT num1 num2 (PRODUCT num1 num2 num3 ...) num1 * num2 outputs the product of its inputs. ucblogo-5.5/helpfiles/quotient0100644000161300001330000000055410276165605014512 0ustar bhdoeQUOTIENT num1 num2 (QUOTIENT num) num1 / num2 outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is 2, not 2.0 -- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input. ucblogo-5.5/helpfiles/remainder0100644000161300001330000000023310276165605014602 0ustar bhdoeREMAINDER num1 num2 outputs the remainder on dividing "num1" by "num2"; both must be integers and the result is an integer with the same sign as num1. ucblogo-5.5/helpfiles/modulo0100644000161300001330000000023010276165605014130 0ustar bhdoeMODULO num1 num2 outputs the remainder on dividing "num1" by "num2"; both must be integers and the result is an integer with the same sign as num2. ucblogo-5.5/helpfiles/int0100644000161300001330000000032310276165605013426 0ustar bhdoeINT num outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input. ucblogo-5.5/helpfiles/round0100644000161300001330000000006710276165605013770 0ustar bhdoeROUND num outputs the nearest integer to the input. ucblogo-5.5/helpfiles/sqrt0100644000161300001330000000011510276165605013624 0ustar bhdoeSQRT num outputs the square root of the input, which must be nonnegative. ucblogo-5.5/helpfiles/power0100644000161300001330000000015410276165605013772 0ustar bhdoePOWER num1 num2 outputs "num1" to the "num2" power. If num1 is negative, then num2 must be an integer. ucblogo-5.5/helpfiles/exp0100644000161300001330000000007010276165605013427 0ustar bhdoeEXP num outputs e (2.718281828+) to the input power. ucblogo-5.5/helpfiles/ln0100644000161300001330000000006610276165605013251 0ustar bhdoeLN num outputs the natural logarithm of the input. ucblogo-5.5/helpfiles/sin0100644000161300001330000000011110276165605013420 0ustar bhdoeSIN degrees outputs the sine of its input, which is taken in degrees. ucblogo-5.5/helpfiles/radsin0100644000161300001330000000011410276165605014112 0ustar bhdoeRADSIN radians outputs the sine of its input, which is taken in radians. ucblogo-5.5/helpfiles/cos0100644000161300001330000000011310276165605013415 0ustar bhdoeCOS degrees outputs the cosine of its input, which is taken in degrees. ucblogo-5.5/helpfiles/radcos0100644000161300001330000000011610276165605014107 0ustar bhdoeRADCOS radians outputs the cosine of its input, which is taken in radians. ucblogo-5.5/helpfiles/arctan0100644000161300001330000000031010276165605014100 0ustar bhdoeARCTAN num (ARCTAN x y) outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or -90 depending on the sign of y, if x is zero. ucblogo-5.5/helpfiles/radarctan0100644000161300001330000000043210276165605014574 0ustar bhdoeRADARCTAN num (RADARCTAN x y) outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or -pi/2 depending on the sign of y, if x is zero. The expression 2*(RADARCTAN 0 1) can be used to get the value of pi. ucblogo-5.5/helpfiles/iseq0100644000161300001330000000024510276165605013600 0ustar bhdoeISEQ from to (library procedure) outputs a list of the integers from FROM to TO, inclusive. ? show iseq 3 7 [3 4 5 6 7] ? show iseq 7 3 [7 6 5 4 3] ucblogo-5.5/helpfiles/rseq0100644000161300001330000000035110276165605013607 0ustar bhdoeRSEQ from to count (library procedure) outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive. ? show rseq 3 5 9 [3 3.25 3.5 3.75 4 4.25 4.5 4.75 5] ? show rseq 3 5 5 [3 3.5 4 4.5 5] ucblogo-5.5/helpfiles/lessp0100644000161300001330000000016110276165605013762 0ustar bhdoeLESSP num1 num2 LESS? num1 num2 num1 < num2 outputs TRUE if its first input is strictly less than its second. ucblogo-5.5/helpfiles/greaterp0100644000161300001330000000017210276165605014447 0ustar bhdoeGREATERP num1 num2 GREATER? num1 num2 num1 > num2 outputs TRUE if its first input is strictly greater than its second. ucblogo-5.5/helpfiles/rerandom0100644000161300001330000000071210276165605014445 0ustar bhdoeRERANDOM (RERANDOM seed) command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers. ucblogo-5.5/helpfiles/form0100644000161300001330000000124610276165605013604 0ustar bhdoeFORM num width precision outputs a word containing a printable representation of "num", possibly preceded by spaces (and therefore not a number for purposes of performing arithmetic operations), with at least "width" characters, including exactly "precision" digits after the decimal point. (If "precision" is 0 then there will be no decimal point in the output.) As a debugging feature, (FORM num -1 format) will print the floating point "num" according to the C printf "format", to allow to hex :num op form :num -1 "|%08X %08X| end to allow finding out the exact result of floating point operations. The precise format needed may be machine-dependent. ucblogo-5.5/helpfiles/bitand0100644000161300001330000000015710276165605014102 0ustar bhdoeBITAND num1 num2 (BITAND num1 num2 num3 ...) outputs the bitwise AND of its inputs, which must be integers. ucblogo-5.5/helpfiles/bitor0100644000161300001330000000015410276165605013755 0ustar bhdoeBITOR num1 num2 (BITOR num1 num2 num3 ...) outputs the bitwise OR of its inputs, which must be integers. ucblogo-5.5/helpfiles/bitxor0100644000161300001330000000017110276165606014145 0ustar bhdoeBITXOR num1 num2 (BITXOR num1 num2 num3 ...) outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers. ucblogo-5.5/helpfiles/bitnot0100644000161300001330000000011610276165606014134 0ustar bhdoeBITNOT num outputs the bitwise NOT of its input, which must be an integer. ucblogo-5.5/helpfiles/ashift0100644000161300001330000000026610276165606014121 0ustar bhdoeASHIFT num1 num2 outputs "num1" arithmetic-shifted to the left by "num2" bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers. ucblogo-5.5/helpfiles/lshift0100644000161300001330000000025610276165606014133 0ustar bhdoeLSHIFT num1 num2 outputs "num1" logical-shifted to the left by "num2" bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers. ucblogo-5.5/helpfiles/and0100644000161300001330000000117410276165606013404 0ustar bhdoeAND tf1 tf2 (AND tf1 tf2 tf3 ...) outputs TRUE if all inputs are TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, "true" or "True" or "TRUE" are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example: MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5] to avoid the division by zero if the first part is false. ucblogo-5.5/helpfiles/or0100644000161300001330000000116310276165606013260 0ustar bhdoeOR tf1 tf2 (OR tf1 tf2 tf3 ...) outputs TRUE if any input is TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, "true" or "True" or "TRUE" are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example: IF OR :X=0 [some.long.computation] [...] to avoid the long computation if the first condition is met. ucblogo-5.5/helpfiles/not0100644000161300001330000000030210276165606013432 0ustar bhdoeNOT tf outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. ucblogo-5.5/helpfiles/forward0100644000161300001330000000021410276165606014300 0ustar bhdoeFORWARD dist FD dist moves the turtle forward, in the direction that it's facing, by the specified distance (measured in turtle steps). ucblogo-5.5/helpfiles/fd0100644000161300001330000000021410276165606013225 0ustar bhdoeFORWARD dist FD dist moves the turtle forward, in the direction that it's facing, by the specified distance (measured in turtle steps). ucblogo-5.5/helpfiles/back0100644000161300001330000000026510276165606013542 0ustar bhdoeBACK dist BK dist moves the turtle backward, i.e., exactly opposite to the direction that it's facing, by the specified distance. (The heading of the turtle does not change.) ucblogo-5.5/helpfiles/bk0100644000161300001330000000026510276165606013236 0ustar bhdoeBACK dist BK dist moves the turtle backward, i.e., exactly opposite to the direction that it's facing, by the specified distance. (The heading of the turtle does not change.) ucblogo-5.5/helpfiles/left0100644000161300001330000000017710276165606013576 0ustar bhdoeLEFT degrees LT degrees turns the turtle counterclockwise by the specified angle, measured in degrees (1/360 of a circle). ucblogo-5.5/helpfiles/lt0100644000161300001330000000017710276165606013263 0ustar bhdoeLEFT degrees LT degrees turns the turtle counterclockwise by the specified angle, measured in degrees (1/360 of a circle). ucblogo-5.5/helpfiles/right0100644000161300001330000000017110276165606013753 0ustar bhdoeRIGHT degrees RT degrees turns the turtle clockwise by the specified angle, measured in degrees (1/360 of a circle). ucblogo-5.5/helpfiles/rt0100644000161300001330000000017110276165606013263 0ustar bhdoeRIGHT degrees RT degrees turns the turtle clockwise by the specified angle, measured in degrees (1/360 of a circle). ucblogo-5.5/helpfiles/setpos0100644000161300001330000000017610276165606014160 0ustar bhdoeSETPOS pos moves the turtle to an absolute screen position. The input is a list of two numbers, the X and Y coordinates. ucblogo-5.5/helpfiles/setxy0100644000161300001330000000017310276165606014014 0ustar bhdoeSETXY xcor ycor moves the turtle to an absolute screen position. The two inputs are numbers, the X and Y coordinates. ucblogo-5.5/helpfiles/setx0100644000161300001330000000022010276165606013614 0ustar bhdoeSETX xcor moves the turtle horizontally from its old position to a new absolute horizontal coordinate. The input is the new X coordinate. ucblogo-5.5/helpfiles/sety0100644000161300001330000000021410276165606013620 0ustar bhdoeSETY ycor moves the turtle vertically from its old position to a new absolute vertical coordinate. The input is the new Y coordinate. ucblogo-5.5/helpfiles/setheading0100644000161300001330000000024410276165606014752 0ustar bhdoeSETHEADING degrees SETH degrees turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive Y axis. ucblogo-5.5/helpfiles/seth0100644000161300001330000000024410276165606013602 0ustar bhdoeSETHEADING degrees SETH degrees turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive Y axis. ucblogo-5.5/helpfiles/home0100644000161300001330000000014110276165606013563 0ustar bhdoeHOME moves the turtle to the center of the screen. Equivalent to SETPOS [0 0] SETHEADING 0. ucblogo-5.5/helpfiles/arc0100644000161300001330000000033310276165606013403 0ustar bhdoeARC angle radius draws an arc of a circle, with the turtle at the center, with the specified radius, starting at the turtle's heading and extending clockwise through the specified angle. The turtle does not move. ucblogo-5.5/helpfiles/pos0100644000161300001330000000014210276165606013435 0ustar bhdoePOS outputs the turtle's current position, as a list of two numbers, the X and Y coordinates. ucblogo-5.5/helpfiles/xcor0100644000161300001330000000011710276165606013611 0ustar bhdoeXCOR (library procedure) outputs a number, the turtle's X coordinate. ucblogo-5.5/helpfiles/ycor0100644000161300001330000000011710276165606013612 0ustar bhdoeYCOR (library procedure) outputs a number, the turtle's Y coordinate. ucblogo-5.5/helpfiles/heading0100644000161300001330000000007610276165606014241 0ustar bhdoeHEADING outputs a number, the turtle's heading in degrees. ucblogo-5.5/helpfiles/towards0100644000161300001330000000025110276165606014320 0ustar bhdoeTOWARDS pos outputs a number, the heading at which the turtle should be facing so that it would point from its current position to the position given as the input. ucblogo-5.5/helpfiles/scrunch0100644000161300001330000000027310276165606014306 0ustar bhdoeSCRUNCH outputs a list containing two numbers, the X and Y scrunch factors, as used by SETSCRUNCH. (But note that SETSCRUNCH takes two numbers as inputs, not one list of numbers.) ucblogo-5.5/helpfiles/showturtle0100644000161300001330000000005310276165606015055 0ustar bhdoeSHOWTURTLE ST makes the turtle visible. ucblogo-5.5/helpfiles/st0100644000161300001330000000005310276165606013263 0ustar bhdoeSHOWTURTLE ST makes the turtle visible. ucblogo-5.5/helpfiles/hideturtle0100644000161300001330000000030010276165606015001 0ustar bhdoeHIDETURTLE HT makes the turtle invisible. It's a good idea to do this while you're in the middle of a complicated drawing, because hiding the turtle speeds up the drawing substantially. ucblogo-5.5/helpfiles/ht0100644000161300001330000000030010276165606013243 0ustar bhdoeHIDETURTLE HT makes the turtle invisible. It's a good idea to do this while you're in the middle of a complicated drawing, because hiding the turtle speeds up the drawing substantially. ucblogo-5.5/helpfiles/clean0100644000161300001330000000022510276165606013720 0ustar bhdoeCLEAN erases all lines that the turtle has drawn on the graphics window. The turtle's state (position, heading, pen mode, etc.) is not changed. ucblogo-5.5/helpfiles/clearscreen0100644000161300001330000000020710276165606015124 0ustar bhdoeCLEARSCREEN CS erases the graphics window and sends the turtle to its initial position and heading. Like HOME and CLEAN together. ucblogo-5.5/helpfiles/cs0100644000161300001330000000020710276165606013243 0ustar bhdoeCLEARSCREEN CS erases the graphics window and sends the turtle to its initial position and heading. Like HOME and CLEAN together. ucblogo-5.5/helpfiles/wrap0100644000161300001330000000063510276165606013614 0ustar bhdoeWRAP tells the turtle to enter wrap mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will "wrap around" and reappear at the opposite edge of the window. The top edge wraps to the bottom edge, while the left edge wraps to the right edge. (So the window is topologically equivalent to a torus.) This is the turtle's initial mode. Compare WINDOW and FENCE. ucblogo-5.5/helpfiles/window0100644000161300001330000000061610276165606014151 0ustar bhdoeWINDOW tells the turtle to enter window mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move offscreen. The visible graphics window is considered as just part of an infinite graphics plane; the turtle can be anywhere on the plane. (If you lose the turtle, HOME will bring it back to the center of the window.) Compare WRAP and FENCE. ucblogo-5.5/helpfiles/fence0100644000161300001330000000040210276165606013713 0ustar bhdoeFENCE tells the turtle to enter fence mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move as far as it can and then stop at the edge with an "out of bounds" error message. Compare WRAP and WINDOW. ucblogo-5.5/helpfiles/fill0100644000161300001330000000036310276165606013567 0ustar bhdoeFILL fills in a region of the graphics window containing the turtle and bounded by lines that have been drawn earlier. This is not portable; it doesn't work for all machines, and may not work exactly the same way on different machines. ucblogo-5.5/helpfiles/label0100644000161300001330000000017610276165606013722 0ustar bhdoeLABEL text takes a word or list as input, and prints the input on the graphics window, starting at the turtle's position. ucblogo-5.5/helpfiles/textscreen0100644000161300001330000000035010276165606015021 0ustar bhdoeTEXTSCREEN TS rearranges the size and position of windows to maximize the space available in the text window (the window used for interaction with Logo). The details differ among machines. Compare SPLITSCREEN and FULLSCREEN. ucblogo-5.5/helpfiles/ts0100644000161300001330000000035010276165606013263 0ustar bhdoeTEXTSCREEN TS rearranges the size and position of windows to maximize the space available in the text window (the window used for interaction with Logo). The details differ among machines. Compare SPLITSCREEN and FULLSCREEN. ucblogo-5.5/helpfiles/fullscreen0100644000161300001330000000123310276165606015000 0ustar bhdoeFULLSCREEN FS rearranges the size and position of windows to maximize the space available in the graphics window. The details differ among machines. Compare SPLITSCREEN and TEXTSCREEN. In the DOS version, switching from fullscreen to splitscreen loses the part of the picture that's hidden by the text window. Also, since there must be a text window to allow printing (including the printing of the Logo prompt), Logo automatically switches from fullscreen to splitscreen whenever anything is printed. [This design decision follows from the scarcity of memory, so that the extra memory to remember an invisible part of a drawing seems too expensive.] ucblogo-5.5/helpfiles/fs0100644000161300001330000000123310276165606013246 0ustar bhdoeFULLSCREEN FS rearranges the size and position of windows to maximize the space available in the graphics window. The details differ among machines. Compare SPLITSCREEN and TEXTSCREEN. In the DOS version, switching from fullscreen to splitscreen loses the part of the picture that's hidden by the text window. Also, since there must be a text window to allow printing (including the printing of the Logo prompt), Logo automatically switches from fullscreen to splitscreen whenever anything is printed. [This design decision follows from the scarcity of memory, so that the extra memory to remember an invisible part of a drawing seems too expensive.] ucblogo-5.5/helpfiles/splitscreen0100644000161300001330000000035110276165606015171 0ustar bhdoeSPLITSCREEN SS rearranges the size and position of windows to allow some room for text interaction while also keeping most of the graphics window visible. The details differ among machines. Compare TEXTSCREEN and FULLSCREEN. ucblogo-5.5/helpfiles/ss0100644000161300001330000000035110276165606013263 0ustar bhdoeSPLITSCREEN SS rearranges the size and position of windows to allow some room for text interaction while also keeping most of the graphics window visible. The details differ among machines. Compare TEXTSCREEN and FULLSCREEN. ucblogo-5.5/helpfiles/setscrunch0100644000161300001330000000161310276165606015021 0ustar bhdoeSETSCRUNCH xscale yscale adjusts the aspect ratio and scaling of the graphics display. After this command is used, all further turtle motion will be adjusted by multiplying the horizontal and vertical extent of the motion by the two numbers given as inputs. For example, after the instruction "SETSCRUNCH 2 1" motion at a heading of 45 degrees will move twice as far horizontally as vertically. If your squares don't come out square, try this. (Alternatively, you can deliberately misadjust the aspect ratio to draw an ellipse.) For Unix machines and Macintoshes, both scale factors are initially 1. For DOS machines, the scale factors are initially set according to what the hardware claims the aspect ratio is, but the hardware sometimes lies. The values set by SETSCRUNCH are remembered in a file (called SCRUNCH.DAT) and are automatically put into effect when a Logo session begins. ucblogo-5.5/helpfiles/refresh0100644000161300001330000000031010276165606014267 0ustar bhdoeREFRESH tells Logo to remember the turtle's motions so that they can be reconstructed in case the graphics window is overlayed. The effectiveness of this command may depend on the machine used. ucblogo-5.5/helpfiles/norefresh0100644000161300001330000000022210276165606014626 0ustar bhdoeNOREFRESH tells Logo not to remember the turtle's motions. This will make drawing faster, but prevents recovery if the window is overlayed. ucblogo-5.5/helpfiles/shownp0100644000161300001330000000020010276165606014145 0ustar bhdoeSHOWNP SHOWN? outputs TRUE if the turtle is shown (visible), FALSE if the turtle is hidden. See SHOWTURTLE and HIDETURTLE. ucblogo-5.5/helpfiles/pendown0100644000161300001330000000011210276165606014303 0ustar bhdoePENDOWN PD sets the pen's position to DOWN, without changing its mode. ucblogo-5.5/helpfiles/pd0100644000161300001330000000011210276165606013234 0ustar bhdoePENDOWN PD sets the pen's position to DOWN, without changing its mode. ucblogo-5.5/helpfiles/penup0100644000161300001330000000010610276165606013763 0ustar bhdoePENUP PU sets the pen's position to UP, without changing its mode. ucblogo-5.5/helpfiles/pu0100644000161300001330000000010610276165606013260 0ustar bhdoePENUP PU sets the pen's position to UP, without changing its mode. ucblogo-5.5/helpfiles/penpaint0100644000161300001330000000010310276165606014447 0ustar bhdoePENPAINT PPT sets the pen's position to DOWN and mode to PAINT. ucblogo-5.5/helpfiles/ppt0100644000161300001330000000010310276165606013434 0ustar bhdoePENPAINT PPT sets the pen's position to DOWN and mode to PAINT. ucblogo-5.5/helpfiles/penerase0100644000161300001330000000010210276165606014432 0ustar bhdoePENERASE PE sets the pen's position to DOWN and mode to ERASE. ucblogo-5.5/helpfiles/pe0100644000161300001330000000010210276165606013234 0ustar bhdoePENERASE PE sets the pen's position to DOWN and mode to ERASE. ucblogo-5.5/helpfiles/penreverse0100644000161300001330000000021110276165606015007 0ustar bhdoePENREVERSE PX sets the pen's position to DOWN and mode to REVERSE. (This may interact in hardware-dependent ways with use of color.) ucblogo-5.5/helpfiles/px0100644000161300001330000000021110276165606013260 0ustar bhdoePENREVERSE PX sets the pen's position to DOWN and mode to REVERSE. (This may interact in hardware-dependent ways with use of color.) ucblogo-5.5/helpfiles/setpencolor0100644000161300001330000000116210276165606015174 0ustar bhdoeSETPENCOLOR colornumber.or.rgblist SETPC colornumber.or.rgblist sets the pen color to the given number, which must be a nonnegative integer. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. Alternatively, sets the pen color to the given RGB values (a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color). ucblogo-5.5/helpfiles/setpc0100644000161300001330000000116210276165606013755 0ustar bhdoeSETPENCOLOR colornumber.or.rgblist SETPC colornumber.or.rgblist sets the pen color to the given number, which must be a nonnegative integer. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. Alternatively, sets the pen color to the given RGB values (a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color). ucblogo-5.5/helpfiles/pots0100644000161300001330000000021710276165606013624 0ustar bhdoePOTS (library procedure) command. Prints the title lines of all unburied procedures in the workspace. Abbreviates POT PROCEDURES. ucblogo-5.5/helpfiles/erase0100644000161300001330000000034510276165606013740 0ustar bhdoeERASE contentslist ER contentslist command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE. ucblogo-5.5/helpfiles/er0100644000161300001330000000034510276165606013247 0ustar bhdoeERASE contentslist ER contentslist command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE. ucblogo-5.5/helpfiles/erall0100644000161300001330000000020310276165606013731 0ustar bhdoeERALL command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates ERASE CONTENTS. ucblogo-5.5/helpfiles/erps0100644000161300001330000000014410276165606013607 0ustar bhdoeERPS command. Erases all unburied procedures from the workspace. Abbreviates ERASE PROCEDURES. ucblogo-5.5/helpfiles/erns0100644000161300001330000000013610276165606013606 0ustar bhdoeERNS command. Erases all unburied variables from the workspace. Abbreviates ERASE NAMES. ucblogo-5.5/helpfiles/erpls0100644000161300001330000000014510276165606013764 0ustar bhdoeERPLS command. Erases all unburied property lists from the workspace. Abbreviates ERASE PLISTS. ucblogo-5.5/helpfiles/`0100644000161300001330000000244510276165606013063 0ustar bhdoe` list (library procedure) outputs a list equal to its input but with certain substitutions. If a member of the input list is the word "," (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word ",@" (comma atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the ,@ and the instructionlist. Example: show `[foo baz ,[bf [a b c]] garply ,@[bf [a b c]]] will print [foo baz [b c] garply b c] A word starting with , or ,@ is treated as if the rest of the word were a one-word list, e.g., ,:FOO is equivalent to ,[:FOO]. A word starting with ", (quote comma) or :, (colon comma) becomes a word starting with " or : but with the result of running the substitution (or its first word, if the result is a list) replacing what comes after the comma. Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found: ? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f] [a ` [b , [1+2] , [foo 4 d] e] f] ?make "name1 "x ?make "name2 "y ? show `[a `[b ,:,:name1 ,",:name2 d] e] [a ` [b , [:x] , ["y] d] e] ucblogo-5.5/helpfiles/for0100644000161300001330000000266610276165606013437 0ustar bhdoeFOR forcontrol instructionlist (library procedure) command. The first input must be a list containing three or four members: (1) a word, which will be used as the name of a local variable; (2) a word or list that will be evaluated as by RUN to determine a number, the starting value of the variable; (3) a word or list that will be evaluated to determine a number, the limit value of the variable; (4) an optional word or list that will be evaluated to determine the step size. If the fourth member is missing, the step size will be 1 or -1 depending on whether the limit value is greater than or less than the starting value, respectively. The second input is an instructionlist. The effect of FOR is to run that instructionlist repeatedly, assigning a new value to the control variable (the one named by the first member of the forcontrol list) each time. First the starting value is assigned to the control variable. Then the value is compared to the limit value. FOR is complete when the sign of (current - limit) is the same as the sign of the step size. (If no explicit step size is provided, the instructionlist is always run at least once. An explicit step size can lead to a zero-trip FOR, e.g., FOR [I 1 0 1] ...) Otherwise, the instructionlist is run, then the step is added to the current value of the control variable and FOR returns to the comparison step. ? for [i 2 7 1.5] [print :i] 2 3.5 5 6.5 ? ucblogo-5.5/helpfiles/dodwhile0100644000161300001330000000054110276165606014436 0ustar bhdoeDO.WHILE instructionlist tfexpression (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains TRUE. Evaluates the first input first, so the "instructionlist" is always run at least once. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. ucblogo-5.5/helpfiles/while0100644000161300001330000000053210276165606013747 0ustar bhdoeWHILE tfexpression instructionlist (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains TRUE. Evaluates the first input first, so the "instructionlist" may never be run at all. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. ucblogo-5.5/helpfiles/doduntil0100644000161300001330000000054210276165606014462 0ustar bhdoeDO.UNTIL instructionlist tfexpression (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains FALSE. Evaluates the first input first, so the "instructionlist" is always run at least once. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. ucblogo-5.5/helpfiles/until0100644000161300001330000000053310276165606013773 0ustar bhdoeUNTIL tfexpression instructionlist (library procedure) command. Repeatedly evaluates the "instructionlist" as long as the evaluated "tfexpression" remains FALSE. Evaluates the first input first, so the "instructionlist" may never be run at all. The "tfexpression" must be an expressionlist whose value when evaluated is TRUE or FALSE. ucblogo-5.5/helpfiles/apply0100644000161300001330000000054310276165606013766 0ustar bhdoeAPPLY template inputlist command or operation. Runs the "template," filling its slots with the members of "inputlist." The number of members in "inputlist" must be an acceptable number of slots for "template." It is illegal to apply the primitive TO as a template, but anything else is okay. APPLY outputs what "template" outputs, if anything. ucblogo-5.5/helpfiles/invoke0100644000161300001330000000032310276165606014130 0ustar bhdoeINVOKE template input (library procedure) (INVOKE template input1 input2 ...) command or operation. Exactly like APPLY except that the inputs are provided as separate expressions rather than in a list. ucblogo-5.5/helpfiles/foreach0100644000161300001330000000172310276165606014251 0ustar bhdoeFOREACH data template (library procedure) (FOREACH data1 data2 ... template) command. Evaluates the template list repeatedly, once for each member of the data list. If more than one data list are given, each of them must be the same length. (The data inputs can be words, in which case the template is evaluated once for each character. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. ucblogo-5.5/helpfiles/map0100644000161300001330000000227310276165606013420 0ustar bhdoeMAP template data (library procedure) (MAP template data1 data2 ...) outputs a word or list, depending on the type of the data input, of the same length as that data input. (If more than one data input are given, the output is of the same type as data1.) Each member of the output is the result of evaluating the template list, filling the slots with the corresponding member(s) of the data input(s). (All data inputs must be the same length.) In the case of a word output, the results of the template evaluation must be words, and they are concatenated with WORD. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. ucblogo-5.5/helpfiles/mapdse0100644000161300001330000000216710276165606014116 0ustar bhdoeMAP.SE template data (library procedure) (MAP.SE template data1 data2 ...) outputs a list formed by evaluating the template list repeatedly and concatenating the results using SENTENCE. That is, the members of the output are the members of the results of the evaluations. The output list might, therefore, be of a different length from that of the data input(s). (If the result of an evaluation is the empty list, it contributes nothing to the final output.) The data inputs may be words or lists. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. ucblogo-5.5/helpfiles/filter0100644000161300001330000000177210276165606014133 0ustar bhdoeFILTER tftemplate data (library procedure) outputs a word or list, depending on the type of the data input, containing a subset of the members (for a list) or characters (for a word) of the input. The template is evaluated once for each member or character of the data, and it must produce a TRUE or FALSE value. If the value is TRUE, then the corresponding input constituent is included in the output. ? print filter "vowelp "elephant eea ? In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. ucblogo-5.5/helpfiles/find0100644000161300001330000000155410276165606013564 0ustar bhdoeFIND tftemplate data (library procedure) outputs the first constituent of the data input (the first member of a list, or the first character of a word) for which the value produced by evaluating the template with that consituent in its slot is TRUE. If there is no such constituent, the empty list is output. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. ucblogo-5.5/helpfiles/reduce0100644000161300001330000000253410276165606014112 0ustar bhdoeREDUCE template data (library procedure) outputs the result of applying the template to accumulate the members of the data input. The template must be a two-slot function. Typically it is an associative function name like "SUM. If the data input has only one constituent (member in a list or character in a word), the output is that consituent. Otherwise, the template is first applied with ?1 filled with the next-to-last consitient and ?2 with the last constituent. Then, if there are more constituents, the template is applied with ?1 filled with the next constituent to the left and ?2 with the result from the previous evaluation. This process continues until all constituents have been used. The data input may not be empty. Note: If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs: to max :a :b output ifelse :a > :b [:a] [:b] end print reduce "max [...] Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does: to max [:inputs] 2 if emptyp :inputs ~ [(throw "error [not enough inputs to max])] output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs end ucblogo-5.5/helpfiles/crossmap0100644000161300001330000000154310276165606014471 0ustar bhdoeCROSSMAP template listlist (library procedure) (CROSSMAP template data1 data2 ...) outputs a list containing the results of template evaluations. Each data list contributes to a slot in the template; the number of slots is equal to the number of data list inputs. As a special case, if only one data list input is given, that list is taken as a list of data lists, and each of its members contributes values to a slot. CROSSMAP differs from MAP in that instead of taking members from the data inputs in parallel, it takes all possible combinations of members of data inputs, which need not be the same length. ? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4]) [a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4] ? For compatibility with the version in the first edition of CSLS, CROSSMAP templates may use the notation :1 instead of ?1 to indicate slots. ucblogo-5.5/helpfiles/cascade0100644000161300001330000000510410276165606014222 0ustar bhdoeCASCADE endtest template startvalue (library procedure) (CASCADE endtest tmp1 sv1 tmp2 sv2 ...) (CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate) outputs the result of applying a template (or several templates, as explained below) repeatedly, with a given value filling the slot the first time, and the result of each application filling the slot for the following application. In the simplest case, CASCADE has three inputs. The second input is a one-slot expression template. That template is evaluated some number of times (perhaps zero). On the first evaluation, the slot is filled with the third input; on subsequent evaluations, the slot is filled with the result of the previous evaluation. The number of evaluations is determined by the first input. This can be either a nonnegative integer, in which case the template is evaluated that many times, or a predicate expression template, in which case it is evaluated (with the same slot filler that will be used for the evaluation of the second input) repeatedly, and the CASCADE evaluation continues as long as the predicate value is FALSE. (In other words, the predicate template indicates the condition for stopping.) If the template is evaluated zero times, the output from CASCADE is the third (startvalue) input. Otherwise, the output is the value produced by the last template evaluation. CASCADE templates may include the symbol # to represent the number of times the template has been evaluated. This slot is filled with 1 for the first evaluation, 2 for the second, and so on. ? show cascade 5 [lput # ?] [] [1 2 3 4 5] ? show cascade [vowelp first ?] [bf ?] "spring ing ? show cascade 5 [# * ?] 1 120 ? Several cascaded results can be computed in parallel by providing additional template-startvalue pairs as inputs to CASCADE. In this case, all templates (including the endtest template, if used) are multi-slot, with the number of slots equal to the number of pairs of inputs. In each round of evaluations, ?2 represents the result of evaluating the second template in the previous round. If the total number of inputs (including the first endtest input) is odd, then the output from CASCADE is the final value of the first template. If the total number of inputs is even, then the last input is a template that is evaluated once, after the end test is satisfied, to determine the output from CASCADE. to fibonacci :n output (cascade :n [?1 + ?2] 1 [?1] 0) end to piglatin :word output (cascade [vowelp first ?] ~ [word bf ? first ?] ~ :word ~ [word ? "ay]) end ucblogo-5.5/helpfiles/transfer0100644000161300001330000000145410276165606014467 0ustar bhdoeTRANSFER endtest template inbasket (library procedure) outputs the result of repeated evaluation of the template. The template is evaluated once for each member of the list "inbasket." TRANSFER maintains an "outbasket" that is initially the empty list. After each evaluation of the template, the resulting value becomes the new outbasket. In the template, the symbol ?IN represents the current member from the inbasket; the symbol ?OUT represents the entire current outbasket. Other slot symbols should not be used. If the first (endtest) input is an empty list, evaluation continues until all inbasket members have been used. If not, the first input must be a predicate expression template, and evaluation continues until either that template's value is TRUE or the inbasket is used up. ucblogo-5.5/helpfiles/dmacro0100644000161300001330000001106310276165606014105 0ustar bhdoe.MACRO procname :input1 :input2 ... (special form) .DEFMACRO procname text A macro is a special kind of procedure whose output is evaluated as Logo instructions in the context of the macro's caller. .MACRO is exactly like TO except that the new procedure becomes a macro; .DEFMACRO is exactly like DEFINE with the same exception. Macros are useful for inventing new control structures comparable to REPEAT, IF, and so on. Such control structures can almost, but not quite, be duplicated by ordinary Logo procedures. For example, here is an ordinary procedure version of REPEAT: to my.repeat :num :instructions if :num=0 [stop] run :instructions my.repeat :num-1 :instructions end This version works fine for most purposes, e.g., my.repeat 5 [print "hello] But it doesn't work if the instructions to be carried out include OUTPUT, STOP, or LOCAL. For example, consider this procedure: to example print [Guess my secret word. You get three guesses.] repeat 3 [type "|?? | ~ if readword = "secret [pr "Right! stop]] print [Sorry, the word was "secret"!] end This procedure works as written, but if MY.REPEAT is used instead of REPEAT, it won't work because the STOP will stop MY.REPEAT instead of stopping EXAMPLE as desired. The solution is to make MY.REPEAT a macro. Instead of actually carrying out the computation, a macro must return a list containing Logo instructions. The contents of that list are evaluated as if they appeared in place of the call to the macro. Here's a macro version of REPEAT: .macro my.repeat :num :instructions if :num=0 [output []] output sentence :instructions ~ (list "my.repeat :num-1 :instructions) end Every macro is an operation -- it must always output something. Even in the base case, MY.REPEAT outputs an empty instruction list. To show how MY.REPEAT works, let's take the example my.repeat 5 [print "hello] For this example, MY.REPEAT will output the instruction list [print "hello my.repeat 4 [print "hello]] Logo then executes these instructions in place of the original invocation of MY.REPEAT; this prints "hello" once and invokes another repetition. The technique just shown, although fairly easy to understand, has the defect of slowness because each repetition has to construct an instruction list for evaluation. Another approach is to make my.repeat a macro that works just like the non-macro version unless the instructions to be repeated include OUTPUT or STOP: .macro my.repeat :num :instructions catch "repeat.catchtag ~ [op repeat.done runresult [repeat1 :num :instructions]] op [] end to repeat1 :num :instructions if :num=0 [throw "repeat.catchtag] run :instructions .maybeoutput repeat1 :num-1 :instructions end to repeat.done :repeat.result if emptyp :repeat.result [op [stop]] op list "output quoted first :repeat.result end If the instructions do not include STOP or OUTPUT, then REPEAT1 will reach its base case and invoke THROW. As a result, my.repeat's last instruction line will output an empty list, so the second evaluation of the macro result will do nothing. But if a STOP or OUTPUT happens, then REPEAT.DONE will output a STOP or OUTPUT instruction that will be re-executed in the caller's context. The macro-defining commands have names starting with a dot because macros are an advanced feature of Logo; it's easy to get in trouble by defining a macro that doesn't terminate, or by failing to construct the instruction list properly. Lisp users should note that Logo macros are NOT special forms. That is, the inputs to the macro are evaluated normally, as they would be for any other Logo procedure. It's only the output from the macro that's handled unusually. Here's another example: .macro localmake :name :value output (list "local ~ word "" :name ~ "apply ~ ""make ~ (list :name :value)) end It's used this way: to try localmake "garply "hello print :garply end LOCALMAKE outputs the list [local "garply apply "make [garply hello]] The reason for the use of APPLY is to avoid having to decide whether or not the second input to MAKE requires a quotation mark before it. (In this case it would -- MAKE "GARPLY "HELLO -- but the quotation mark would be wrong if the value were a list.) It's often convenient to use the ` function to construct the instruction list: .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end On the other hand, ` is pretty slow, since it's tree recursive and written in Logo. ucblogo-5.5/helpfiles/ddefmacro0100644000161300001330000001106310276165606014564 0ustar bhdoe.MACRO procname :input1 :input2 ... (special form) .DEFMACRO procname text A macro is a special kind of procedure whose output is evaluated as Logo instructions in the context of the macro's caller. .MACRO is exactly like TO except that the new procedure becomes a macro; .DEFMACRO is exactly like DEFINE with the same exception. Macros are useful for inventing new control structures comparable to REPEAT, IF, and so on. Such control structures can almost, but not quite, be duplicated by ordinary Logo procedures. For example, here is an ordinary procedure version of REPEAT: to my.repeat :num :instructions if :num=0 [stop] run :instructions my.repeat :num-1 :instructions end This version works fine for most purposes, e.g., my.repeat 5 [print "hello] But it doesn't work if the instructions to be carried out include OUTPUT, STOP, or LOCAL. For example, consider this procedure: to example print [Guess my secret word. You get three guesses.] repeat 3 [type "|?? | ~ if readword = "secret [pr "Right! stop]] print [Sorry, the word was "secret"!] end This procedure works as written, but if MY.REPEAT is used instead of REPEAT, it won't work because the STOP will stop MY.REPEAT instead of stopping EXAMPLE as desired. The solution is to make MY.REPEAT a macro. Instead of actually carrying out the computation, a macro must return a list containing Logo instructions. The contents of that list are evaluated as if they appeared in place of the call to the macro. Here's a macro version of REPEAT: .macro my.repeat :num :instructions if :num=0 [output []] output sentence :instructions ~ (list "my.repeat :num-1 :instructions) end Every macro is an operation -- it must always output something. Even in the base case, MY.REPEAT outputs an empty instruction list. To show how MY.REPEAT works, let's take the example my.repeat 5 [print "hello] For this example, MY.REPEAT will output the instruction list [print "hello my.repeat 4 [print "hello]] Logo then executes these instructions in place of the original invocation of MY.REPEAT; this prints "hello" once and invokes another repetition. The technique just shown, although fairly easy to understand, has the defect of slowness because each repetition has to construct an instruction list for evaluation. Another approach is to make my.repeat a macro that works just like the non-macro version unless the instructions to be repeated include OUTPUT or STOP: .macro my.repeat :num :instructions catch "repeat.catchtag ~ [op repeat.done runresult [repeat1 :num :instructions]] op [] end to repeat1 :num :instructions if :num=0 [throw "repeat.catchtag] run :instructions .maybeoutput repeat1 :num-1 :instructions end to repeat.done :repeat.result if emptyp :repeat.result [op [stop]] op list "output quoted first :repeat.result end If the instructions do not include STOP or OUTPUT, then REPEAT1 will reach its base case and invoke THROW. As a result, my.repeat's last instruction line will output an empty list, so the second evaluation of the macro result will do nothing. But if a STOP or OUTPUT happens, then REPEAT.DONE will output a STOP or OUTPUT instruction that will be re-executed in the caller's context. The macro-defining commands have names starting with a dot because macros are an advanced feature of Logo; it's easy to get in trouble by defining a macro that doesn't terminate, or by failing to construct the instruction list properly. Lisp users should note that Logo macros are NOT special forms. That is, the inputs to the macro are evaluated normally, as they would be for any other Logo procedure. It's only the output from the macro that's handled unusually. Here's another example: .macro localmake :name :value output (list "local ~ word "" :name ~ "apply ~ ""make ~ (list :name :value)) end It's used this way: to try localmake "garply "hello print :garply end LOCALMAKE outputs the list [local "garply apply "make [garply hello]] The reason for the use of APPLY is to avoid having to decide whether or not the second input to MAKE requires a quotation mark before it. (In this case it would -- MAKE "GARPLY "HELLO -- but the quotation mark would be wrong if the value were a list.) It's often convenient to use the ` function to construct the instruction list: .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end On the other hand, ` is pretty slow, since it's tree recursive and written in Logo. ucblogo-5.5/helpfiles/macrop0100644000161300001330000000011510276165606014115 0ustar bhdoeMACROP name MACRO? name outputs TRUE if its input is the name of a macro. ucblogo-5.5/helpfiles/macroexpand0100644000161300001330000000067110276165606015144 0ustar bhdoeMACROEXPAND expr (library procedure) takes as its input a Logo expression that invokes a macro (that is, one that begins with the name of a macro) and outputs the the Logo expression into which the macro would translate the input expression. .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end ? show macroexpand [localmake "pi 3.14159] [local "pi apply "make [pi 3.14159]] ucblogo-5.5/helpfiles/caseignoredp0100644000161300001330000000032210276165606015277 0ustar bhdoeCASEIGNOREDP (variable) if TRUE, indicates that lower case and upper case letters should be considered equal by EQUALP, BEFOREP, MEMBERP, etc. Logo initially makes this variable TRUE, and buries it. ucblogo-5.5/helpfiles/erract0100644000161300001330000000023210276165606014114 0ustar bhdoeERRACT (variable) an instructionlist that will be run in the event of an error. Typically has the value [PAUSE] to allow interactive debugging. ucblogo-5.5/helpfiles/loadnoisily0100644000161300001330000000022610276165606015165 0ustar bhdoeLOADNOISILY (variable) if TRUE, prints the names of procedures defined when loading from a file (including the temporary file made by EDIT). ucblogo-5.5/helpfiles/printdepthlimit0100644000161300001330000000022310276165606016054 0ustar bhdoePRINTDEPTHLIMIT (variable) if a nonnegative integer, indicates the maximum depth of sublist structure that will be printed by PRINT, etc. ucblogo-5.5/helpfiles/printwidthlimit0100644000161300001330000000023210276165606016067 0ustar bhdoePRINTWIDTHLIMIT (variable) if a nonnegative integer, indicates the maximum number of members in any one list that will be printed by PRINT, etc. ucblogo-5.5/helpfiles/redefp0100644000161300001330000000014310276165606014102 0ustar bhdoeREDEFP (variable) if TRUE, allows primitives to be erased (ERASE) or redefined (COPYDEF). ucblogo-5.5/helpfiles/startup0100644000161300001330000000021310276165606014335 0ustar bhdoeSTARTUP (variable) if assigned a list value in a file loaded by LOAD, that value is run as an instructionlist after the loading. ucblogo-5.5/helpfiles/minus0100644000161300001330000000050610276165605013772 0ustar bhdoeMINUS num - num outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms: MINUS 3 + 4 means -(3+4) - 3 + 4 means (-3)+4 ucblogo-5.5/helpfiles/log100100644000161300001330000000007010276165605013555 0ustar bhdoeLOG10 num outputs the common logarithm of the input. ucblogo-5.5/helpfiles/traced0100644000161300001330000000012610276165606014100 0ustar bhdoeTRACED outputs a contents list including all traced named items in the workspace. ucblogo-5.5/helpfiles/stepped0100644000161300001330000000013010276165606014275 0ustar bhdoeSTEPPED outputs a contents list including all stepped named items in the workspace. ucblogo-5.5/helpfiles/primitives0100644000161300001330000000035010276165606015030 0ustar bhdoePRIMITIVES outputs a list of the names of all primitive procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.) ucblogo-5.5/helpfiles/lessequalp0100644000161300001330000000017710276165605015021 0ustar bhdoeLESSEQUALP num1 num2 LESSEQUAL? num1 num2 num1 <= num2 outputs TRUE if its first input is less than or equal to its second. ucblogo-5.5/helpfiles/greaterequalp0100644000161300001330000000021110276165605015471 0ustar bhdoeGREATEREQUALP num1 num2 GREATEREQUAL? num1 num2 num1 >= num2 outputs TRUE if its first input is greater than or equal to its second. ucblogo-5.5/helpfiles/notequalp0100644000161300001330000000027610276165605014653 0ustar bhdoeNOTEQUALP thing1 thing2 NOTEQUAL? thing1 thing2 thing1 <> thing2 outputs FALSE if the inputs are equal, TRUE otherwise. See EQUALP for the meaning of equality for different data types. ucblogo-5.5/helpfiles/ALL_NAMES0100644000161300001330000000554610276165606014204 0ustar bhdoeword list sentence se fput lput array mdarray listtoarray arraytolist combine reverse gensym first firsts last butfirst bf butfirsts bfs butlast bl item mditem pick remove remdup quoted setitem mdsetitem .setfirst .setbf .setitem push pop queue dequeue wordp word? listp list? arrayp array? emptyp empty? equalp equal? notequalp notequal? beforep before? .eq memberp member? substringp substring? numberp number? backslashedp backslashed? count ascii rawascii char member lowercase uppercase standout parse runparse print pr type show readlist rl readword rw readrawline readchar rc readchars rcs shell setprefix prefix openread openwrite openappend openupdate close allopen closeall erasefile erf dribble nodribble setread setwrite reader writer setreadpos setwritepos readpos writepos eofp eof? filep file? keyp key? cleartext ct setcursor cursor setmargins settextcolor settc sum difference minus product quotient remainder modulo int round sqrt power exp log10 ln sin radsin cos radcos arctan radarctan iseq rseq lessp less? greaterp greater? lessequalp lessequal? greaterequalp greaterequal? random rerandom form bitand bitor bitxor bitnot ashift lshift and or not forward fd back bk left lt right rt setpos setxy setx sety setheading seth home arc pos xcor ycor heading towards scrunch showturtle st hideturtle ht clean clearscreen cs wrap window fence fill label textscreen ts fullscreen fs splitscreen ss setscrunch refresh norefresh shownp shown? screenmode turtlemode pendown pd penup pu penpaint ppt penerase pe penreverse px setpencolor setpc setpalette setpensize setpenpattern setpen setbackground setbg pendownp pendown? penmode pencolor pc palette pensize penpattern pen background bg savepict loadpict epspict mousepos buttonp button? button to define text fulltext copydef make name local localmake thing global pprop gprop remprop plist procedurep procedure? primitivep primitive? definedp defined? namep name? plistp plist? contents buried traced stepped procedures primitives names plists namelist pllist arity nodes printout po poall pops pons popls pon popl pot pots erase er erall erps erns erpls ern erpl bury buryall buryname unbury unburyall unburyname buriedp buried? trace untrace tracedp traced? step unstep steppedp stepped? edit ed editfile edall edps edns edpls edn edpl save savel load cslsload help seteditor setlibloc sethelploc setcslsloc settemploc gc .setsegmentsize run runresult repeat forever repcount if ifelse test iftrue ift iffalse iff stop output op catch throw error pause continue co wait bye .maybeoutput goto tag ignore ` for do.while while do.until until case cond apply invoke foreach map map.se filter find reduce crossmap cascade transfer .macro .defmacro macrop macro? macroexpand allowgetset caseignoredp erract fullprintp loadnoisily printdepthlimit printwidthlimit redefp startup unburyonedit usealternatenames logoversion logoplatform + - * / = < > <= >= <> ucblogo-5.5/helpfiles/setcslsloc0100644000161300001330000000027510276165606015021 0ustar bhdoeSETCSLSLOC path command. Tells Logo to use the specified directory for the CSLSLOAD command, instead of the default directory. The format of a path depends on your operating system. ucblogo-5.5/helpfiles/cslsload0100644000161300001330000000026210276165606014443 0ustar bhdoeCSLSLOAD name command. Loads the named file, like LOAD, but from the directory containing the Computer Science Logo Style programs instead of the current user's directory. ucblogo-5.5/helpfiles/HELPCONTENTS0100644000161300001330000000531510276165606014551 0ustar bhdoeHelp is available on the following: ` difference last plistp setcslsloc < do.until left plists setcursor <= do.while lessequalp pllist seteditor <> dribble lessp poall .setfirst = edall list pon setheading > edit listp pons sethelploc >= editfile listtoarray pop setitem - edn ln popl .setitem / edns load popls setlibloc * edpl loadnoisily pops setmargins + edpls loadpict pos setpalette allopen edps local pot setpen allowgetset emptyp localmake pots setpencolor and eofp log10 power setpenpattern apply epspict logoplatform pprop setpensize arc .eq logoversion prefix setpos arctan equalp lowercase primitivep setprefix arity erall lput primitives setread array erase lshift print setreadpos arrayp erasefile .macro printdepthlimit setscrunch arraytolist ern macroexpand printout .setsegmentsize ascii erns macrop printwidthlimit settemploc ashift erpl make procedurep settextcolor back erpls map procedures setwrite background erps map.se product setwritepos backslashedp erract .maybeoutput push setx beforep error mdarray queue setxy bitand exp mditem quoted sety bitnot fence mdsetitem quotient shell bitor filep member radarctan show bitxor fill memberp radcos shownp buried filter minus radsin showturtle buriedp find modulo random sin bury first mousepos rawascii splitscreen buryall firsts name readchar sqrt buryname for namelist readchars standout butfirst foreach namep reader startup butfirsts forever names readlist step butlast form nodes readpos stepped button forward nodribble readrawline steppedp buttonp fput norefresh readword stop bye fullprintp not redefp substringp cascade fullscreen notequalp reduce sum case fulltext numberp refresh tag caseignoredp gc openappend remainder test catch gensym openread remdup text char global openupdate remove textscreen clean goto openwrite remprop thing clearscreen gprop or repcount throw cleartext greaterequalp output repeat to close greaterp palette rerandom towards closeall heading parse reverse trace combine help pause right traced cond hideturtle pen round tracedp contents home pencolor rseq transfer continue if pendown run turtlemode copydef ifelse pendownp runparse type cos iffalse penerase runresult unbury count iftrue penmode save unburyall crossmap ignore penpaint savel unburyname cslsload int penpattern savepict unburyonedit cursor invoke penreverse screenmode unstep define iseq pensize scrunch until definedp item penup sentence untrace .defmacro keyp pick setbackground uppercase dequeue label plist .setbf usealternatenam wait window wordp writepos xcor while word wrap writer ycor ucblogo-5.5/helpfiles/buttonp0100644000161300001330000000035610276165606014336 0ustar bhdoeBUTTONP BUTTON? outputs TRUE if a mouse button is down and the mouse is over the graphics window. Once the button is down, BUTTONP remains true until the button is released, even if the mouse is dragged out of the graphics window. ucblogo-5.5/helpfiles/button0100644000161300001330000000036710276165606014160 0ustar bhdoeBUTTON outputs 0 if BUTTONP would output FALSE; otherwise, it outputs an integer between 1 and 3 indicating which button was pressed. Ordinarily 1 means left, 2 means right, and 3 means center, but operating systems may reconfigure these. ucblogo-5.5/helpfiles/printout0100644000161300001330000000026310276165606014524 0ustar bhdoePRINTOUT contentslist PO contentslist command. Prints to the write stream the definitions of all procedures, variables, and property lists named in the input contents list. ucblogo-5.5/helpfiles/logoversion0100644000161300001330000000013310276165606015202 0ustar bhdoeLOGOVERSION (variable) a real number indicating the Logo version number, e.g., 5.5 ucblogo-5.5/helpfiles/logoplatform0100644000161300001330000000013710276165606015345 0ustar bhdoeLOGOPLATFORM (variable) one of the following words: X11, Windows, or Unix-Nographics. ucblogo-5.5/emacs/0040755000161300001330000000000010276171174012031 5ustar bhdoeucblogo-5.5/emacs/makefile0100644000161300001330000000365710152437202013527 0ustar bhdoeBUILDIR = `pwd` EMACSDIR = $(LIBLOC)/emacs INFODIR = $(prefix)/info LOADPATH = $(subst X,$(EMACSDIR),(setq load-path (cons "\"X\"" load-path))) LOGOBIN = $(subst X,$(BINDIR),(setq logo-binary-name \"X/logo\")) INFOPATH = $(subst X,$(INFODIR),(setq logo-info-file \"X/ucblogo.info\")) HELPPATH = $(subst X,$(LIBLOC),(setq logo-help-path \"X/helpfiles/\")) TUTORPATH = $(subst X,$(EMACSDIR),(setq logo-tutorial-path \"X/\")) all: logo.elc dot.emacs install-logo-mode logo.elc: comint-logo.el letrec.el logo.el emacs -batch -l $(BUILDIR)/edfunc.el -f compile-load-path -f batch-byte-compile comint-logo.el letrec.el logo.el dot.emacs: @echo "$(LOADPATH)" > e.path @echo "$(LOGOBIN)" > e.bin @echo "$(INFOPATH)" > e.info @echo "$(HELPPATH)" > e.help @echo "$(TUTORPATH)" > e.tutor @echo ";;" > e.safe cat dot.emacs1 e.safe e.path e.bin e.info e.help e.tutor dot.emacs2 > dot.emacs @echo ";;; -*- logo -*-" > e.loops1 @echo "load \"$(EMACSDIR)/.logo load \"$(EMACSDIR)/.LOOPS" > e.loops2 cat e.loops1 e.loops2 > dot.loops install-logo-mode: @echo "emacs -batch ~/.emacs -l $(EMACSDIR)/edfunc.el -f edfunc -insert $(EMACSDIR)/dot.emacs -f save-buffer -kill" > e.user @echo "exec emacs $(EMACSDIR)/check.lg &" > e.check @echo "#!/bin/sh" > add.user cat add.user e.user e.check > install-logo-mode chmod u=rwx,go=rx install-logo-mode clean: -rm -f e.* -rm -f add.user ship: -rm -f e.* -rm -f add.user install-logo-mode dot.emacs dot.loops *.elc install: all for d in $(EMACSDIR); do [ -d $$d ] || mkdir -p $$d || exit 1; done cp -f logo.* $(EMACSDIR)/. cp -f letrec.* $(EMACSDIR)/. cp -f comint*.* $(EMACSDIR)/. cp -f tutor* $(EMACSDIR)/. cp -f dot.loops $(EMACSDIR)/. cp -f dot.logo $(EMACSDIR)/.logo cp -f dot.LOOPS $(EMACSDIR)/.LOOPS cp -f dot.emacs $(EMACSDIR)/. cp -f README $(EMACSDIR)/. cp -p install-logo-mode $(BINDIR)/. cp -f edfunc.el $(EMACSDIR)/. cp -f check.lg $(EMACSDIR)/. ucblogo-5.5/emacs/check.lg0100644000161300001330000000405507556010456013435 0ustar bhdoe;; check.lg ;; ;; This file serves as a test file for Berkeley Logo and Emacs logo-mode ;; installation. Read the text, and carry out the actions indicated. ;; ;; Now click mouse on the `Logo-start' menu (menu-bar top right), and ;; choose `Run Logo Other Frame'. ;; ;; This should pop-up a new emacs frame with title *logo*, and Logo ;; should greet you in it with: ;; ;; Welcome to Berkeley Logo version 5.1 ;; ? ;; ;; -------------------------------------------------------------------- ;;; WARNING: If emacs (instead of opening a new frame) appears to hung ;;; up, you can regain control by hitting Control-g (twice). ;;; Unfortunately, you will not be able to use logo-mode, because ;;; (probably) Logo itself does not work properly on your system. ;; -------------------------------------------------------------------- ;; ;; If you can see this, then both Logo and emacs logo-mode, are probably ;; properly installed. Let's test one more thing. Position the cursor on ;; the line of Logo code (below) that starts with `ct repeat 120 [...' ;; and hit C-x C-e (Control-x Control-e). ct repeat 120 [setcursor list random 75 random 23 type standout cursor] ;; 120 pairs of highlighted numbers should appear scattered in *logo* ;; frame. If there were no beeps and error messages -- you have a ;; working version of logo-mode. ;; ;;; REMARK: Some Linux distributions install very elaborate .emacs (or ;;; .gnu-emacs) files into user's home directory, or use desktop ;;; schemes, which can cause the inferior Logo frame to shrink in ;;; size. If you detect this, hit C-M-f (Ctrl-Alt-f) combination to ;;; restore the required Logo frame size. ;; ;; If you want to continue with logo-mode tutorial, click on `Help' ;; menu and choose `Logo-help>>Tutorial'. If you don't want to do that ;; now, click on `Files' menu, and choose `Exit Emacs'. (Answer `Yes' ;; to all questions that Emacs asks before exiting.) ;; ;; You can run logo-mode tutorial later, by simply opening one Logo ;; file in emacs (any file that has `.lg' extension), and choosing ;; `Help>>Logo-help>>Tutorial' menu. ucblogo-5.5/emacs/dot.emacs10100644000161300001330000000200007270062710013672 0ustar bhdoe;;; LOGO-MODE CHANGES *BEGIN* ;;; ;;; Do *NOT* insert your own forms between lines "LOGO-MODE CHANGES *BEGIN*" ;;; and "LOGO-MODE CHANGES *END*" . Everything between these two lines ;;; can/will be deleted during subsequent installation of logo-mode! ;; ;; This is a must! (setq auto-mode-alist (cons '("\\.lgo?\\'" . logo-mode) auto-mode-alist)) (autoload 'logo-mode "logo") ;; ;; Forcing `xterm' as terminal definition for Logo. If you prefer to use ;; `vt100' , then reverse the commenting of next two lines. To use the ;; system default terminal definition -- comment out both: (setq logo-system-type 'xterm) ;(setq logo-system-type 'vt100) ;; ;; If you don't want syntax highlighting uncomment next line. ;(setq logo-syntax-highlight nil) ;; ;; If you are not a novice (meaning emacs - mostly), uncomment next line ;(setq logo-novice-management nil) ;; ;; Next 5 are automatically inserted by MAKE - in case you used ;; make LIBLOC=some-unusual-place, or changed $(prefix) in toplevel ;; ucblogo makefile ucblogo-5.5/emacs/dot.emacs20100644000161300001330000000155707556010456013722 0ustar bhdoe;; ;; Uncomment next 2 if you want to change the default size of Logo window. ;; Default is 80 x 24. ;(setq process-term-columns 86) ;(setq process-term-rows 32) ;; ;; Next 2 are not important, but I like it this way. (setq logo-setcursor-overwrite nil) (setq logo-unbalanced-distance 4096) ;; ;; I assume you are not planning to install translated ucblogo info-manual. ;; If you are, (this goes for Croatians) then comment out next line. (setq logo-info-trans nil) ;; ;; If you have no intention to use .logo initialization file then ;; uncomment next line: ;(setq logo-load-language nil) ;; ;; If you don't want me messing with your default emacs colors, then ;; uncomment next line: ;(setq dont-mess-with-logo-colors t) ;; ;; If you don't want parens matching on cursor movement, then ;; uncomment next line: ;(setq logo-flash-on-movement nil) ;; ;;; LOGO-MODE CHANGES *END* ucblogo-5.5/emacs/tutor1.lg0100644000161300001330000000524407270062710013610 0ustar bhdoe;;; second part of logo-mode tutorial ;; Start queens with queens 8, if you want only the first result ;; To get all results use (queens 8 "false), and be prepared for ;; a long wait. (Maybe you should try 6, or 4 first?) to queens :number [:one.only "true] 1 (foreach letrec [[ ;; Define local procedure makeboard [makeboard [[n] [localmake "row cascade :n [[x] [op lput # :x]] []] [op cascade :n [[x] [op fput :row :x]] []]]] ;; Define local procedure shade [shade [[queen rest.board [offset 1] 2] [if emptyp :rest.board [op []]] [op (fput (filter [[x] [op not (or :x = (:queen - :offset) :x = :queen :x = (:queen + :offset))]] first :rest.board) (shade :queen bf :rest.board :offset + 1))]]] ;; Define local procedure put.queen [put.queen [[board result] ;; When the board is empty, we're done [if emptyp :board [push "stack :result op :one.only]] [localmake "row first :board] [localmake "queen and [not emptyp :row] [first :row]] ;; If queen not placed -- backtrack right away [op (and [:queen] [or ;; Go ahead -- try to place next queen [(put.queen (shade :queen bf :board) lput :queen :result)] ;; Nowhere to put next queen -- try to move ;; this queen to next available square [(put.queen fput bf :row bf :board :result)]])]]]] ;; Start of letrec body forms [localmake "stack []] ;; Run program and discard the output (true/false) [ignore (put.queen (makeboard :number) [])] ;; Output positions -- letrec ends here [op reverse :stack]] ;; Template for foreach [[x] [(show "position # :x)]]) end ;; Logo version of insert sort -- .logo.compiler torture test to insert.sort :lst op (reduce [[e lst] [op letrec [[ [insert [[lst] [cond [ [[emptyp :lst] [op (list :e)]] [[:e < first :lst] [op fput :e :lst]] [t [op fput first :lst (insert bf :lst)]]]]]]] [(insert :lst)]]]] lput (list last :lst) bl :lst) end ucblogo-5.5/emacs/edfunc.el0100644000161300001330000000103707270062710013610 0ustar bhdoe;; Deleting from .emacs previous logo-mode installation (defun edfunc () (goto-char (point-max)) (let ((start (re-search-backward "^[ \t]*;+[ \t]*LOGO-MODE[ \t]+CHANGES[ \t]+\\*BEGIN\\*" nil t)) (end (re-search-forward "^[ \t]*;+[ \t]*LOGO-MODE[ \t]+CHANGES[ \t]+\\*END\\*" nil t))) (and end start (not (> (- end start) 2500)) (delete-region start end))) (goto-char (point-max)) (delete-blank-lines) (or (bobp) (insert "\n\n"))) ;; temporary (defun compile-load-path () (setq load-path (cons "./" load-path)))ucblogo-5.5/emacs/logo.el0100644000161300001330000051630010150412451013300 0ustar bhdoe;;; logo.el -- Major mode for editing Logo source code ;; Copyright (C) 1998, 2000, 2001, 2003, 2004 by Hrvoje Blazevic ;; Logo.el is free software distributed under the terms ;; of the GNU General Public License, version 2, or (at your option) ;; any later version. ;; Logo.el 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. ;; This is version 3.0 completed on 15th November 2004, with ;; bits and pieces lifted from scheme.el and cmuscheme.el . ;; For more information about logo mode , comments, or bug reports, ;; send e-mail to ;;; Commentary: ;; Logo mode is written for Berkeley Logo interpreter. ;; ;; Inferior Logo mode TERMINAL ACCESS issues ;; ========================================= ;; ;; All Berkeley ;; Logo terminal access commands are available in logo ;; process buffer, as well as all normal emacs and comint mode editing ;; goodies. However, the behavior of emacs might look strange at times ;; in this mode. This is a result of two conflicting requirements. On ;; one side the need to make emacs buffer behave like a standard ;; terminal, and on the other to allow most of emacs editing niceties. ;; The most visible differences are: ;; Backspace and Delete keys will only work if the point is within input ;; line (string) limits. That also means that if you haven't entered any ;; fresh input yet, they will not work. You got no business deleting text ;; all over inferior logo buffer anyway! Yanking marked text with mouse-2 ;; works, but it *always* inserts at the beginning of input line, no ;; matter where you point with the mouse, overwriting any text found ;; there. Reason is simple - again, you got no business yanking text all ;; over inferior logo buffer (except at input line). C-k and C-y kill or ;; yank-back only the input line. C-y works the same way as mouse-2, ;; which means that if external X-selection exists, it will always use ;; that, and not the contents of the kill-ring. ;; ;; ========================================= ;; ;; The indenting style that I chose to implement here is trying to ;; follow Brian Harwey's Computer Science Logo Style (Second Edition). ;; ;; The "Style" can be described as follows: ;; ;; 1 Everything is flush left -- except ;; ;; 2 Explicit continuation lines (after the line ending with `~') ;; indent to the second word on previous line, or to same ;; column as the previous line. Explicit continuation has a ;; "sanity checker" -- 50th column, built in. This can be changed ;; by changing 'logo-max-indent' variable. ;; ;; 3 Implicit continuation lines, lines with pending `]', `)', or `}', ;; indent in several different ways. The "BOOK" uses mostly lisp ;; style indentation on logo that does not have lisp syntactical ;; form. If you want to enforce this in your code use parenthesis, ;; even if not needed. Ending the line with `[' starts something ;; that can be described as C style -- or a very long line style. ;; ;; The examples bellow are taken from CSLS: ;; ;; Lisp style (almost) ;; ;; to worldtree ;; make "world tree "world ~ ;; (list (tree "France ;; (list (tree "Paris []) ;; (tree "Dijon []) ;; (tree "Avignon []))) ;; (tree "China ;; (list ... ;; ;; Very, very long line style ;; ;; ifelse :end1 < (linenum :fib1) [ ;; print (sentence "INSERT :end1+1 (word (linenum :fib2) "- :end2)) ;; ] [ifelse :end2 < (linenum :fib2) [ ;; print (sentence "DELETE (word (linenum :fib1) "- :end1) :end2+1) ;; ] [ ;; print (sentence "CHANGE (word (linenum :fib1) "- :end1) ;; (word (linenum :fib2) "- :end2)) ;; make "dashes "true ;; ]] ;; ;; C style ? ;; ;; for [i 1 :buttons] [ ;; setitem :i :f 0 ;; make "right 0 ;; for [j 0 :i-1] [ ;; make "left :right ;; ... ;; ] ;; setitem :i :combs 1 ;; ] ;; ;; 4 Continued strings do not indent. ;; ;; All of this is implemented, and works automatically. If (in ;; certain situations) it doesn't, or you just hate it, then ;; use `~'. ;; ;;; ================================================================== ;; ;; Following lines should be added to your .emacs file: ;; ;; THIS IS A MUST! ;; (setq auto-mode-alist ;; (cons '("\\.lgo?\\'" . logo-mode) ;; auto-mode-alist)) ;; (autoload 'logo-mode "logo") ;; ;; If your Logo binary is not called 'logo', or is not on your PATH: ;; (setq logo-binary-name "your-PATH/your-logo-binary") ;; ;; To change the size of emacs frame/window for logo inferior process: ;; (setq process-term-columns 96) ;; (setq process-term-rows 48) ;; where 96 and 48 is whatever makes you happy. If this is not set, ;; logo.el will default to 80 and 24. ;; Emacs edit buffer will resize to process-term-columns, but will *not* ;; resize to process-term-rows. This works properly only with ucblogo ;; versions greater than 5.0 . ;; ;; By default emacs will run newline and indent when RET key is hit in ;; logo (edit) buffer. LFD key (C-j) will run newline only. To change this ;; behavior: ;; (setq logo-standard-indent t) ;; This will reverse RET and LFD keys. ;; ;; By default, the old text, after recalling the previous input in ;; inferior logo mode will be cleared to the end of the line. If that gets in ;; your way, set this: ;; (setq logo-setcursor-spaces-old n) ;; where n is from 0 to any number. However, spaces are never pushed beyond ;; end of the line. ;; ;; By default two spaces are pushed ahead of end of the new input in ;; inferior logo mode. If that gets in your way, set this: ;; (setq logo-setcursor-spaces-new n) ;; where n is from 0 to any number. However, spaces are never pushed beyond ;; end of the line. ;; ;; If your logo helpfiles are not in /usr/local/lib/logo/helpfiles ;; (setq logo-help-path "/your-help-path") ;; ;; If your contents file in helpfiles is not called HELPCONTENTS ;; (setq logo-helpcontents "your-helpcontents") ;; ;; If your logo info files are not in /usr/local/info/ or in ;; /usr/local/lib/logo/info ;; (setq logo-info-file "/your-info-path/ucblogo.info") ;; ;; If you have installed ucblogo info files translated into another language, ;; then set this: ;; (setq logo-info-file-trans "/your-info-path/file-name.info") ;; However, for this to work - somebody has to write translation first. To the ;; best of my knowledge only Croatian translation exists. Therefore by default ;; this is set to "/usr/local/info/ucbl-hr.info". If you change this to another ;; language you must also update the 'Help' menu entry by setting this: ;; (setq logo-info-trans "De") ;; This "De" would be in case your translation is German, but you can use ;; longer words as well. By default this is set to "Hr". ;; If you don't care for this at all set ;; (setq logo-info-trans nil) ;; With this set menu entry for translated manual will disappear. ;; ;; Emacs expects to find logo-mode tutorial files (tutorial.lg & ;; tutor1.lg) in /usr/local/lib/logo/emacs directory. If you placed these ;; files somewhere else, then set this: ;; (setq logo-tutorial-path "/your-path/") ;; ;; By default emacs allowes changing Logo language standard from ;; standard Logo to LOOPS with Language menu. If you don't want to see ;; that menu, set this: ;; (setq logo-load-language nil) ;; ;; If you don't want to use /tmp/e-logo and /tmp/DEBUG for the temporary ;; transfer and tracing info files. Make sure you have writing permission ;; in /your-path (However it is safer not to change this). ;; (setq logo-temp-file "/your-path/your-transfer-file") ;; (setq logo-debug-file "/your-path/your-debug-file") ;; ;; By default logo-mode starts with syntax highlighting enabled. If ;; you do not want that, set this: ;; (setq logo-syntax-highlight nil) ;; ;; By default logo-mode starts with novice command management enabled, ;; which limits user's access to some possibly dangerous commands. ;; If you are not a novice (meaning emacs - mostly), set this: ;; (setq logo-novice-management nil) ;; ;; By default logo-mode starts with automatic expansion of common Logo ;; abbreviations enabled, If you do not want this, set: ;; (setq logo-expand-common-abbrevs nil) ;; ;; Logo mode automatically sets the depth of inferior logo input ;; history menu to safe value for the display resolution it is running ;; on. (20 entries for 640x480, 25 for 800x600 ...) To change this ;; set following: ;; (setq logo-dynamic-menu-depth n) ;; where n is any number. However note that if you use larger number, ;; you may not see and use all menu entries. ;; ;; When logo-mode cranks up ucblogo in inferior logo buffer, the ;; xterm is passed to Logo process as terminal description. If you ;; want to change this, set the following variable: ;; (setq logo-system-type "vt100") ;; or ;; (setq logo-system-type "ansi.sys") ;; or whatever fully capable termcap definition you fancy. ;; ;; The following should be set if your system is *very* slow, or heavily ;; overloaded at times: ;; ;; To change the maximum distance for checking unbalanced parentheses ;; (setq logo-unbalanced-distance 2048) ;; This should still be a reasonable value (default is 4096). ;; ;; For default filter timer problems; ;; (setq logo-filter-timer n) ;; `n' = 2 by default, which should work well for P133 or comparable system. ;; P6/200 works well with 1, but P60 needs 5. These figures are given just ;; as an indication. If you suspect timing problems with default filter, ;; carry out the following test: ;; ;; repeat 1000 [setcursor list random 75 random 24 type standout cursor] ;; ;; If you find more than one `?' after the loop has completed, you have to ;; increase `n'. This will *not* slow down your system's normal response. ;; What it will do is this: in case of *very* long standout (295 characters ;; or longer - a situation that Logo itself can't handle well) you will have ;; to wait `n' seconds to be notified, and to see the portion of output that ;; Logo did print out. That's why I set default to 2 --- to avoid creating ;; the illusion of a hang-up system. ;; ;; ;; ===***=== ;; ;; The *BEST* way to start logo mode is opening one logo source file ;; and using Logo-start menu (on menu-bar) to fire up Logo. Of the ;; two choices there (Run Logo Other Frame, and Run Logo Same Window), ;; the best is Other Frame. Same window is there just for historical reasons. ;; ;; "Logo source file" means file with extension '.lg' or '.lgo', or ;; a file that starts with magic characters: ';;; -*- logo -*-'. ;; ;; ===***=== ;; ;; Basic features and functionality of logo.el, are about the same ;; as cmuscheme.el, therefore no detailed instructions are necessary. ;; However, as Logo probably attracts younger users than Scheme, I have ;; included menu-bar equivalents for most of standard editing and ;; process-communication commands. ;; ;; Help system is very simple and low-tech. Mouse-3 in edit buffer ;; opens help file for the selected word. If help file for the word ;; does not exist, HELPCONTENTS file is visited. From HELPCONTENTS ;; user can select (mouse-3) and view as many help files as he wants. ;; To quit this cycle hit `q' in HELPCONTENS. ;; ;; Debug menu in Logo-process buffer, offers a simple mouse selection ;; for tracing and stepping. Mouse bindings are as in XFM manager. ;; Mouse-1 de-selects everything previously selected in category ;; (procedures, variables, properties) and selects chosen name. ;; Mouse-2 toggles selection for name. ;; Mouse-3 selects and quits debug buffer. `q' key also quits buffer ;; and sends the selected contents list to Logo. ;; ;; Names that were TRACED or STEPPED before the debug buffer opens, will ;; be highlighted and placed in parentheses. Highlighting will be turned ;; on/off with mouse action (to reflect user's choice). Parentheses (around ;; previously chosen names) will, however, remain. I choose to call this ;; a feature -- although some will probably call it laziness. ;; ;;; ================================================================== (require 'comint-logo) (require 'timer) (require 'font-lock) (require 'letrec) (require 'thingatpt) ;;; code (and (< emacs-major-version 21) (defalias 'mapc 'mapcar)) ;; making sure that global .emacs setings do not interfere ;; with logo-mode syntax highlighting settings (global-font-lock-mode -1) ;;; ============= Syntax Stuff ============== (defvar logo-mode-syntax-table nil "") (if (not logo-mode-syntax-table) (let ((i 0)) (setq logo-mode-syntax-table (make-syntax-table)) (set-syntax-table logo-mode-syntax-table) ;; Default is symbol constituent (while (< i 256) (modify-syntax-entry i "- ") (setq i (1+ i))) ;; Standard word constituents (setq i ?0) (while (<= i ?9) (modify-syntax-entry i "w ") (setq i (1+ i))) (setq i ?A) (while (<= i ?Z) (modify-syntax-entry i "w ") (setq i (1+ i))) (setq i ?a) (while (<= i ?z) (modify-syntax-entry i "w ") (setq i (1+ i))) ;; Logo specific word constituents (modify-syntax-entry ?. "w ") (modify-syntax-entry ?: "w ") (modify-syntax-entry ?? "w ") (modify-syntax-entry ?` "w ") (modify-syntax-entry ?_ "w ") ;; The rest is to handle names in CSLS match program (modify-syntax-entry ?^ "w ") (modify-syntax-entry ?# "w ") (modify-syntax-entry ?@ "w ") (modify-syntax-entry ?& "w ") (modify-syntax-entry ?! "w ") (modify-syntax-entry ?' "w ") ;; Whitespace (modify-syntax-entry ?\t " ") (modify-syntax-entry ?\n "> ") (modify-syntax-entry ?\f " ") (modify-syntax-entry ?\r " ") (modify-syntax-entry ?\ " ") ;; Symbol delimiters (modify-syntax-entry ?\( "() ") (modify-syntax-entry ?\) ")( ") (modify-syntax-entry ?{ "(} ") (modify-syntax-entry ?} "){ ") (modify-syntax-entry ?[ "(] ") (modify-syntax-entry ?] ")[ ") ;; Quotes (modify-syntax-entry ?\| "\" ") ;; Comments (modify-syntax-entry ?\; "< ") ;; Special characters (modify-syntax-entry ?, "_ p") ;; (modify-syntax-entry ?\" "_ p") (modify-syntax-entry ?\" "w ") ;; Escape character (modify-syntax-entry ?\\ "\\ "))) ;;; ================ Abbreviation table =============== ;;; ;;; Common Logo abbreviations are expanded before 'space', ;;; 'newline', ')', ']', and '}'. ;;; ;;; If you do not want particular expansion to happen, escape ;;; the trigger character; e.g.: Esc SPC, Esc newline ... (defvar logo-expand-common-abbrevs t "default expansion behavior") (defvar logo-mode-abbrev-table nil "Table that holds Logo common abbreviations") (or logo-mode-abbrev-table (define-abbrev-table 'logo-mode-abbrev-table '(("op" "output") ("pr" "print") ("ct" "cleartext") ("setpc" "setpencolor") ("er" "erase") ("settc" "settextcolor") ("erf" "erasefile") ("st" "showturtle") ("ss" "splitscreen") ("bk" "back") ("bg" "background") ("rc" "readchar") ("rcs" "readchars") ("rl" "readlist") ("ts" "textscreen") ("bf" "butfirst") ("rw" "readword") ("bfs" "butfirsts") ("fd" "forward") ("bl" "butlast") ("fs" "fullscreen") ("cs" "clearscreen") ("ht" "hideturtle") ("pc" "pencolor") ("rt" "right") ("pd" "pendown") ("co" "continue") ("pe" "penerase") ("iff" "iffalse") ("ift" "iftrue") ("ppt" "penpaint") ("px" "penreverse") ("pu" "penup") ("se" "sentence") ("setbg" "setbackground") ("seth" "setheading") ("lt" "left") ("ed" "edit")))) (defun logo-bypass-abbrev-spc () "Disabling Logo common abbrev expansion after space" (interactive) (logo-bypass-abbrev (lambda () (insert ?\ )))) (defun logo-bypass-abbrev-nl () "Disabling Logo common abbrev expansion after newline" (interactive) (logo-bypass-abbrev (lambda () (newline-and-indent)))) (defun logo-bypass-abbrev-b () "Disabling Logo common abbrev expansion after ]" (interactive) (logo-bypass-abbrev (lambda () (insert ?\])))) (defun logo-bypass-abbrev-p () "Disabling Logo common abbrev expansion after )" (interactive) (logo-bypass-abbrev (lambda () (insert ?\))))) (defun logo-bypass-abbrev-c () "Disabling Logo common abbrev expansion after }" (interactive) (logo-bypass-abbrev (lambda () (insert ?\})))) (defun logo-bypass-abbrev (thunk) (let ((abbrev abbrev-mode)) (and abbrev (abbrev-mode -1)) (funcall thunk) (and abbrev (abbrev-mode 1)))) ;;; ================ Logo mode variables ================= (defvar dont-mess-with-logo-colors nil "Set highlighting for edit buffer") (defvar logo-defun-start-rgx nil "Start of Logo definition common string") (defvar logo-defun-start nil "Start of Logo definition") (defvar logo-defun-end nil "End of Logo definition") (defvar logo-defun-lock-start nil "Start of Logo definition - lock-mode") (defvar logo-defun-lock-end nil "End of Logo definition - lock-mode") (defvar logo-defun-lock-define nil "Start of Logo define or .defmacro") (defvar logo-max-indent nil "Max indent column for ~ indenting") (defvar logo-min-indent nil "Min indent column") (defvar logo-xcontinuation-line nil "Explicit Logo continuation line") (defvar logo-comment-line nil "Comment only line") (defvar logo-unbalanced-distance 4096 "Search distance for end of sexp") (defvar logo-instring-distance nil "Search distance string bounds") (defvar logo-syntax-highlight t "Turn on syntax highlighting by default") (defvar logo-novice-management t "Turn on disabling `dangerous' commands") (defvar logo-flash-on-movement t "Turn on parens matching on cursor movement") (defvar logo-lazy-lock-mode nil "Use standard font-lock as a default") (defvar logo-current-os-system 'undecided-unix "Change this to 'DOS if not working on *nix system") ;; Pacifying the compiler (defvar font-lock-mode-maximum-decoration t) (defvar font-lock-use-default-fonts t) (defvar font-lock-use-default-colors t) (defun logo-mode-variables () (set-syntax-table logo-mode-syntax-table) (setq local-abbrev-table logo-mode-abbrev-table) ;; Indenting stuff (make-local-variable 'paragraph-start) (make-local-variable 'paragraph-separate) (setq paragraph-start "$\\|^^L") (setq paragraph-separate "[ \t]*$\\|^^L") (make-local-variable 'paragraph-ignore-fill-prefix) (setq paragraph-ignore-fill-prefix t) (make-local-variable 'indent-line-function) (setq indent-line-function 'logo-indent-line) (setq indent-tabs-mode nil) (make-local-variable 'words-include-escapes) (setq words-include-escapes t) ;; Comments stuff (make-local-variable 'parse-sexp-ignore-comments) (setq parse-sexp-ignore-comments t) (make-local-variable 'comment-start) (setq comment-start ";") (make-local-variable 'comment-start-skip) ;; Look within the line for a ; following an even number of backslashes ;; after either a non-backslash or the line beginning. (setq comment-start-skip "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+[ \t]*") (make-local-variable 'parse-sexp-ignore-comments) (setq parse-sexp-ignore-comments t) ;; Logo mode frame colors (or dont-mess-with-logo-colors (condition-case nil (setq default-frame-alist '( ;; This will look nice if you set following in ~/.Xdefaults. ;; emacs*Background: DarkSlateGray ;; emacs*Foreground: Wheat ;; emacs.pointerColor: Orchid (cursor-color . "red") (cursor-type . box) (foreground-color . "black") (background-color . "honeydew"))) (error nil))) ;; Syntax highlighting stuff (logo-syntax-colors)) (defun logo-syntax-colors () (make-local-variable 'font-lock-defaults) (setq font-lock-defaults '(logo-font-lock-keywords nil t)) (or dont-mess-with-logo-colors (condition-case nil (progn (make-face-bold 'bold-italic) (set-face-foreground 'bold-italic "Blue") (setq font-lock-mode-maximum-decoration t) (setq font-lock-use-default-fonts nil) (setq font-lock-use-default-colors nil) (copy-face 'bold 'font-lock-string-face) (set-face-foreground 'font-lock-string-face "RosyBrown") (copy-face 'italic 'font-lock-comment-face) (set-face-foreground 'font-lock-comment-face "Firebrick") (copy-face 'bold 'font-lock-function-name-face) (set-face-foreground 'font-lock-function-name-face "MediumBlue") (copy-face 'bold 'font-lock-variable-name-face) (set-face-foreground 'font-lock-variable-name-face "SteelBlue") (copy-face 'bold 'font-lock-keyword-face) (set-face-foreground 'font-lock-keyword-face "Purple") ;; used for quoted words -- just being lazy (copy-face 'bold 'font-lock-type-face) (set-face-foreground 'font-lock-type-face "MidnightBlue") (set-face-background 'region "LightCyan3") (set-face-foreground 'modeline "red") (set-face-background 'modeline "bisque")) (error nil)))) (if (not logo-max-indent) (setq logo-max-indent 50)) (if (not logo-min-indent) (setq logo-min-indent 3)) ;; Regex for matching the explicit continuation line. ;; Looking for a line that can consist of anything, as long as it does ;; have tilde at the end, followed by white spaces and end of line. It ;; must either have beginning of line, or can not have odd number of ;; backslashes, or newline directly in front of tilde. (if (not logo-xcontinuation-line) (setq logo-xcontinuation-line ".*\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*~[ \t]*$")) ;; Matching Logo procedure definition start - basic string. ;; Look for a word that starts Logo definition followed by at least ;; one space and a word constituent or a comment ending with ~ or ;; xcontinuation line. (or logo-defun-start-rgx (setq logo-defun-start-rgx (concat "\\(to\\|.macro\\)\\([ \t]+\\w+\\|" "[ \t]*;[^~\n]*~[ \t]*$\\|" "[ \t]*~[ \t]*$\\)"))) ;; Matching Logo procedure definition start. ;; Nothing but white spaces on a line before the basic string. (or logo-defun-start (setq logo-defun-start (concat "^[ \t]*" logo-defun-start-rgx))) ;; Look for a line that starts with word END followed by zero or more spaces, ;; and end of line or comment start. This is more restrictive than Logo. ;; Logo will allow anything after END. (or logo-defun-end (setq logo-defun-end "^[ \t]*\\(end\\)[ \t]*\\($\\|;\\)")) ;; Font-lock mode - handling to and .macro - must be flush left (or logo-defun-lock-start (setq logo-defun-lock-start (concat "^" logo-defun-start-rgx))) ;; Font-lock mode - handling end - must be flush left (or logo-defun-lock-end (setq logo-defun-lock-end "^\\(end\\)[ \t]*\\($\\|;\\)")) ;; Font-lock mode - handling define and .defmacro (or logo-defun-lock-define (setq logo-defun-lock-define (concat "\\(^\\|[ \t]+\\)\\(define\\|.defmacro\\)\\([ \t]+\"?\\w+\\|" "[ \t]*;[^~\n]*~[ \t]*$\\|" "[ \t]*~[ \t]*$\\)"))) ;; Defining how and when syntax highlighting happens (setq font-lock-mode-maximum-decoration t) (and logo-lazy-lock-mode (progn (defvar font-lock-support-mode 'lazy-lock-mode "") (defvar lazy-lock-defer-time 1 "") (defvar lazy-lock-defer-contextually t "") (defvar lazy-lock-stealth-time 3 "")) (fast-lock-mode 1)) (defvar logo-font-lock-keywords (list (cons "\\<:\\w+\\>" 'font-lock-variable-name-face) ;; used for quoted words (cons "\\<\"\\w+\\>" 'font-lock-type-face) (list logo-defun-lock-define 2 'font-lock-keyword-face 'append) (list logo-defun-lock-define 3 'font-lock-function-name-face 'append) (list logo-defun-lock-start 1 'font-lock-keyword-face 'append) (list logo-defun-lock-start 2 'font-lock-function-name-face 'append) (list logo-defun-lock-end 1 'font-lock-keyword-face 'append)) "Default expressions to highlight in Logo mode.") ;; Comment only line - for indenting purposes (if (not logo-comment-line) (setq logo-comment-line "^[ \t]*;+[^\n]*$")) (defvar logo-reindent-now nil "Do we reindent auto-magically after next character?") (make-variable-buffer-local 'logo-reindent-now) (defvar logo-buffer nil "Name of buffer running logo inferior process.") (defvar logo-edit-buflist nil "List holding names of logo edit buffers") (defvar logo-frames nil "If t starting 2 frame operation.") (defvar logo-binary-name nil "Logo binary name") (if logo-binary-name nil (setq logo-binary-name "logo")) ;; Change this to your binary ;; This sets the temporary transfer file to /tmp/e-logoxxxxxx ;; Make sure you have writing permission in /tmp , or wherever you ;; change this to. (defvar logo-temp-file nil "Name of load file.") (if logo-temp-file nil (setq logo-temp-file (make-temp-name "/tmp/e-logo"))) (defvar logo-help-path nil "Logo helpfiles path.") (if (not logo-help-path) (setq logo-help-path "/usr/local/lib/logo/helpfiles/")) (defvar logo-helpcontents nil "Logo helpcontents file.") (if (not logo-helpcontents) (setq logo-helpcontents "HELPCONTENTS")) (defvar logo-tutorial-path "/usr/local/lib/logo/emacs/" "Logo-mode tutorial files") (defvar logo-info-file nil "Variable holding full path to ucblogo info file.") (or logo-info-file (setq logo-info-file "/usr/local/info/ucblogo.info")) (defvar logo-info-trans "(Hr)" "Variable holding language name extension for info translation. Set by default to Croatian. To clear this menu enty set it to nil.") (defvar logo-info-file-trans nil "Variable holding full path to translated info file.") (or logo-info-file-trans (setq logo-info-file-trans "/usr/local/info/ucbl-hr.info")) ;; Try not to write programs with input prompts that look like ;; Logo REPL prompt -- `?' flush left with only one space following. (defvar logo-busy-p nil "Is Logo idle or running a program?") ;; Width and height of emacs window for Logo inferior process are ;; set to 80 and 24, which is what Logo defaults to if it can not ;; get sizes from termcap. This is also vt100 default. (defvar process-term-columns nil "Width of terminal for setcursor mode.") (defvar process-term-rows nil "Height of terminal for setcursor mode.") (or process-term-columns (setq process-term-columns 80)) (or process-term-rows (setq process-term-rows 24)) (defvar logo-mouse-pos nil "Mouse position.") (defvar logo-standard-indent nil "By default RET runs newline & indent.") (defvar logo-mode-hook nil "*Hook for customizing logo mode.") (defun logo-initialize-hooks () (make-local-hook 'view-mode-hook) (add-hook 'view-mode-hook 'logo-help-function) (make-local-hook 'post-command-hook) (setq post-command-hook nil) (and logo-flash-on-movement ;; Set-up parens matching (progn (require 'paren) (show-paren-mode 1) (setq show-paren-style 'mixed) ;; echo matched text, if off screen (defadvice show-paren-function (before verbal-off-screen) (let ((message-log-max)) (and (char-equal (char-syntax (preceding-char)) ?\)) (blink-matching-open)))) (ad-activate 'show-paren-function) (setq blink-matching-delay 0))) (add-hook 'post-command-hook 'logo-post-command-function) (add-hook 'kill-emacs-hook (lambda () (or (not (file-readable-p logo-temp-file)) (delete-file logo-temp-file)) (or (not (file-readable-p logo-syntax-file)) (delete-file logo-syntax-file)))) (make-local-hook 'kill-buffer-hook) (add-hook 'kill-buffer-hook (lambda () (setq logo-edit-buflist (delete (buffer-name) logo-edit-buflist))))) ;;; ================ Key definitions & menus ================= (defun logo-mode-commands (map) ;; Next two could be dangerous (unwind-protect (progn ;; Removing mule menu from global map (defvar logo-mode-mule-menu (copy-keymap mule-menu-keymap)) (global-unset-key [menu-bar mule]))) (unwind-protect (progn ;; Removing tools menu from global map (defvar logo-mode-tools-menu (copy-keymap menu-bar-tools-menu)) (global-unset-key [menu-bar tools]))) (define-key map "\t" 'logo-indent-line) (if logo-standard-indent ;; gnu convention (define-key map "\C-j" 'newline-and-indent) ;; switching RET & LFD keys (define-key map "\C-j" 'newline) (define-key map "\C-m" 'newline-and-indent)) ;; allegro cl (define-key map "\C-\M-q" 'logo-indent-definition) (define-key map "\M-;" 'logo-comment-region) ;; allegro cl (define-key map "\C-c;" 'logo-uncomment-region) ;; allegro cl (define-key map "\C-cl" 'logo-toggle-to-logo) (define-key map "\C-cb" 'logo-send-buffer) ;; cmuscheme48 (define-key map "\C-cr" 'logo-send-region) (define-key map "\C-c\C-b" 'logo-send-buffer-and-go) ;; cmuscheme48 (define-key map "\C-c\C-r" 'logo-send-region-and-go) ;; gnu convention (define-key map "\M-\C-x" 'logo-send-definition) ;; gnu convention (send sexp) (define-key map "\C-x\C-e" 'logo-send-instruction-line) (define-key map "\M-\t" 'logo-dabbrev-keywords) ;; disabling common abbrev expansion just this once (define-key map [?\e ?\ ] 'logo-bypass-abbrev-spc) (define-key map [?\e ?\r] 'logo-bypass-abbrev-nl) (define-key map [?\e ?\]] 'logo-bypass-abbrev-b) (define-key map [?\e ?\)] 'logo-bypass-abbrev-p) (define-key map [?\e ?\}] 'logo-bypass-abbrev-c) ;; this is just to have these keys present in mode description (define-key map "\M-/" 'dabbrev-expand) (define-key map [?\e ?\^/] 'dabbrev-completion) ;; mouse bindings (define-key map [down-mouse-2] 'mouse-set-point) (define-key map [down-mouse-3] 'logo-mouse-set-point) (define-key map [mouse-3] 'logo-help) ;; Menu bar ;; Logo-start menu (define-key map [menu-bar logo-start] (cons "Logo-start" (make-sparse-keymap "Logo-start"))) (define-key map [menu-bar logo-start run-logo-same-window] '("Run Logo Same Window" . run-logo-same-window)) (define-key map [menu-bar logo-start run-logo-other-frame] '("Run Logo Other Frame" . run-logo-other-frame)) ;; Logo-send menu (define-key map [menu-bar logo-send] (cons "Logo-send" (make-sparse-keymap "Logo-send"))) (define-key map [menu-bar logo-send toggle-to-logo] '("Go to Logo" . toggle-to-logo)) (define-key map [menu-bar logo-send separator-send-1] '("--")) (define-key map [menu-bar logo-send logo-send-buffer] '("Send Buffer" . logo-send-buffer)) (define-key map [menu-bar logo-send logo-send-region] '("Send Region" . logo-send-region)) (define-key map [menu-bar logo-send logo-send-definition] '("Send Definition" . logo-send-definition)) (define-key map [menu-bar logo-send logo-send-instruction-line] '("Send Instruction" . logo-send-instruction-line)) (define-key map [menu-bar logo-send separator-send-2] '("--")) (define-key map [menu-bar logo-send logo-send-buffer-and-go] '("Send Buffer & Go" . logo-send-buffer-and-go)) (define-key map [menu-bar logo-send logo-send-region-and-go] '("Send Region & Go" . logo-send-region-and-go)) (define-key map [menu-bar logo-send logo-send-definition-and-go] '("Send Definition & Go" . logo-send-definition-and-go)) (define-key map [menu-bar logo-send logo-send-instruction-line-and-go] '("Send Instruction & Go" . logo-send-instruction-line-and-go)) ;; Logo-edit menu (define-key map [menu-bar logo-edit] (cons "Logo-edit" (make-sparse-keymap "Logo-edit"))) (define-key map [menu-bar logo-edit logo-customize] (cons "Preferences" (make-sparse-keymap "Preferences"))) (define-key map [menu-bar logo-edit logo-customize logo-toggle-common-expansion] '("Toggle Abbreviation Expansion" . abbrev-mode)) (define-key map [menu-bar logo-edit logo-customize logo-toggle-syntax-highlight] '("Toggle Syntax Highlighting" . logo-font-lock-mode)) (define-key map [menu-bar logo-edit logo-customize logo-toggle-novice] '("Toggle Novice Management" . logo-toggle-novice)) (define-key map [menu-bar logo-edit separator-edit-1] '("--")) (define-key map [menu-bar logo-edit logo-uncomment-definition] '("Uncomment Definition" . logo-uncomment-definition)) (define-key map [menu-bar logo-edit logo-uncomment-region] '("Uncomment Region" . logo-uncomment-region)) (define-key map [menu-bar logo-edit logo-comment-definition] '("Comment Out Definition" . logo-comment-definition)) (define-key map [menu-bar logo-edit logo-comment-region] '("Comment Out Region" . logo-comment-region)) (define-key map [menu-bar logo-edit separator-edit-2] '("--")) (define-key map [menu-bar logo-edit logo-indent-buffer] '("Indent Buffer" . logo-indent-buffer)) (define-key map [menu-bar logo-edit logo-indent-definition] '("Indent Definition" . logo-indent-definition)) (define-key map [menu-bar logo-edit separator-edit-3] '("--")) (define-key map [menu-bar logo-edit logo-remove-check] '("Remove Syntax Check" . logo-remove-check)) (define-key map [menu-bar logo-edit logo-typo-region] '("Syntax Check Region" . logo-typo-region)) (define-key map [menu-bar logo-edit logo-typo-buffer] '("Syntax Check Buffer" . logo-typo-buffer)) (unwind-protect (define-key map [menu-bar mule] (cons "Mule" logo-mode-mule-menu))) (unwind-protect (define-key map [menu-bar tools] (cons "Tools" logo-mode-tools-menu))) ;; Adding Logo help to emacs Help menu (and (memq 'help-menu menu-bar-final-items) (define-key global-map [menu-bar help-menu separator-l-help] '("--")) (define-key global-map [menu-bar help-menu logo-help] (cons "Logo-help" (make-sparse-keymap "Logo-help"))) (define-key global-map [menu-bar help-menu logo-help logo-tutorial] '("Tutorial" . logo-tutorial)) (define-key global-map [menu-bar help-menu logo-help separator] '("--")) ;; Include this if info translation set (if logo-info-trans (define-key global-map [menu-bar help-menu logo-help logo-info-t] (cons (concat "User Manual " logo-info-trans) 'logo-show-info-trans)) t) (define-key global-map [menu-bar help-menu logo-help loops-info] '("LOOPS User Manual" . loops-show-info)) (define-key global-map [menu-bar help-menu logo-help logo-info] '("Logo User Manual" . logo-show-info)) (define-key global-map [menu-bar help-menu logo-help logo-helpcontents] '("Help Contents" . logo-show-helpcontents))) ;; Adding open new Logo file to emacs Files menu (define-key global-map [menu-bar files separator-logo-file] '("--")) (define-key global-map [menu-bar files logo-mode-files] (cons "Logo-mode Files" (make-sparse-keymap "Logo-mode-files"))) (define-key global-map [menu-bar files logo-mode-files logo-mode-on] '("Convert to Logo-mode" . logo-mode-on)) (define-key global-map [menu-bar files logo-mode-files logo-file] '("Open Logo File..." . logo-open-file))) (defvar logo-mode-map nil) (if (not logo-mode-map) (progn (setq logo-mode-map (make-sparse-keymap)) (logo-mode-commands logo-mode-map))) (setplist 'logo-tutorial '(menu-enable (and (file-readable-p (concat logo-tutorial-path "tutorial.lg")) (equal major-mode 'logo-mode)))) (setplist 'logo-typo-buffer '(menu-enable (let ((debug-buf (get-buffer (file-name-nondirectory logo-debug-file)))) (and (not debug-buf) *logo-builtin-names* logo-syntax-highlight font-lock-fontified (get-buffer-process logo-buffer) (not logo-busy-p))))) (setplist 'logo-typo-region '(menu-enable (let ((debug-buf (get-buffer (file-name-nondirectory logo-debug-file)))) (and (not debug-buf) *logo-builtin-names* logo-syntax-highlight font-lock-fontified (get-buffer-process logo-buffer) (not logo-busy-p) (mark))))) (setplist 'logo-remove-check '(menu-enable (let ((debug-buf (get-buffer (file-name-nondirectory logo-debug-file)))) (and (not debug-buf) *logo-builtin-names* logo-syntax-highlight font-lock-fontified (get-buffer-process logo-buffer) (not logo-busy-p))))) (setplist 'logo-font-lock-mode '(menu-enable logo-syntax-highlight)) (setplist 'logo-show-helpcontents '(menu-enable (and (let ((helpcontents (get-buffer logo-helpcontents))) (or (not helpcontents) (not (get-buffer-window helpcontents t)))) (equal major-mode 'logo-mode)))) (setplist 'loops-show-info '(menu-enable (and (let ((info-buf (get-buffer "*info*"))) (or (not info-buf) (not (get-buffer-window info-buf t)))) (or (equal major-mode 'logo-mode) (equal major-mode 'inferior-logo-mode))))) (setplist 'logo-mode-on '(menu-enable (and (equal major-mode 'fundamental-mode) (not logo-debug-mode) (not logo-helpcontents-mode) (not logo-help-mode)))) (setplist 'make-frame-command '(menu-enable (equal major-mode 'logo-mode))) (setplist 'logo-open-file '(menu-enable (equal major-mode 'logo-mode))) (setplist 'logo-show-info-trans '(menu-enable (and (let ((info-buf (get-buffer "*info*"))) (or (not info-buf) (not (get-buffer-window info-buf t)))) (or (file-readable-p logo-info-file-trans) (file-readable-p (concat logo-info-file-trans ".gz"))) (or (equal major-mode 'logo-mode) (equal major-mode 'inferior-logo-mode))))) (setplist 'run-logo-same-window '(menu-enable (not (get-buffer-process logo-buffer)))) (setplist 'run-logo-other-window '(menu-enable (not (get-buffer-process logo-buffer)))) (setplist 'run-logo-other-frame '(menu-enable (not (get-buffer-process logo-buffer)))) (setplist 'logo-comment-region '(menu-enable (mark))) (setplist 'logo-uncomment-region '(menu-enable (mark))) (setplist 'logo-send-instruction-line-and-go '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (get-buffer-window "*logo*" t)))) (setplist 'logo-send-instruction-line '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-send-definition-and-go '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (get-buffer-window "*logo*" t)))) (setplist 'logo-send-definition '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-send-buffer-and-go '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (get-buffer-window "*logo*" t)))) (setplist 'logo-send-buffer '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-send-region '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (mark)))) (setplist 'logo-send-region-and-go '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (mark) (get-buffer-window "*logo*" t)))) (defalias 'toggle-to-logo 'logo-toggle-to-logo) (put 'toggle-to-logo 'menu-enable '(get-buffer-process logo-buffer)) (defalias 'toggle-to-edit 'logo-toggle-to-logo) (put 'toggle-to-edit 'menu-enable t) (put 'toggle-to-logo 'menu-alias t) (put 'toggle-to-edit 'menu-alias t) ;;; ======================= Novice package ======================= (defun logo-novice-commands (&optional enable) "Disabling `dangerous' commands." (let ((toggle (and (not enable) "\nYOU *PROBABLY* DON'T WANT THIS!\n\n")) (commands '( ;; List of emacs & comint commands to be disabled 'kill-this-buffer 'make-frame-on-display 'ediff-files 'ediff-merge-files-with-ancestor 'ediff-merge-buffers 'ediff-merge-buffers-with-ancestor 'ediff-merge-directories 'ediff-merge-directories-with-ancestor 'ediff-merge-revisions 'ediff-merge-revisions-with-ancestor 'ediff-merge-directory-revisions 'ediff-merge-directory-revisions-with-ancestor 'ediff-patch-file 'ediff-patch-buffer 'ediff-documentation 'ediff-show-registry 'ediff-toggle-multiframe 'vc-register 'vc-directory 'gnus 'rmail 'compose-mail 'calendar 'grep 'compile 'gdb 'facemenu-set-read-only 'facemenu-set-invisible 'facemenu-set-intangible 'facemenu-remove-special 'set-justification-none 'set-justification-left 'set-justification-right 'set-justification-full 'set-justification-center 'increase-left-margin 'decrease-left-margin 'increase-right-margin 'decrease-right-margin 'facemenu-remove-face-props 'facemenu-remove-all 'list-text-properties-at 'list-faces-display 'list-colors-display 'find-tag 'toggle-input-method 'set-input-method 'set-buffer-file-coding-system 'universal-coding-system-argument 'set-selection-coding-system 'set-next-selection-coding-system 'view-hello-file 'toggle-global-lazy-font-lock-mode 'toggle-text-mode-auto-fill 'toggle-uniquify-buffer-names 'toggle-debug-on-error 'toggle-debug-on-quit 'comint-dynamic-complete 'comint-dynamic-complete-filename 'comint-replace-by-expanded-filename ))) ;; Really -- there should be a `foreach' to do this! (mapcar (lambda (x) (eval (list 'put x ''disabled toggle))) commands) (message (concat "Novice command management " (if enable "Disabled!" "Enabled!"))))) (and logo-novice-management (logo-novice-commands)) (defun logo-toggle-novice () "Toggle novice commands management." (interactive) (if logo-novice-management (progn (setq logo-novice-management nil) (logo-novice-commands t)) (setq logo-novice-management t) (logo-novice-commands))) ;;; ======================= dabbrev stuff ======================= (defvar dabbrev-search-these-buffers-only nil "") ;; Making sure that completion window is deleted (define-key completion-list-mode-map "\C-m" 'logo-choose-completion) (define-key completion-list-mode-map [mouse-2] 'logo-mouse-choose-completion) (if (get-buffer " *logo-names*") nil (save-excursion (set-buffer (get-buffer-create " *logo-names*")) (insert-file-contents (concat logo-help-path logo-helpcontents)) (toggle-read-only 1) (skip-chars-forward "^:") (beginning-of-line 2) (narrow-to-region (point) (point-max)))) (defun logo-dabbrev-setup () "Setting variables for dynamic abbreviation expansion." (set (make-local-variable 'dabbrev-abbrev-skip-leading-regexp) "[:\"]") (set (make-local-variable 'dabbrev-case-fold-search) nil) (set (make-local-variable 'dabbrev-case-replace) nil) (set (make-local-variable 'dabbrev-check-all-buffers) nil) (set (make-local-variable 'dabbrev-search-these-buffers-only) nil) (set (make-local-variable 'dabbrev-select-buffers-function) (function (lambda nil (mapcar 'get-buffer logo-edit-buflist))))) (defun logo-dabbrev-keywords () "Try to expand the word at point, looking for completions in Logo HELPCONTENTS file. If not unique, show a window with all possible completions." (interactive) (unwind-protect (progn (setq dabbrev-search-these-buffers-only (list (get-buffer " *logo-names*"))) (dabbrev-completion)) (setq dabbrev-search-these-buffers-only nil))) (defun logo-mouse-choose-completion (event) "Delete completions window if not in `Logo other window' mode." (interactive "@e") (mouse-choose-completion event) ;; If this was invoked from inferior logo buffer, continue with ;; `setcursor-copy-expansion' function (if (string= (buffer-name completion-reference-buffer) " setcursor-tmp") (setcursor-copy-expansion) (condition-case nil (delete-completion-window) (error nil)))) (defun logo-choose-completion () "Delete completions window if not in `Logo other window' mode." (interactive) (choose-completion) ;; If this was invoked from inferior logo buffer, continue with ;; `setcursor-copy-expansion' function (if (string= (buffer-name completion-reference-buffer) " setcursor-tmp") (setcursor-copy-expansion) (condition-case nil (delete-completion-window) (error nil)))) ;;; ======================= Tutorial ============================= (defun logo-tutorial () "Start logo-mode tutorial." (interactive) (let ((tutorial (concat logo-tutorial-path "tutorial.lg")) (tutor1 (concat logo-tutorial-path "tutor1.lg"))) (if (file-readable-p tutorial) (progn (if (file-readable-p tutor1) (progn ;; Just copying tutor1.lg to ~/ directory (find-file tutor1) (write-file (substitute-in-file-name "$HOME")) (kill-buffer (current-buffer)))) (find-file tutorial) (write-file (substitute-in-file-name "$HOME"))) (error "Can't find tutorial.lg file -- see logo-tutorial-path variable")))) ;;; ======================= We start here ======================== ;;;###autoload (defun logo-mode () "Major mode for editing Logo source code. Important stuff to remember while writing Logo source in emacs logo mode: You can leave blank lines inside Logo procedure definitions, and you do not have to leave blank lines between two definitions. This last one is unwise, though -- you will speed things up if you do. However, you can *not* leave blank lines inside Logo string constants. This will cause problems with indenting and procedure sending code. Most of usual Lisp/Scheme mode commands are implemented here. You can: Indent a line Indent a procedure definition Comment out a region Uncomment a region Send region to Logo (and go) Send buffer to Logo (and go) Send procedure to Logo (and go) Send instruction line to Logo (and go) Complete Logo name, based on names in HELPCONTENTS file. Complete Logo name, based on names you used before. Toggle between logo-edit and logo-process buffers (with prefix toggles to older edit-buffers, if more than one exist) Help for `procedure' is invoked by clicking mouse-3 on `procedure' \\{logo-mode-map}" (interactive) (kill-all-local-variables) (logo-mode-variables) (logo-mode-initialize) (logo-initialize-hooks) ;; initialize abbrev mode (and logo-expand-common-abbrevs (abbrev-mode 1)) (run-hooks 'logo-mode-hook)) (defun logo-mode-initialize () ;; Making sure that display is set the way Logo expects it! ;; Need one more to put 80 in one row ;; If frame height less than process-term-rows, enlarging it! (set-frame-width (window-frame (selected-window)) (1+ process-term-columns) process-term-columns) (setq pop-up-frame-alist (list (cons 'width (1+ process-term-columns)) (cons 'height (+ process-term-rows 2)))) (let ((height (frame-height))) (or (>= height (+ process-term-rows 2)) (set-frame-height (window-frame (selected-window)) (+ process-term-rows 2)))) ;; Overriding any user settings ;; In Mandrake Linux 6.1 some joker decided to set transient-mode-mark ;; globally, and that is NOT a good idea! (setq transient-mark-mode nil) (setq truncate-lines nil) (auto-fill-mode -1) ;; (use-local-map logo-mode-map) (setq major-mode 'logo-mode) (setq mode-name "Logo") (add-to-list 'logo-edit-buflist (buffer-name)) (logo-dabbrev-setup) ;; Starting syntax highlighting (if logo-syntax-highlight (logo-font-lock-mode 1) (logo-font-lock-mode -1))) (defun logo-mode-on (&optional kill) "Changing buffer major mode to logo-mode, and inserting mode line." (interactive) (save-excursion (save-restriction (widen) (goto-char (point-min)) (unwind-protect (progn (newline) (goto-char (point-min)) (delete-blank-lines) (insert-before-markers ";;; -*- logo -*- \n\n")) (if kill (progn (save-buffer 0) (kill-buffer (current-buffer))) (logo-mode)))))) (defun logo-font-lock-mode (&optional arg) "Just making sure that font-lock-mode docstring doesn't show. There must be a better way to do this." (interactive) (font-lock-mode arg) (setq minor-mode-alist (delete '(font-lock-mode nil) minor-mode-alist))) ;;; ================ Static Syntax Checker ==================== ;; ;;; =========================================================== ;; I case that word-at-point is not defined (defun word-at-point () (thing-at-point 'word)) (defvar *logo-builtin-names* nil) (defvar *logo-user-names* nil) (defvar logo-names-file "ALL_NAMES") (defvar logo-skip-word-faces '(font-lock-variable-name-face font-lock-keyword-face font-lock-function-name-face font-lock-comment-face font-lock-string-face)) (defvar logo-syntax-file nil "Temporary file for logo contents output.") (if (not logo-syntax-file) (setq logo-syntax-file (make-temp-name "/tmp/SYNTAX"))) (defvar logo-report-string "to logo.report.bound.procs :file_elisp_code [:copydef \"false] 1 ; Part of Emacs logo-mode localmake \"printwidthlimit -1 localmake \"wr_elisp_code writer openwrite :file_elisp_code setwrite :file_elisp_code (if :copydef [print sentence first buried procedures] [print procedures]) close :file_elisp_code setwrite :wr_elisp_code end bury [[logo.report.bound.procs] [] []]") (defvar logo-alias-string "to logo.report.aliases :file_elisp_code :ub_list ; Part of Emacs logo-mode localmake \"printwidthlimit -1 localmake \"wr_elisp_code writer openwrite :file_elisp_code setwrite :file_elisp_code print remdup filter \"primitivep :ub_list close :file_elisp_code setwrite :wr_elisp_code end bury [[logo.report.aliases] [] []]") ;;; ======================================================= (defun logoize-buffer () ;; Logo specific word constituents (modify-syntax-entry ?. "w ") (modify-syntax-entry ?? "w ") (modify-syntax-entry ?` "w ") (modify-syntax-entry ?_ "w ") ;; The rest is to handle names in CSLS match program (modify-syntax-entry ?^ "w ") (modify-syntax-entry ?# "w ") (modify-syntax-entry ?@ "w ") (modify-syntax-entry ?& "w ") (modify-syntax-entry ?! "w ") (modify-syntax-entry ?' "w ")) (defun logo-typo-region (start end) "Sends the contents of region to logo." (interactive "r") (logo-typo-check start end)) (defun logo-typo-buffer () (interactive) (logo-typo-check (point-min) (point-max))) (defun logo-typo-check (start end) "Statically check edit buffer for typos -- only procedure names" (save-excursion (logo-remove-check) (logo-add-nl) (goto-char start) (let ((old-buff (current-buffer)) (copydef (logo-copydefp)) (unknown nil)) (set-buffer (get-buffer-create "static-syntax-buf")) ;; Logo specific word constituents (logoize-buffer) ;; reading Logo report file for unburied procedures (logo-send-string (if copydef (concat "( logo.report.bound.procs \"" logo-syntax-file " \"true )") (concat "logo.report.bound.procs \"" logo-syntax-file))) (with-timeout (3 (error "Logo did not write to %s file" logo-syntax-file)) (while (or (not (file-readable-p logo-syntax-file)) logo-busy-p) (sleep-for 0.3))) (insert-file-contents logo-syntax-file nil) (setq *logo-user-names* (logo-static-read nil)) (kill-buffer "static-syntax-buf") (set-buffer old-buff) ;; check syntax (goto-char start) (logo-static-check end) (if copydef (let ((aliases (logo-get-aliases unknown))) (if aliases (let ((*logo-user-names* (append aliases *logo-user-names*))) (set-buffer old-buff) (goto-char start) (logo-remove-check) (goto-char start) (logo-static-check end)))))))) (defun logo-remove-check () (interactive) (save-excursion (let ((overlays (overlays-in (point-min) (point-max)))) (mapc '(lambda (x) (delete-overlay x)) overlays)))) (defun logo-static-initialize () "Initialize variables for syntax checking" (set-buffer (get-buffer-create "static-syntax-buf")) ;; setting up hash-table (setq *logo-builtin-names* (make-hash-table :test 'equal :size 512)) ;; reading ALL_NAMES file (let ((standard-names (concat logo-help-path logo-names-file))) (if (file-readable-p standard-names) (insert-file-contents standard-names nil) ;; not Logo 5.4 ;; reading HELPCONTENTS file (insert-file-contents (concat logo-help-path logo-helpcontents) nil) ;; skip title (skip-chars-forward "^\n") (forward-word 1))) ;; making sure map.se 'n such is read ;; Logo specific word constituents (modify-syntax-entry ?. "w ") (modify-syntax-entry ?? "w ") (mapc '(lambda (x) (puthash x t *logo-builtin-names*)) (logo-static-read nil)) ;; setup for reading user defined procedures and copydefs (logo-send-file nil nil (concat logo-report-string "\n\n" logo-alias-string)) ;; cleanup (kill-buffer "static-syntax-buf")) (defun logo-static-read (names) (while (forward-word 1) (push (word-at-point) names)) names) (defun logo-get-aliases (unknown) (let* ((logo-str (mapconcat '(lambda (x) x) unknown " ")) (alias-str (car (read-from-string (concat "\"[" logo-str "]\""))))) (logo-send-string (concat "logo.report.aliases \"" logo-syntax-file " " alias-str)) (set-buffer (get-buffer-create "static-syntax-buf")) ;; modify syntax to read Logo specific words (logoize-buffer) (with-timeout (3 (error "Logo did not write to %s file" logo-syntax-file)) (while (or (not (file-readable-p logo-syntax-file)) logo-busy-p) (sleep-for 0.3))) (insert-file-contents logo-syntax-file nil) (prog1 (logo-static-read nil) (kill-buffer "static-syntax-buf")))) (defun logo-static-check (end) (while (not (>= (point) end)) (let ((token (thing-at-point 'word))) (if token (let ((face (get-text-property 0 'face token))) (if face (progn (if (listp face) (setq face (car face))) (if (memq face logo-skip-word-faces) (forward-word 1) ;; quoted words (logo-check-syntax-quoted token) (forward-word 1))) ;; unfontified words (logo-check-syntax-unmarked token) (forward-word 1))) (forward-word 1))))) (defun logo-check-syntax-quoted (name) (let*((bound (logo-boundp (substring name 1))) (limits (bounds-of-thing-at-point 'word)) (overlay (make-overlay (car limits) (cdr limits)))) (if (or bound (condition-case nil (numberp (car (read-from-string name 1))) (error t)) (save-excursion (forward-word -2) (not (logo-check-for-hof)))) (overlay-put overlay 'face '(:foreground "DarkOliveGreen")) (push (substring name 1) unknown) (overlay-put overlay 'face '(:foreground "red"))))) (defun logo-check-for-hof () (let ((previous (thing-at-point 'word))) (member previous '("apply" "invoke" "map" "map.se" "filter" "find" "reduce" "crossmap" "APPLY" "INVOKE" "MAP" "MAP.SE" "FILTER" "FIND" "REDUCE" "CROSSMAP")))) (defun logo-check-syntax-unmarked (name) (let*((bound (logo-boundp name)) (limits (bounds-of-thing-at-point 'word)) (overlay (make-overlay (car limits) (cdr limits)))) (if (or bound (condition-case nil (numberp (car (read-from-string name))) (error t))) (overlay-put overlay 'face '(:foreground "DarkOliveGreen")) (let ((in-list (save-excursion (logo-in-list-p)))) (push name unknown) (if in-list (progn (overlay-put overlay 'face '(:underline "red"))) (overlay-put overlay 'face '(:foreground "red"))))))) (defun logo-boundp (name) (let ((lcase (downcase name))) (and (or (string-equal (upcase lcase) name) (string-equal lcase name)) (or (gethash lcase *logo-builtin-names*) (member lcase *logo-user-names*))))) (defun logo-copydefp () (let ((copydef (re-search-forward "\\(^[ \t]*\\|[\n \t[(]+\\)copydef[ \t]+" nil t))) (if (and copydef (logo-in-string/comment-p copydef)) (logo-copydefp) copydef))) (defun logo-in-string/comment-p (pos) (goto-char pos) (let ((face (get-text-property 0 'face (thing-at-point 'word)))) (and face (progn (if (listp face) (setq face (car face))) (memq face '(font-lock-comment-face font-lock-string-face)))))) (defun logo-in-list-p () "Is this word inside brackets" (save-restriction (condition-case nil (let* ((start (point)) ;; Limit search to the value of logo-unbalanced-distance ;; characters before the beginning of this word (search-limit (- start logo-unbalanced-distance))) (narrow-to-region (if (< search-limit (point-min)) (point-min) ;; Make sure that search-limit is not in the middle of a comment (goto-char search-limit) (beginning-of-line) (point)) start) (goto-char start) (let ((paren (progn (up-list -1) (following-char)))) (while (char-equal paren ?\() (up-list -1) (setq paren (following-char)))) (point)) (error nil)))) (defun logo-add-nl () (goto-char (point-max)) (or (bolp) (insert-char ?\n 1))) ;;; ================= Opening new edit frame =================== ;; Pacifying compiler (defvar dired-mode-map nil) (defun dired-mouse-find-file-other-window (e) nil) (add-hook 'dired-load-hook (lambda () (define-key dired-mode-map [mouse-2] 'logo-mouse-find-file-this-window)) "Rebinding mouse-2 to run find-file-this-window in dired.") (defun logo-mouse-find-file-this-window (event) (interactive "@e") (let ((dired-window (get-buffer-window (current-buffer)))) (dired-mouse-find-file-other-window event) ;; Kill dired window (delete-window dired-window)) ;; This is an odd-ball. Mouse pointer remains as a cross??? (set-mouse-color (assoc "mouse-color" (frame-parameters)))) (defun logo-open-file () "Opening another Logo file. Using the same mode used to start Logo (same/other window, other frame), if user did start Logo. If not, default to other frame." (interactive) (or logo-buffer (setq logo-frames t)) (and logo-frames (select-frame (make-frame-command))) (dired default-directory)) ;;; ================= Starting process stuff =================== (let ((logo-inferior-proc (get-process "logo"))) (if (and (not logo-buffer) logo-inferior-proc) (setq logo-buffer (process-buffer logo-inferior-proc)))) (defun logo-proc () (let ((proc (get-buffer-process logo-buffer))) (or proc (error "No current process -- start Logo first")))) (defun run-logo-same-window () "Start process Logo in the same window." (interactive) (setq logo-buffer nil) (setq logo-frames nil) (fset 'logo-switch-buffer 'switch-to-buffer) (run-logo) ;; giving enough time to Logo (sleep-for 0.5) (logo-static-initialize)) (defun run-logo-other-frame () "Start process Logo in the second frame." (interactive) (setq logo-buffer nil) (setq logo-frames t) (fset 'logo-switch-buffer 'pop-to-buffer) (run-logo) ;; giving enough time to Logo (sleep-for 0.5) (logo-static-initialize)) (defmacro logo-popup-frames (pred &rest subexprs) "Enable popping frames temporary." `(progn (setq pop-up-frames ,pred) ,@subexprs (setq pop-up-frames nil))) ;;; ========================== Help code ========================== ;; ;;; Logo-helpcontents minor mode ;; This is here just to avoid compilation warnings - View mode kludge (defvar view-mode nil) (defvar view-overlay nil) (defvar view-mode-auto-exit nil) (defvar view-old-buffer-read-only nil) (defvar view-exit-position nil) (defvar view-exit-action nil) (defvar view-return-here nil) (defvar view-return-to-alist nil) (defun view-exit nil) (defun View-kill-and-leave nil) (defun view-mode-exit (&optional a b c)) (defvar logo-helpcontents-mode nil "Mode variable for logo-helpcontents minor mode.") (make-variable-buffer-local 'logo-helpcontents-mode) (defvar logo-helpcontents-mode-map nil) (if logo-helpcontents-mode-map nil (setq logo-helpcontents-mode-map (make-sparse-keymap)) ;; Overriding `dangerous' keys in View-mode (define-key logo-helpcontents-mode-map "E" 'ignore) (define-key logo-helpcontents-mode-map "e" 'ignore) (define-key logo-helpcontents-mode-map "Q" 'ignore) (define-key logo-helpcontents-mode-map "c" 'ignore) (define-key logo-helpcontents-mode-map "C" 'ignore) ;; mouse bindings (define-key logo-helpcontents-mode-map [down-mouse-3] 'logo-mouse-set-point) (define-key logo-helpcontents-mode-map [mouse-3] 'logo-help) ;; the other two are here just to disable beeping (define-key logo-helpcontents-mode-map [down-mouse-1] 'logo-mouse-set-point) (define-key logo-helpcontents-mode-map [mouse-1] 'logo-help) (define-key logo-helpcontents-mode-map [down-mouse-2] 'logo-mouse-set-point) (define-key logo-helpcontents-mode-map [mouse-2] 'logo-help)) (defun logo-helpcontents-mode () "Logo helpcontents minor mode. Click with mouse (all 3 buttons work) on any Logo name in HELPCONTENTS to choose help for that procedure. Hit `q' to return to Logo edit buffer. \\{logo-helpcontents-mode-map}" (interactive) (logo-helpcontents-mode-initialize) (setq logo-helpcontents-mode t)) (defun logo-helpcontents-mode-initialize () (or (assq 'logo-helpcontents-mode minor-mode-map-alist) (setq minor-mode-map-alist (cons (cons 'logo-helpcontents-mode logo-helpcontents-mode-map) minor-mode-map-alist))) (if (not (assq 'logo-helpcontents-mode minor-mode-alist)) (setq minor-mode-alist (cons '(logo-helpcontents-mode " Logo-helpcontents") minor-mode-alist))) ;; Logo specific word constituents (modify-syntax-entry ?. "w ") (modify-syntax-entry ?: "w ") (modify-syntax-entry ?? "w ") (modify-syntax-entry ?` "w ")) ;;; Logo-help minor mode (defvar logo-help-mode nil "Mode variable for Logo-help minor mode.") (make-variable-buffer-local 'logo-help-mode) (defvar logo-help-mode-map nil) (if logo-help-mode-map nil (setq logo-help-mode-map (make-sparse-keymap)) ;; Overriding dangerous keys in View-mode (define-key logo-help-mode-map "E" 'ignore) (define-key logo-help-mode-map "e" 'ignore) (define-key logo-help-mode-map "Q" 'ignore) (define-key logo-help-mode-map "c" 'ignore) (define-key logo-help-mode-map "C" 'ignore) ;; mouse bindings - actually, allowing only marking region with mouse-1 (define-key logo-help-mode-map [down-mouse-3] 'logo-mouse-set-point) (define-key logo-help-mode-map [mouse-3] 'logo-mouse-set-point) (define-key logo-help-mode-map [down-mouse-1] 'mouse-drag-region) (define-key logo-help-mode-map [mouse-1] 'mouse-set-point) (define-key logo-help-mode-map [down-mouse-2] 'logo-mouse-set-point) (define-key logo-help-mode-map [mouse-2] 'logo-mouse-set-point)) (defun logo-help-mode () "Logo help minor mode. Hit `q' to return to Logo edit buffer, or to HELPCONTENTS buffer - if started there. Drag mouse-1 to mark region for copying into edit buffer. \\{logo-help-mode-map}" (interactive) (logo-help-mode-initialize) (setq logo-help-mode t)) (defun logo-help-mode-initialize () (or (assq 'logo-help-mode minor-mode-map-alist) (setq minor-mode-map-alist (cons (cons 'logo-help-mode logo-help-mode-map) minor-mode-map-alist))) (if (not (assq 'logo-help-mode minor-mode-alist)) (setq minor-mode-alist (cons '(logo-help-mode " Logo-help") minor-mode-alist)))) (defun logo-mouse-set-point (event) "set the point with down-mouse-n." (interactive "@e") (mouse-set-point event) (setq logo-mouse-pos (point))) (defun logo-help (event) "Pops a window with help-file for procedure at the point." (interactive "@e") (letrec ((strip (lambda (word) (cond ((string-match "^[\":]" word) (strip (replace-match "" t t word))) ((string-match "\\." word) (strip (replace-match "d" t t word))) ((string-match "\?\\>" word) (replace-match "p" t t word)) (t word))))) (mouse-set-point event) (let ((word (current-word t))) (if (or (not word) (not (= (point) logo-mouse-pos))) (message "Mouse-3 invokes Logo Help -- point to `name' and try again.") (let* ((selected (downcase (strip word))) (path (concat logo-help-path selected)) (double (get-buffer (concat selected " Help")))) (cond (double (logo-popup-frames logo-frames (logo-switch-buffer double))) ((file-readable-p path) (unwind-protect (progn (remove-hook 'view-mode-hook 'logo-debug-function) (view-file path)) (add-hook 'view-mode-hook 'logo-debug-function))) (t ;; Help file doesn't exist (message "File: %s not found -- check helpcontents." selected) (sit-for 0.5) (logo-show-helpcontents)))))))) (defun logo-show-helpcontents () "Handling help request for misspelled procedure, or activated by Logo-help menu from emacs Help." (interactive) (let ((helpcontents (concat logo-help-path logo-helpcontents))) (if (file-readable-p helpcontents) (let ((double (get-buffer logo-helpcontents))) (if (and double (get-buffer-window double t)) (logo-popup-frames logo-frames (logo-switch-buffer double)) (unwind-protect (progn (remove-hook 'view-mode-hook 'logo-debug-function) (view-file (concat logo-help-path logo-helpcontents))) (add-hook 'view-mode-hook 'logo-debug-function)))) (error "File: %s missing" helpcontents)))) (defun logo-help-function () "If in HELPCONTENTS turn on Logo-helpcontents mode. If in Logo help file buffer, turn on Logo-help mode." (let ((buffer (buffer-name))) (cond ((string= buffer logo-helpcontents) ;; In HELPCONTENTS - turn on Logo-helpcontents mode (logo-helpcontents-mode)) ;; Do nothing - emacs help or completions buffer - making doubly sure ((string= buffer "*Help*")) ((string= buffer " *Completions*")) ;; If buffer found in helpfiles this must be Logo help file ((file-readable-p (concat logo-help-path buffer)) (rename-buffer (concat buffer " Help")) (logo-help-mode))))) (defadvice view-mode-exit (before hack-return-to-alist (&optional return-to-alist exit-action all-win)) "Making sure that the HELPCONTENTS buffer is not shown in more than one window." (let* ((helpcontents (get-buffer logo-helpcontents)) (double (and helpcontents (get-buffer-window helpcontents t) (equal helpcontents (nth 2 (car view-return-to-alist)))))) ;; If return buffer is again HELPCONTENTS, remove it from the alist (setq return-to-alist (if double (cdr view-return-to-alist) view-return-to-alist))) (setq exit-action 'kill-buffer) (setq all-win t)) (ad-activate 'view-mode-exit) (defun logo-hidden-buffer (edit-buffers) "Return hidden edit buffer." (cond ((null edit-buffers) nil) ((get-buffer-window (car edit-buffers) t) (logo-hidden-buffer (cdr edit-buffers))) (t (car edit-buffers)))) (defun logo-show-info () "Starting info mode on ucblogo.info version of usermanual." (interactive) (let ((info-gz (concat logo-info-file ".gz"))) (cond ((file-readable-p "/usr/local/lib/logo/info/ucblogo.info") ;; First trying default path (info "xx/../usr/local/lib/logo/info/logo.info")) ((file-readable-p logo-info-file) ;; Forcing absolute path with `xx/../'. Why is this needed ;; is beyond me? (info (concat "xx/../" logo-info-file))) ((file-readable-p info-gz) (info (concat "xx/../" info-gz))) (t (error "file: %s not found -- see variable `logo-info-file'" logo-info-file))))) (defun loops-show-info () "Starting info mode on loops.info usermanual." (interactive) (let* ((info (concat (file-name-directory logo-info-file) "loops.info")) (info-gz (concat info ".gz"))) (cond ((file-readable-p "/usr/local/lib/logo/info/loops.info") ;; First trying default path (info "xx/../usr/local/lib/logo/info/loops.info")) ((file-readable-p info) ;; Forcing absolute path with `xx/../'. Why is this needed ;; is beyond me? (info (concat "xx/../" info))) ((file-readable-p info-gz) (info (concat "xx/../" info-gz))) (t (error "file: %s not found -- see variable `logo-info-file'" logo-info-file))))) (defun logo-show-info-trans () "Starting info mode on translated ucblogo.info version of usermanual." (interactive) (let ((info-gz (concat logo-info-file-trans ".gz"))) (cond ((file-readable-p logo-info-file-trans) ;; Forcing absolute path with `xx/../'. Why is this needed ;; is beyond me? (info (concat "xx/../" logo-info-file-trans))) ((file-readable-p info-gz) (info (concat "xx/../" info-gz))) (t (error "file: %s not found -- see variable `logo-info-file-trans'" logo-info-file-trans))))) ;;; ========================== Indenting code ========================== (defsubst logo-in-string-p (&optional def-start) "Is beginning of this line in string?" (let* ((line (point)) ;; Limit search to the beginning of enclosing paragraph or ;; start of Logo definition (search-limit (or def-start (progn (backward-paragraph) (point))))) (goto-char search-limit) (nth 3 (parse-partial-sexp (point) line)))) (defsubst logo-jump-to-next-word () (let ((start (point)) (end (progn (skip-syntax-forward "^<>") (point)))) (goto-char start) (forward-word 1) (if (and (> (point) end) (not (logo-in-string-p))) (goto-char start)) (skip-syntax-forward " " end))) (defun logo-indent-line (&optional no-instring def-start) "If explicit or implicit continuation line above, then indent, otherwise flush left. First optional input must be t or nil; t if you want to skip in-string checking for x-continuation lines. Second optional input is limit for unbalanced brackets search." (interactive) (let ((indent (logo-indent-p no-instring def-start))) (save-excursion (beginning-of-line) ;; If in a string - do not remove leading spaces (or (logo-in-string-p def-start) (delete-horizontal-space)) (if indent (indent-to indent))) (and (zerop (current-column)) indent (forward-char (current-indentation))))) (defsubst logo-unbalanced-p (&optional def-start) "Is this line unbalanced?" (save-restriction (condition-case nil (let* ((line (progn (beginning-of-line) (point))) ;; Limit search to the value of logo-unbalanced-distance ;; characters before the beginning of this line (search-limit (or def-start (- line logo-unbalanced-distance)))) (narrow-to-region (if (< search-limit (point-min)) (point-min) ;; Make sure that search-limit is not in the middle of a comment (goto-char search-limit) (beginning-of-line) (point)) line) (goto-char line) (up-list -1) (point)) (error nil)))) (defsubst logo-xcontinuation-p (&optional no-instring def-start) "Are we on a line that ends with `~' and is not part of Logo string?" (and (looking-at logo-xcontinuation-line) (or no-instring ;; Is end of this line part of a Logo string? (let ((pos (point))) (end-of-line) (prog1 (not (logo-in-string-p def-start)) (goto-char pos)))))) (defun logo-indent-p (&optional no-instring def-start) "Is this a line after ~ or after unmatched `[ ( {' ? Strings that span several lines are not indenting." (save-excursion (beginning-of-line) (and (not (bobp)) (forward-line -1) (or (and (logo-xcontinuation-p no-instring def-start) (logo-xtab)) ;; Implicit indentation stuff (logo-itab (point) (progn (forward-line 1) (skip-syntax-forward " ") (following-char)) (logo-unbalanced-p def-start)))))) (defun logo-itab (prev-line next-char paren-pos) "Calculate implicit indent column." (if paren-pos (let ((open-char (following-char)) (indent (cond ((looking-at "\\[[ \t]*$") (logo-long-line prev-line next-char)) ((or (forward-char) (looking-at "[ \t]*\\s\(")) (progn (skip-syntax-forward " ") (current-column))) ((logo-indent-to-paren next-char (point))) (t (goto-char paren-pos) (logo-jump-to-next-word) (current-column))))) indent))) (defun logo-long-line (prev-line next-char) "Start `long line' indent if next-char = ]." (cond ((char-equal next-char ?\]) (goto-char prev-line) (max 0 (- (current-indentation) logo-min-indent))) ((< next-char 14) (setq logo-reindent-now t) (current-indentation)) (t (+ (current-indentation) logo-min-indent)))) (defun logo-indent-to-paren (next-char after-paren) "Indent to inner balanced parens, if any." (save-restriction (condition-case nil (progn (narrow-to-region after-paren (progn (end-of-line) (point))) (goto-char after-paren) (down-list 1) (widen) (if (char-equal (preceding-char) ?\() (progn (cond ((char-equal (char-syntax next-char) ?\() (backward-char)) ((< next-char 14) (setq logo-reindent-now t) (goto-char after-paren)) (t (goto-char after-paren) (logo-jump-to-next-word))) (current-column)) (goto-char after-paren) (logo-jump-to-next-word) (current-column))) (error nil)))) (defun logo-xtab () "Calculate explicit indent - beginning of second word." (let ((indent (current-indentation))) (if (not (zerop indent)) (min indent logo-max-indent) (logo-jump-to-next-word) (min (current-column) logo-max-indent)))) (defun logo-post-command-function () "Re-indent after inserting first character." (and logo-reindent-now (cond ((eq this-command 'self-insert-command) (and (char-equal (char-syntax (preceding-char)) ?\ ) (message "Waiting for character other than space to re-indent.")) (setq logo-reindent-now nil) (logo-indent-line)) ((not (member this-command '(logo-indent-line newline-and-indent overwrite-mode))) (setq logo-reindent-now nil))))) (defun logo-indent-definition () "Indent Logo instruction or definition! First try to find boundaries of definition above the point. If that fails indent paragraph. Point must be inside or directly under definition!" (interactive) (save-excursion (let ((search-limit (and (logo-mark-definition) (point)))) (if (looking-at "[ \t]*$") (forward-line 1)) (while (and (<= (point) (mark)) (not (eobp))) (logo-indent-line nil search-limit) (forward-line 1)))) (logo-indent-line) (and (zerop (current-column)) (skip-syntax-forward " "))) (defsubst logo-defun-start-p (&optional dummy) "Is this a start of Logo definition." (and (looking-at logo-defun-start) (not (logo-indent-p t)) (not (logo-in-string-p)))) (defsubst logo-defun-end-p (&optional dummy) "Is this the end of Logo definition." (and (looking-at logo-defun-end) (not (logo-indent-p t)) (not (logo-in-string-p)))) (defun logo-mark-definition () "Finds the boundaries of Logo procedure definition. Marks the end and leaves point at the beginning. Return value is t or nil" (beginning-of-line) ;; Up to the first nonempty line (while (and (not (bobp)) (looking-at "[ \t]*$")) (beginning-of-line 0)) (let ((begin (point))) ;; Look for first boundary (while (and (not (bobp)) (not (logo-defun-start-p)) (not (logo-defun-end-p))) (beginning-of-line 0)) (cond ((looking-at logo-defun-end) ;; END found (if (= (point) begin) ;; OK - there was nothing below END (progn (end-of-line) (push-mark nil t t) (logo-mark-start begin)) ;; There was something below END - mark that (beginning-of-line 2) (let ((limit (point))) (goto-char begin) (mark-paragraph) (and (< (point) limit) (goto-char limit)) (message "No Logo definition at point -- grabbing paragraph.") nil))) ((looking-at logo-defun-start) ;; TO or .MACRO found (logo-mark-end (point) begin)) (t ;; This can only be bobp (goto-char begin) (mark-paragraph) (if (zerop (- (mark) (point))) (message "Nothing found.") (message "No Logo definition at point -- grabbing paragraph.")) nil)))) (defun logo-mark-start (begin) "After the mark is set at the end of definition, look for start." (beginning-of-line 0) (while (and (not (bobp)) (not (logo-defun-start-p)) (not (logo-defun-end-p))) (beginning-of-line 0)) (cond ((looking-at logo-defun-start)) ((bobp) (message "No Logo definition at point -- grabbing paragraph.") (goto-char begin) (mark-paragraph) nil) (t ;; End again? (message "No Logo definition at point -- grabbing paragraph.") (goto-char begin) (mark-paragraph) nil))) (defun logo-mark-end (defun-start begin) "Point is at the start of definition, look for end." (goto-char begin) (beginning-of-line 2) (while (and (not (eobp)) (not (logo-defun-end-p)) (not (logo-defun-start-p))) (beginning-of-line 2)) (cond ((looking-at logo-defun-end) (end-of-line) (push-mark nil t t) (goto-char defun-start) t) ((eobp) (message "No Logo definition at point -- grabbing paragraph.") (goto-char begin) (mark-paragraph) nil) (t ;; Start of Logo definition again? (message "No Logo definition at point -- grabbing paragraph.") (goto-char begin) (mark-paragraph) nil))) (defun logo-indent-buffer (&optional beg end) "Indent the whole buffer - this is mostly for old Logo code & testing. Also indents region - used for commenting." (interactive) (save-excursion (save-restriction (widen) (let ((start (or beg (point-min))) (stop (or end (point-max)))) (goto-char start) (while (and (not (eobp)) (not (> (point) stop))) (logo-indent-line) (forward-line)))))) ;;; ================= Commenting - Uncommenting ================= (defun logo-comment-region (beg end) "Comment out selected region." (interactive "r") (save-excursion (goto-char beg) (beginning-of-line) (logo-comment-helper (lambda () (if (char-equal (following-char) ?\;) (insert-char ?\; 1) (insert "; "))) (count-lines beg end)))) (defun logo-comment-helper (func lines) (letrec ((loop (lambda (lines) (if (zerop lines) nil (funcall func) (beginning-of-line 2) (loop (1- lines)))))) (if (> lines 1000) (error "Region is too large (%d lines) -- choose up to 1000 and try again" lines) (loop lines)))) (defun logo-uncomment-region (beg end) "Uncomment selected region - one column only." (interactive "r") (save-excursion (goto-char beg) (beginning-of-line) (logo-comment-helper (lambda () (if (char-equal (following-char) ?\;) (delete-char 1))) (count-lines beg end)) (logo-indent-buffer beg end))) (defun logo-comment-definition () "Comment out Logo definition, or maybe paragraph. Point must be inside definition!" (interactive) (save-excursion (logo-mark-definition) (if (looking-at "[ \t]*$") (forward-line 1)) (logo-comment-region (point) (mark)))) (defun logo-uncomment-definition () "Uncomment Logo definition, or maybe paragraph. Point must be inside definition!" (interactive) (save-excursion (logo-mark-definition) (if (looking-at "[ \t]*$") (forward-line 1)) (if (char-equal (following-char) ?\;) (logo-uncomment-region (point) (mark)) (message "Use Uncomment Region for that!")))) ;;; ================ Sending to Logo process ================== (fset 'comint-send-string (lambda (proc string) (setq logo-busy-p t) (process-send-string proc string))) (defun logo-send-buffer () "Sends the contents of buffer to logo." (interactive) (logo-send-file (point-min) (point-max))) (defun logo-send-buffer-and-go () "Sends contents of buffer to logo and switches to logo process buffer." (interactive) (logo-send-file (point-min) (point-max)) (and (get-buffer-window "*logo*" t) (logo-toggle-to-logo))) (defun logo-send-string (string) "Strip newline and xcontinuation marks `~' from buffer string. This doesn't work for some bizarre situations like embedded newline in continued string." (comint-send-string (logo-proc) (concat "pr [] " ;; avoiding multiple ? prompts (logo-strip-newline (logo-strip-xcont string)) "\n"))) (defun logo-strip-xcont (string) "Strip tilde and following newline if marking explicit continuation." (let ((xcont (string-match "[^\\\\]\\(\\\\\\\\\\)*\\(~[ \t]*\\)\\(\n\\)" string))) (if xcont (or (and ;; If match not in Logo string replace `~' with "" (save-match-data (zerop (% (logo-instring-count (substring string 0 (1+ xcont)) 0) 2))) (logo-strip-xcont (replace-match "" t t string 2))) ;; If match in Logo string leave `~' & replace `\n' with " " (logo-strip-xcont (replace-match " " t t string 3))) string))) (defun logo-instring-count (string count) "Finding if end of string in Logo string. Actually only counting number of bars before the end of string." (let ((bar (string-match "[^\\\\]\\(\\\\\\\\\\)*|" string))) (if bar (logo-instring-count (substring string (1+ bar)) (1+ count)) count))) (defun logo-send-region (start end) "Sends the contents of region to logo." (interactive "r") (logo-send-file start end)) (defun logo-send-region-and-go (start end) "Sends contents of region and switches to logo buffer." (interactive "r") (logo-send-file start end) (and (get-buffer-window "*logo*" t) (logo-toggle-to-logo))) (defun logo-send-definition () "Send procedure definition before point to logo." (interactive) (save-excursion (or (logo-mark-definition) (message "No Logo procedure at point -- sending paragraph.")) (logo-send-file (point) (mark)))) (defun logo-send-definition-and-go () "Send paragraph before point to Logo and go." (interactive) (logo-send-definition) (and (get-buffer-window "*logo*" t) (logo-toggle-to-logo))) (defun logo-send-instruction-line () "Send instruction line before point to Logo." (interactive) (save-excursion (beginning-of-line) (while (and (not (bobp)) (looking-at "[ \t]*$")) (beginning-of-line 0)) (let* ((beg (point)) (start-line (progn (while (or (logo-indent-p t) (logo-in-string-p)) (beginning-of-line 0)) (if (or (looking-at logo-defun-start) (looking-at logo-defun-end)) (error (concat "Can not use `logo-send-instruction-line' " "for defining logo procedure")) (point)))) (end-line (progn (goto-char beg) (beginning-of-line 2) (while (and (not (eobp)) (or (logo-indent-p t) (logo-in-string-p))) (beginning-of-line 2)) (or (eobp) (backward-char)) (point)))) (condition-case nil ;; Had a change of heart here. It is much easier to let Logo ;; parse the string by loading it from a temporary file than ;; having to parse it here, and pass it as a string. ;; However the mechanism for parsing is still used for mouse-2 ;; yank in setcursor mode. (prog1 (error) (logo-send-string (buffer-substring-no-properties start-line end-line))) (error (logo-send-file start-line end-line)))))) (defun logo-send-instruction-line-and-go () "Send instruction line before point to Logo and go." (interactive) (logo-send-instruction-line) (and (get-buffer-window "*logo*" t) (logo-toggle-to-logo))) (defun logo-send-file (start end &optional string) "Does the actual transfer via temporary file." (let ((contents (concat "pr []\n" (or string (buffer-substring-no-properties start end)) "\n")) ;; making sure that Emacs does not use DOS coding ;; when writing string to a temporary file (coding-system-for-write logo-current-os-system)) (condition-case nil (write-region contents t logo-temp-file nil 1) (error (error "Check write permission on %s file" logo-temp-file))) (comint-send-string (logo-proc) (concat "load \"" logo-temp-file "\n")))) ;;; ========================================================================= ;;; ========================== Inferior process logo ======================== ;; ;; Logo process in a buffer. ;; ;; This is a customization of comint-mode (see comint.el) ;; ;;; ========================================================================= ;; Pacifying the compiler (defvar comint-last-input-end nil) (defvar comint-last-output-start) (defvar comint-last-input-start) (defvar logo-setcursor-spaces-old nil "Number of spaces to clear after old input. Nil clears to the end of line.") (or (and logo-setcursor-spaces-old ;; Let's be reasonable (setq logo-setcursor-spaces-old (min logo-setcursor-spaces-old (1- process-term-columns)))) (setq logo-setcursor-spaces-old (1- process-term-columns))) (defvar logo-setcursor-spaces-new nil "Number of spaces to clear after new input. Nil clears 2 spaces.") (or (and logo-setcursor-spaces-new ;; Let's be reasonable (setq logo-setcursor-spaces-new (min logo-setcursor-spaces-new (1- process-term-columns)))) (setq logo-setcursor-spaces-new 2)) (defsubst logo-pad-function () "Padding text with spaces to the end of the line." (move-to-column process-term-columns t)) (defvar inferior-logo-mode-syntax-table nil "") (if inferior-logo-mode-syntax-table nil (setq inferior-logo-mode-syntax-table (copy-syntax-table logo-mode-syntax-table)) (set-syntax-table inferior-logo-mode-syntax-table) (modify-syntax-entry ?\| "\" ") (modify-syntax-entry ?\; "< ") (modify-syntax-entry ?\" "_ p")) ;; 2D nonsequential stuff -- related to comint ;;=========================================================================== ;; (defsubst logo-terminal-return (&optional dummy) "Return does not insert newline, except at eobp. This is used for `comint-terminal-return' function." (logo-pad-function) (if (eobp) ;; Hard newline (insert-before-markers ?\n) ;; Just drop down (beginning-of-line 2)) ;; Padding (logo-pad-function) (beginning-of-line) ;; Return something -- if called by insert functions "") (defun comint-soft-preoutput-filter (proc string) "Handling hard newline in process output. Send to comint up to a newline, do a soft newline, and repeat." (letrec ((preotput (lambda (output) (let ((procbuf (set-buffer (process-buffer proc))) (beg (string-match "\n" output))) (if (not beg) ;; No newlines - hand it to comint (comint-output-filter proc output) ;; Send anything before newline to comint (comint-output-filter proc (substring output 0 beg)) (insert-before-markers (logo-terminal-return)) (set-marker (process-mark proc) (point) procbuf) (preotput (substring output (match-end 0)))))))) ;; Handle the focus (let ((oldbuf (current-buffer))) (save-match-data (preotput string)) (set-buffer oldbuf)))) (defun comint-postoutput-overwrite (output &optional proc) "Deleting enough old text to simulate overwrite behavior. This function should be the first function in the list `comint-output-filter-functions'." ;; Check if this was called from `comint-output-filter-functions' (let ((process (or proc (and (boundp 'process) process) (get-buffer-process (current-buffer))))) ;; Handle the focus (let ((oldbuf (current-buffer))) (unwind-protect (let ((procbuf (set-buffer (process-buffer process)))) (if procbuf ;; deleting text after newly inserted. ;; Stopping before eob, or before eol, ;; but only if not at column 80. If at col 80 ;; insert newline, and continue deleting next line (save-restriction (widen) (goto-char (process-mark process)) (comint-overwrite-helper (length output) (save-excursion (let ((oend (point))) (beginning-of-line) (- oend (point))))) ;; Setting point at process mark (goto-char (process-mark process)) ;; Setting logo-input-mark (set-marker comint-last-input-end (point))))) (set-buffer oldbuf))))) (defun comint-overwrite-helper (deletions line-len) "This one is actually doing the deleting." (if (> line-len process-term-columns) ;; Insert 1 newline at last column, and eat up following newline ;; This is assuming that padding has been carried out before (progn (save-excursion (move-to-column process-term-columns) (insert-before-markers "\n") (end-of-line) (or (eobp) (delete-char 1))) (comint-overwrite-helper deletions (- line-len process-term-columns))) ;; Delete deletions, but stop before eol or eob (let ((output-end (point))) (delete-char (min deletions (save-excursion (end-of-line) (- (point) output-end)) (- (point-max) output-end)))))) (defadvice ring-insert (after update-popup-history (ring string)) "This is active inside `comint-send-input' function. Logo mode keeps a separate popup input history menu, that has to be updated." (logo-update-history-menu string)) (defadvice comint-send-input (around input-advice) (ad-activate 'ring-insert) ad-do-it (ad-deactivate 'ring-insert)) (ad-activate 'comint-send-input) (defun comint-overwrite-previous-input (string) "Function that actually inserts the matching input. It is set as the value of `comint-insert-previous-input-function'." (logo-setcursor-kill) ;; Just making sure that we are at the process mark (goto-char (process-mark (get-buffer-process (current-buffer)))) (insert string) (set-marker comint-last-input-end (point)) ;; Need to clear some old text after input end ;; Default is clear to the end of line (let ((spaces (min logo-setcursor-spaces-old (mod (- process-term-columns (mod (current-column) process-term-columns)) process-term-columns)))) (insert-char ?\ spaces) ;; prepare for overwriting after spaces (save-excursion (save-restriction (widen) (comint-overwrite-helper (+ (length string) spaces) (save-excursion (let ((oend (point))) (beginning-of-line) (- oend (point))))))) (goto-char comint-last-input-end)) ;; Do not recenter window (or (pos-visible-in-window-p (point) (selected-window)) (recenter -1))) (defun logo-strip-newline (string &optional character replacement) "Can't have newlines in overwrite mode. This is set as the value of `comint-strip-input-function'." (let ((char (or character "\n+")) (fill (or replacement ""))) (if (string-match char string) (logo-strip-newline (substring (replace-match fill t t string) 0) char fill) string))) ;; ;; 2D Logo output filter stuff ;; (defvar logo-term "xterm" "Set this in .emacs to any fully capable terminal definition. Check the top of logo.el file for more detailed information.") (defvar logo-filter-timer 2 "Set this in .emacs if timing problems occur with default filter. Check the top of logo.el file for more detailed information.") (defvar logo-term-start nil "String matching start of TERM code") (defvar logo-term-all nil "String matching the rest of TERM code") (defvar logo-code-kludge nil "Kludge for cut code in communications") (defun logo-term-setup () "Protecting logo-default-pars code." (let ((system-term (getenv "TERM"))) (setenv "TERM" logo-term) (unwind-protect (logo-default-pars) (setenv "TERM" system-term)))) (defun logo-default-pars () "Setting parameters for filters. Works for most TERM types." ;; local function for replacing 1;1 with filter regex (letrec ((convert2regex (lambda (strng) (if (string-match "1;1" strng) (concat "\\(" (replace-match "\\([0-9]+\\);\\([0-9]+\\)" t t strng) "\\)\\|") (error "SHELL can't find Logo. Either fix PATH, or set 'logo-binary-name in .emacs file - This was returned by SHELL -or- Logo: %s" code-list))))) ;; writing Logo code test file (let ((code-test "make \"startup [ct type \"| | setcursor [0 0] type \"| | type standout \"| | bye]")) (condition-case nil (write-region code-test t logo-temp-file nil 1) (error (error "Check write permission on %s file" logo-temp-file)))) ;; ask Logo to send control codes (let ((code-list (split-string (regexp-quote (with-output-to-string (with-current-buffer standard-output (call-process (if (file-exists-p logo-binary-name) logo-binary-name (message "Oops, your 'logo-binary-name is not set. Trying 'logo.") "logo") nil t nil logo-temp-file))))))) ;; parsing control codes (setq logo-term-start (substring (car code-list) 0 1)) (let ((cleartext ;; or setmargins (convert2regex (substring (car code-list) 1))) (setcursor (convert2regex (substring (cadr code-list) 1))) (standout (concat "\\(" (substring (cadr (cdr code-list)) 1) "\\([^" logo-term-start "]*\\)" (cadr (cddr code-list)) "\\)"))) (setq logo-term-all (concat cleartext setcursor standout)))))) (defsubst logo-ct-function () "Clear the visible portion of the buffer -- simulating CLEARTEXT." (beginning-of-line) (delete-region (point) (point-max)) (narrow-to-region (point) (point-max))) (defun logo-default-filter (proc output) "We are initializing filter -- just handling focus problems." (let* ((pbuff (process-buffer proc)) (obuff (current-buffer)) (pwindow (get-buffer-window pbuff 'visible))) (unwind-protect (progn (if pwindow (select-window pwindow) (switch-to-buffer pbuff) (select-window (get-buffer-window pbuff))) ;; Sending to real filter (logo-default-help proc output)) (let ((owin (get-buffer-window obuff 'visible))) (if owin (select-window owin) (switch-to-buffer obuff)))))) (defun logo-default-help (proc output) "Cleans logo output from terminal access garbage. Simulates CLEARTEXT, STANDOUT, SETCURSOR, and SETMARGINS" (let* ((string (if (not logo-code-kludge) output ;; Tack any leftovers onto new batch of Logo output (concat logo-code-kludge output))) (beg (string-match logo-term-start string))) (if (not beg) ;; Clean code - hand it to comint filter (comint-soft-preoutput-filter proc string) (if (string-match logo-term-all string (1+ beg)) (progn (setq logo-code-kludge nil) (cond ((match-beginning 1) ;; CLEARTEXT & SETMARGINS ;; Send anything before CT to comint (comint-soft-preoutput-filter proc (substring string 0 beg)) ;; Scroll to top (set-window-start (get-buffer-window logo-buffer) (point) t) ;; Narrow from top to buffer end (logo-ct-function) ;; Do the SETCURSOR (logo-setcursor proc string 3 2) ;; Handle the rest (logo-default-help proc (substring string (match-end 1)))) ((match-beginning 4) ;; SETCURSOR ;; Send anything before SETCURSOR to comint (comint-soft-preoutput-filter proc (substring string 0 beg)) ;; Do SETCURSOR (logo-setcursor proc string 6 5 t) ;; Handle the rest (logo-default-help proc (substring string (match-end 4)))) ((match-beginning 7) ;; STANDOUT (add-text-properties (match-beginning 8) (match-end 8) '(rear-nonsticky t face highlight) string) (comint-soft-preoutput-filter proc (concat (substring string 0 beg) (substring string (match-beginning 8) (match-end 8)))) (logo-default-help proc (substring string (match-end 7)))) (t ;; How did we get here? (error "Error in default filter")))) ;; fixing process communication problems (if logo-code-kludge ;; I'm letting it slide here. ;; The only valid Logo code that can get through ;; is a *very* long standout. Unfortunately Logo itself ;; can't handle this properly. (progn ;; Show last Logo output (if logo-busy-p (comint-soft-preoutput-filter proc logo-code-kludge) (comint-soft-preoutput-filter proc string)) (setq logo-code-kludge nil) (ding) (message (concat "Unknown control code or *very* large standout - " "see logo-term variable."))) (setq logo-code-kludge string) ;; Trapping invalid control codes or *very* long standouts ;; This prevents a stalemate, while Logo awaits for user input ;; and emacs awaits for the rest of unrecognized control ;; sequence. (run-with-idle-timer ;; Wait n seconds for next batch of Logo output, after ;; discovery of broken sequence. If on a very slow system, ;; change logo-filter-timer to 3, or whatever works for you. ;; Default value is 2. logo-filter-timer nil (function (lambda () (and logo-code-kludge ;; Ask Logo to send anything -- to force printing of ;; the broken code waiting for next batch of Logo output. (logo-send-command "wait 0")))))))))) (defun logo-setcursor (proc string regex-col regex-row &optional narrow) "2D stuff -- positioning cursor in comint process buffer." (let* ((pbuff (process-buffer proc)) (pwindow (get-buffer-window pbuff))) (unwind-protect (progn (goto-char (point-max)) (goto-char (window-start pwindow)) (and narrow (narrow-to-region (point) (point-max))) ;; Get the coordinates (let ((col (1- (string-to-number (substring string (match-beginning regex-col) (match-end regex-col))))) (row (1- (string-to-number (substring string (match-beginning regex-row) (match-end regex-row)))))) ;; Move down row lines (let ((lines (- row (vertical-motion row)))) ;; If not enough insert newlines (insert-before-markers (make-string lines ?\n))) ;; we're padding here (logo-pad-function) ;; Set the column (move-to-column col t))) ;; Update process mark (set-marker (process-mark proc) (point) pbuff)))) ;; End of comint related 2D stuff ;;========================================================================== ;; ;; 2D stuff not comint related ;;========================================================================== ;; (defun logo-setcursor-self-insert (&optional arg) "A wraparound code for self-insert command. Displaying and trimming text that user types in inferior logo mode." (interactive) (if (or (< (point) (marker-position (process-mark (logo-proc)))) (> (point) (marker-position comint-last-input-end))) (progn (message "This was not within command line -- You have been moved!") (ding) ;; sending point back to the command line (logo-find-input-end))) (let ((inside (< (point) (marker-position comint-last-input-end))) (overwriting overwrite-mode)) (save-excursion ;; Getting rid of all newlines in input. (while (and (skip-chars-forward "^\n") (< (point) (marker-position comint-last-input-end))) (delete-char 1)) ;; Padding the line - works only for first line (logo-pad-function)) ;; Making sure we're in insert mode. (overwrite-mode -1) ;; Inserting dummy space first. Don't want parens maching to ;; occure just yet. (insert-char ?\ 1) ;; Return previous mode (insert/overwrite). (and overwriting (overwrite-mode 1)) ;; If inserted at marker position move marker manually. (if (not inside) (set-marker comint-last-input-end (1+ (marker-position comint-last-input-end)))) (save-excursion (if (and inside overwriting) (delete-char 1) (progn (goto-char comint-last-input-end) (or (eobp) ;; If not at end of line delete character. (and (not (eolp)) (progn (delete-char 1) t)) (progn ;; If at end of line, first pad this line. ;; Then move to next and pad that as well. ;; And finally delete 2 characters. (save-excursion (logo-pad-function) (beginning-of-line 2) (logo-pad-function)) (delete-char 2))))) ;; Inserting previously deleted newlines. (logo-insert-nl (- (progn (end-of-line) (point)) (progn (beginning-of-line) (point))))) ;; Making sure we'r in overwrite mode. (overwrite-mode 1) ;; Inserting character that user typed now. Overwriting dummy space. (and (char-equal (preceding-char) ?\n) (backward-char)) (backward-char) (if arg (insert-char arg 1) (self-insert-command 1)) ;; If inserted at marker position move marker manually, again? (if (not inside) (set-marker comint-last-input-end (1+ (marker-position comint-last-input-end)))) ;; Return previous mode (insert/overwrite). (or overwriting (overwrite-mode -1)) ;; Push some spaces over the old text, to make new input readable (save-excursion (goto-char (marker-position comint-last-input-end)) (let ((spaces (min logo-setcursor-spaces-new ;; Not beyond eobp (- (point-max) (point)) (mod (- process-term-columns (mod (current-column) process-term-columns)) process-term-columns)))) (delete-char spaces) (insert-char ?\ spaces)) ;; Do not recenter window if inserted beyond last line (or (pos-visible-in-window-p (point) (selected-window)) (recenter -1))))) (defun logo-insert-nl (line-len) "Inserting newlines that were removed before using self-insert-command." (if (> line-len process-term-columns) (progn (move-to-column process-term-columns) (insert-before-markers "\n") (logo-insert-nl (- line-len process-term-columns))))) (defun logo-setcursor-backspace (arg) "Adjusting the 'attitude' of backspace key in inferior logo mode. Ignoring newlines and padding at the end of logo input string to prevent shifting of old text." (interactive "p") (let* ((pmark (marker-position (process-mark (logo-proc)))) (in-input (and (> (point) pmark) (<= (point) (marker-position comint-last-input-end)))) (overwriting overwrite-mode)) ;; Backspacing out of input string is not good for you. Anything ;; not good for you is illegal. (and (not in-input) (error "Trying to backspace out of input string - hit C-l to find end of input")) ;; Let's dispense with emacs silly backspacing in overwrite mode. (overwrite-mode -1) (save-excursion ;; Getting rid of all newlines in input. (goto-char pmark) (while (and (skip-chars-forward "^\n") (< (point) (marker-position comint-last-input-end))) (delete-char 1))) (backward-delete-char-untabify arg) (save-excursion (goto-char comint-last-input-end) (insert-char ?\ arg) ;; Inserting previously deleted newlines. (logo-insert-nl (- (progn (end-of-line) (point)) (progn (beginning-of-line) (point))))) ;; Restore the input mode (and overwriting (overwrite-mode 1)))) (defun logo-setcursor-delete () "Adjusting the 'attitude' of delete key in inferior logo mode. Ignoring newlines and padding at the end of logo input string to prevent shifting of old text." (interactive) (let* ((pmark (marker-position (process-mark (logo-proc)))) (in-input (and (>= (point) pmark) (< (point) (marker-position comint-last-input-end))))) ;; Deleting out of input string is not good for you. Anything ;; not good for you is illegal. (and (not in-input) (error "Trying to delete out of input string - hit C-l to find end of input")) (save-excursion ;; Getting rid of all newlines in input. (goto-char pmark) (while (and (skip-chars-forward "^\n") (< (point) (marker-position comint-last-input-end))) (delete-char 1))) ;; This is the one that actually deletes the character. (delete-char 1) (save-excursion (goto-char comint-last-input-end) (insert-char ?\ 1) ;; Inserting previously deleted newlines. (logo-insert-nl (- (progn (end-of-line) (point)) (progn (beginning-of-line) (point))))))) (defun logo-setcursor-yank (&optional arg no-strip) "C-y & Mouse-2 yank back last entry from kill-ring. It is *always* placed at the start of logo input, and overwrites as much old text as necessary. If present, first optional input must be a string to yank back. If second optional argument is t, then the first argument is not stripped of comments, newlines, spaces xcontinuation-lines ..." (interactive) (let* ((proc (logo-proc)) (oproc-mark (marker-position (process-mark proc)))) (goto-char oproc-mark) ;; Sending last entry as Logo output, but stripping newlines first. (let ((yanked nil)) (unwind-protect (progn (comint-output-filter proc ;; if second argument t, skip stripping (if no-strip (progn (logo-setcursor-kill) arg) (let ((string ;; Removing extra spaces (logo-strip-comment ;; Replacing newlines with spaces (logo-strip-newline ;; Stripping comment only lines (logo-strip-comment ;; Getting rid of xcontinuation ~ (logo-strip-xcont (prog1 ;; Checking for X-selection, or ;; presence of the first argument (or arg (current-kill 0)) ;; Kill old input, only if selection exists. (logo-setcursor-kill))) 0) "\n" " ") ;; Look for more than 2 spaces followed by anything ;; and a vertical bar or by anything. 0 "\\([ \t][ \t]+\\)\\(.*|\\|.*\\)" " "))) ;; Strip trailing whitespaces (if (string-match "[ \t]+\\'" string) (substring (replace-match "" t t string) 0) string)))) (setq yanked t)) (set-marker (process-mark proc) oproc-mark) ;; If yank succeeded move end of Logo input marker. (or (and yanked (set-marker comint-last-input-end (point))) ;; Else set point to the end of old Logo input. (goto-char comint-last-input-end)))))) (defun logo-strip-comment (string start &optional regex fill) "Strip comment lines if not within pair of bars." (let* ((regexpr (or regex "[ \t\n]*\\(\\(;+\\).*$\\)")) (replacement (or fill "")) (comment (string-match regexpr string start))) (if comment ;; If match not in Logo string replace it with "" (if (save-match-data (zerop (% (logo-instring-count (substring string 0 (1+ comment)) 0) 2))) (logo-strip-comment (replace-match replacement t t string 1) start regexpr replacement) ;; If match in Logo string leave it, but move start after `;' (logo-strip-comment string (match-end 2) regexpr replacement)) string))) (defun logo-setcursor-kill () "C-k kills the input line in inferior logo. Just overwrites with spaces." (interactive) (let* ((proc (logo-proc)) (oproc-mark (marker-position (process-mark proc))) (logo-mark (marker-position comint-last-input-end))) (goto-char oproc-mark) (let ((spaces (length (logo-strip-newline (buffer-substring-no-properties oproc-mark logo-mark))))) (comint-output-filter proc (make-string spaces ?\ )) (set-marker (process-mark proc) oproc-mark) (goto-char oproc-mark) (set-marker comint-last-input-end (point))))) (defun logo-setcursor-undo () "Undo in inferior logo buffer, only if undoing the new input text." (interactive) (if (> comint-last-input-end (marker-position (process-mark (logo-proc)))) (undo) (message "Not active in inferior logo mode."))) ;;; Inferior logo 2D dabbrev-completion (defun logo-tmp-dabbrev-setup () "Setting variables for dynamic abbreviation expansionin in *logo*." (set-syntax-table inferior-logo-mode-syntax-table) (set (make-local-variable 'dabbrev-abbrev-skip-leading-regexp) "[:\"]") (set (make-local-variable 'dabbrev-abbrev-char-regexp) "\\sw\\|\\s_") (set (make-local-variable 'dabbrev-case-fold-search) nil) (set (make-local-variable 'dabbrev-case-replace) nil) (set (make-local-variable 'dabbrev-check-all-buffers) nil) (set (make-local-variable 'dabbrev-search-these-buffers-only) nil) (set (make-local-variable 'dabbrev-ignored-buffer-names) '("*Messages*" "*Buffer List*" " *logo-names*" "*scratch*")) (set (make-local-variable 'dabbrev-select-buffers-function) (function (lambda nil (mapcar 'get-buffer (cons "*logo*" logo-edit-buflist)))))) ;; This one is currently not used (defun setcursor-insert-string (char-list) "Using logo-setcursor-self-insert to insert arg string -- actually a list of characters." (if (null char-list) 'done (logo-setcursor-self-insert (car char-list)) (setcursor-insert-string (cdr char-list)))) (defvar setcursor-dabbrev-first-point nil "holding value of POINT on first invocation") (defun setcursor-dabbrev-expand (arg) "Wrapping protective code around `dabbrev-expand'. There are two ways to do this. First would be to allow dabbrev to expand in inferior logo buffer, and then to correct the damage done. However, this is in most cases a bad idea, so we chose the second approach. We create the temporary buffer for dabbrev to work in, and then simply copy the command line back and forth." (interactive "*P") (let ((current-expansion)) (if (not (equal this-command last-command)) ;; we're starting on the new abbrev (let* ((oproc-mark (marker-position (process-mark (logo-proc)))) (logo-mark (marker-position comint-last-input-end)) (proc-buf (current-buffer)) (expand-point (- (point) oproc-mark))) (save-excursion ;; create tmp buffer if it doesn't exist (get-buffer-create " setcursor-tmp") ;; overwrite everything in tmp buffer with the current ;; inferior logo buffer command line (copy-to-buffer " setcursor-tmp" oproc-mark logo-mark) (set-buffer " setcursor-tmp") ;; set the dabbrev variables correctly for the new buffer (logo-tmp-dabbrev-setup) ;; place the cursor as in inferior logo buffer (after the abbrev) (goto-char (1+ expand-point)) ;; get rid of all the newlines in tmp buffer (save-excursion (goto-char (point-min)) (skip-chars-forward "^\n") (while (not (eobp)) (delete-char 1) (skip-chars-forward "^\n")))) ;; we're back in inferior logo buffer -- record the original ;; position of the cursor (setq setcursor-dabbrev-first-point (point)))) (unwind-protect ;; try to expand in tmp buffer (save-excursion (set-buffer " setcursor-tmp") (setq current-expansion nil) (dabbrev-expand arg) ;; record the current state of expansion (setq current-expansion (buffer-string))) ;; if expansion failed -- read the state of the tmp buffer (if (not current-expansion) (save-excursion (set-buffer " setcursor-tmp") (setq current-expansion (buffer-string)))) ;; back in inferior logo buffer -- replace the command line ;; with whatever is the state of tmp buffer (logo-setcursor-yank current-expansion t) ;; find the position after the current expansion, and place ;; the point there (goto-char setcursor-dabbrev-first-point) (skip-syntax-forward "\w") (if (char-equal (char-after) ?\n) (progn (forward-char) (skip-syntax-forward "\w")))))) (defvar setcursor-dabbrev-completion-point nil "holding value of POINT on invocation of `dabbrev-completion'") (defun setcursor-dabbrev-completion (arg) (interactive "*P") (setq setcursor-dabbrev-completion-point (point)) (let* ((oproc-mark (marker-position (process-mark (logo-proc)))) (logo-mark (marker-position comint-last-input-end)) (expand-point (- (point) oproc-mark)) (only-expansion nil)) (save-excursion ;; create tmp buffer if it doesn't exist (get-buffer-create " setcursor-tmp") ;; overwrite everything in tmp buffer with the current ;; inferior logo buffer command line (copy-to-buffer " setcursor-tmp" oproc-mark logo-mark) (set-buffer " setcursor-tmp") ;; set the dabbrev variables correctly for the new buffer (logo-tmp-dabbrev-setup) ;; place the cursor as in inferior logo buffer (after the abbrev) (goto-char (1+ expand-point)) ;; get rid of all the newlines in tmp buffer (save-excursion (goto-char (point-min)) (skip-chars-forward "^\n") (while (not (eobp)) (delete-char 1) (skip-chars-forward "^\n"))) ;; do the completion (dabbrev-completion arg) ;; if the completion is unique -- do the rest right away ;; if not -- do it anyway. This is redundant, as the original ;; line is copied back to inferior logo buffer. Anyway, the ;; *completions* window is opened now, and it's up to user ;; to choose the completion. The rest will be carried out ;; by the `setcursor-copy-expansion' function. (set-buffer " setcursor-tmp") (setq only-expansion (buffer-string))) ;; back in inferior logo buffer -- replace the command line ;; with whatever is the state of tmp buffer (logo-setcursor-yank only-expansion t) ;; find the position after the current expansion, and place ;; the point there (goto-char setcursor-dabbrev-completion-point) (skip-syntax-forward "\w") (if (char-equal (char-after) ?\n) (progn (forward-char) (skip-syntax-forward "\w"))))) (defun setcursor-copy-expansion () "Complete the dabbrev mouse completion in inferior logo buffer." ;; copy the state of tmp buffer (where the actual expansion took place) (let ((current-expansion (progn (set-buffer " setcursor-tmp") (buffer-string)))) ;; Make sure that the completion window is deleted (condition-case nil (delete-completion-window) (error nil)) ;; focus inferior logo buffer (switch-to-buffer logo-buffer) ;; back in inferior logo buffer -- replace the command line ;; with whatever is the state of tmp buffer (logo-setcursor-yank current-expansion t) ;; find the position after the current expansion, and place ;; the point there (goto-char setcursor-dabbrev-completion-point) (skip-syntax-forward "\w") (if (char-equal (char-after) ?\n) (progn (forward-char) (skip-syntax-forward "\w"))))) ;; End of 2D non comint related stuff ;;========================================================================== ;; (defvar logo-debug-file nil "Temporary file for logo contents output.") (if (not logo-debug-file) (setq logo-debug-file (make-temp-name "/tmp/DEBUG"))) (defvar logo-language 'standard "Controlling loading of .loops init file.") (defvar logo-load-language t "Allow changes to Logo") (defvar comint-input-sender nil "Variable holding function that sends input to Logo.") (make-variable-buffer-local 'mode-line-format) (defun logo-crowded-mode-line (modeline) "Removing extra spaces from mode line." (cond ((null modeline) nil) ((and (stringp (car modeline)) (string-match "[ ]+" (car modeline))) (cons (replace-match " " t t (car modeline)) (logo-crowded-mode-line (cdr modeline)))) (t (cons (car modeline) (logo-crowded-mode-line (cdr modeline)))))) (defvar logo-history-menu nil "Variable holding setcursor dynamic history menu.") (defun logo-inferior-mode-variables () "Initialize logo-process variables." (setq mode-line-format (logo-crowded-mode-line mode-line-format)) (setq indent-tabs-mode nil) ;; Forcing yank at start of logo input (make-variable-buffer-local 'mouse-yank-at-point) ;; Preventing `next-line' command from inserting newline (make-variable-buffer-local 'next-line-add-newlines) (setq next-line-add-newlines nil) (make-variable-buffer-local 'scroll-step) (setq comint-scroll-to-bottom-on-input nil) (setq comint-scroll-to-bottom-on-output t) (setq comint-input-ignoredups t) (logo-dabbrev-setup) ;; Hook variables (add-hook 'comint-output-filter-functions 'logo-idle-function) (add-hook 'comint-output-filter-functions 'comint-postoutput-overwrite) (make-local-hook 'view-mode-hook) (add-hook 'view-mode-hook 'logo-debug-function) (make-local-hook 'kill-buffer-hook) (add-hook 'kill-buffer-hook (lambda () ;; If this was debug buffer send debug request to Logo (if (equal (buffer-name) (file-name-nondirectory logo-debug-file)) (logo-send-debug)))) (make-local-hook 'kill-buffer-query-functions) (setq kill-buffer-query-functions nil) (add-hook 'kill-buffer-query-functions (lambda () ;; If killing Logo buffer ask first (if (and (equal (buffer-name (current-buffer)) logo-buffer) (get-buffer-process (current-buffer))) (yes-or-no-p "You are killing Logo buffer? ") t))) ;; Setcursor variables (setq comint-scroll-to-bottom-on-output nil) (setq comint-scroll-show-maximum-output t) (and logo-flash-on-movement ;; Setting up parens matching (progn (require 'paren) (show-paren-mode 1) (setq show-paren-style 'mixed) ;; echo matched text, if off screen (defadvice show-paren-function (before verbal-off-screen) (let ((message-log-max)) (and (char-equal (char-syntax (preceding-char)) ?\)) (blink-matching-open)))) (ad-activate 'show-paren-function) (setq blink-matching-delay 0))) ;; Setting setcursor history menu (setq logo-history-menu (cons "History List" nil)) (fset 'logo-history-menu (cons 'keymap logo-history-menu)) (setq comint-get-old-input (function (lambda nil (goto-char comint-last-input-end) (error "This is not available in logo mode")))) (setq comint-input-filter (function (lambda (string) (> (length string) 3)))) (setq comint-eol-on-send 'end-of-input) (setq comint-input-autoexpand nil) (setq scroll-step 1)) (defvar inferior-logo-mode-hook nil "*Hook for customizing inferior logo mode.") ;; This must be here -- used during startup (defun loops-fill-image-menu (&optional directory) (let ((images (append (directory-files default-directory t "\\w+\\.lgimg\\>") (and directory (directory-files directory t "\\w+\\.lgimg\\>"))))) (cons "Select Image" (mapcar (lambda (x) (cons x (cons (file-name-nondirectory x) (cons (list nil) 'menu-bar-select-loops-image)))) images)))) ;;; ===================== Key and menu maps ======================== ;; pacifying compiler with emacs 20.2 ;(defvar menu-bar-print-menu) (defvar inferior-logo-mode-map nil) (if inferior-logo-mode-map nil (setq inferior-logo-mode-map (copy-keymap comint-mode-map)) ;; Restoring part of tools menu from global map (if (or (< emacs-major-version 20) (and (= emacs-major-version 20) (< emacs-minor-version 3)) (and (> emacs-major-version 20) (not (boundp 'menu-bar-print-menu)))) nil ;; Restore print menu only if version > 20.2 and < 21.3 (unwind-protect (progn (prin1 emacs-major-version) (defvar logo-mode-print-menu (copy-keymap menu-bar-print-menu)) (define-key inferior-logo-mode-map [menu-bar print] (cons "Print" logo-mode-print-menu))))) (define-key inferior-logo-mode-map "\C-cl" ;Use prefix for older buffers 'logo-toggle-to-logo) (define-key inferior-logo-mode-map "\M-\C-f" 'logo-resize-frame) ;; Disabling completion commands (define-key inferior-logo-mode-map "\M-\t" 'ignore) ;; LOOPS menu (and logo-load-language (define-key inferior-logo-mode-map [menu-bar loops-menu] (cons "LOOPS" (make-sparse-keymap "LOOPS")))) ;; Logo language menu (if (and logo-load-language (let ((init-file (concat logo-tutorial-path "/dot.loops"))) (file-readable-p init-file))) (progn (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language] (cons "Language" (make-sparse-keymap "logo-language"))) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language loops-save-image] '("Save LOOPS Image" . loops-save-image)) (defvar loops-image-menu (loops-fill-image-menu) "Variable holding names of LOOPS images for dynamic menu.") (fset 'loops-image-menu (cons 'keymap loops-image-menu)) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language load-loops-image] '("Load LOOPS Image" . loops-image-menu)) (put 'menu-bar-select-loops-image 'apropos-inhibit t) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language separator1] '("--")) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language logo-set-default] '("Set Startup Default" . logo-set-default-language)) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language separator] '("--")) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language logo-dot-logo] '("Ucblogo + LOOPS" . logo-load-init-file)) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-language ucblogo-standard] '("Standard Ucblogo" . logo-remove-init-file)))) (define-key inferior-logo-mode-map [menu-bar loops-menu separator] '("--")) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-inspect-objects] '("Inspect Objects" . loops-start-inspector)) (define-key inferior-logo-mode-map [menu-bar loops-menu logo-browse-classes] '("Browse Classes" . loops-start-browser)) ;; Logo menu (define-key inferior-logo-mode-map [menu-bar logo-menu] (cons "Logo" (make-sparse-keymap "Logo"))) (define-key inferior-logo-mode-map [menu-bar logo-menu toggle-to-edit] '("Go to Edit" . toggle-to-edit)) (define-key inferior-logo-mode-map [menu-bar logo-menu separator] '("--")) ;; Logo Compiler menu (if (and logo-load-language (let ((init-file (concat logo-tutorial-path "/dot.loops"))) (file-readable-p init-file))) (progn (define-key inferior-logo-mode-map [menu-bar logo-menu logo-compiler] (cons "Compiler" (make-sparse-keymap "Compiler"))) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-compiler save-compiled] '("Save compiled procedures ..." . logo-save-compiled)) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-compiler compiler] '("Compile Workspace" . logo-structure-compile)))) ;; Debug menu (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug] (cons "Logo-debug" (make-sparse-keymap "Logo-debug"))) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug logo-erase] '("Erase..." . logo-erase)) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug separator] '("--")) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug logo-unstep] '("Unstep all" . logo-unstep-all)) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug logo-untrace] '("Untrace all" . logo-untrace-all)) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug logo-step] '("Step..." . logo-step)) (define-key inferior-logo-mode-map [menu-bar logo-menu logo-debug logo-trace] '("Trace..." . logo-trace)) ;; Messing with comint menu-bar order - making sure Logo is last. (and (memq 'help-menu menu-bar-final-items) (setq menu-bar-final-items (nconc (delq 'help-menu menu-bar-final-items) (if logo-load-language '(logo-menu loops-menu help-menu) '(logo-menu help-menu))))) ;; Rebinding self-insert keys (substitute-key-definition 'self-insert-command 'logo-setcursor-self-insert inferior-logo-mode-map (current-global-map)) ;; Disabling TAB (define-key inferior-logo-mode-map "\t" 'ignore) ;; Not much use for re-center in setcursor mode, but you may need ;; to find input end, if stepping through input history (define-key inferior-logo-mode-map "\C-l" 'logo-find-input-end) ;; Fixing long line problems after backspacing or deleting (define-key inferior-logo-mode-map [backspace] 'logo-setcursor-backspace) ;; Do this only if user altered global binding of delete key to delete-char (let ((delete (lookup-key (current-global-map) [delete]))) (if (or (equal delete 'delete-char) (equal delete "\C-d")) (define-key inferior-logo-mode-map [delete] 'logo-setcursor-delete) (define-key inferior-logo-mode-map [delete] 'logo-setcursor-backspace))) ;; Disabling comint-delchar-or-maybe-eof function (define-key inferior-logo-mode-map "\C-d" 'logo-setcursor-delete) ;; Overloading kill and yank (define-key inferior-logo-mode-map "\C-k" 'logo-setcursor-kill) (define-key inferior-logo-mode-map "\C-y" 'logo-setcursor-yank) (define-key inferior-logo-mode-map "\C-@" 'logo-set-input-mark) ;; mouse bindings (define-key inferior-logo-mode-map [mouse-1] 'logo-setcursor-mouse-1) (define-key inferior-logo-mode-map [down-mouse-2] 'mouse-set-point) (define-key inferior-logo-mode-map [mouse-2] 'logo-setcursor-yank) ;; disabling mouse-3 (define-key inferior-logo-mode-map [down-mouse-3] 'logo-mouse-set-point) (define-key inferior-logo-mode-map [mouse-3] 'logo-mouse-set-point) ;; disabling comint-kill-output (define-key inferior-logo-mode-map "\C-c\C-o" 'ignore) ;; disabling quarry-replace (define-key inferior-logo-mode-map [?\e ?\^%] 'ignore) (define-key inferior-logo-mode-map "\M-%" 'ignore) ;; redefining completions (define-key inferior-logo-mode-map "\M-/" 'setcursor-dabbrev-expand) (define-key inferior-logo-mode-map [?\e ?\^/] 'setcursor-dabbrev-completion) ;; redefining undo (define-key inferior-logo-mode-map "\C-_" 'logo-setcursor-undo) (define-key inferior-logo-mode-map [menu-bar edit undo] 'logo-setcursor-undo) ;; redefining kill-region (define-key inferior-logo-mode-map "\C-w" 'logo-setcursor-kill) (define-key inferior-logo-mode-map [menu-bar edit cut] 'logo-setcursor-kill) ;; redefining paste (define-key inferior-logo-mode-map [menu-bar edit paste] 'logo-setcursor-yank) ;; redefining delete-region (define-key inferior-logo-mode-map [menu-bar edit clear] 'logo-setcursor-kill) ;; disabling list-buffers (define-key inferior-logo-mode-map "\C-x\C-b" 'ignore) ;; disabling split-window (define-key inferior-logo-mode-map "\C-x2" 'ignore) ;; disabling comint "List Input History" (define-key inferior-logo-mode-map "\C-c\C-l" 'ignore) (define-key inferior-logo-mode-map [menu-bar inout list-history] '("" . (lambda () (interactive) (error "In setcursor mode use S-down-mouse-2 instead")))) ;; Pop-up menu for input history and file completion (defvar logo-popup-menu-map (make-sparse-keymap "Setcursor Menu")) (fset 'logo-dynamic-menu logo-popup-menu-map) (define-key logo-popup-menu-map [logo-select-history] '("List Input History" . logo-history-menu)) (put 'logo-history-menu 'menu-enable '(cdr logo-history-menu)) (define-key inferior-logo-mode-map [S-down-mouse-2] 'logo-dynamic-menu)) (put 'loops-image-menu 'menu-enable '(and (cdr loops-image-menu) (eq logo-language 'dot-loops))) (put 'loops-save-image 'menu-enable '(eq logo-language 'dot-loops)) (setplist 'logo-save-compiled '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (eq logo-language 'dot-loops)))) (setplist 'logo-structure-compile '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (eq logo-language 'dot-loops)))) (setplist 'logo-load-init-file '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (eq logo-language 'standard)))) (setplist 'logo-remove-init-file '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (eq logo-language 'dot-loops)))) (setplist 'logo-trace '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-step '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-erase '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-untrace-all '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'logo-unstep-all '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p)))) (setplist 'loops-start-inspector '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (eq logo-language 'dot-loops)))) (setplist 'loops-start-browser '(menu-enable (and (get-buffer-process logo-buffer) (not logo-busy-p) (eq logo-language 'dot-loops)))) ;; Can't use get-old-input in setcursor mode (setplist 'comint-copy-old-input '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling comint-kill-output in setcursor mode (setplist 'comint-kill-output '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling Complete menu in setcursor mode. Has no (or little) ;; value in Logo anyway. (setplist 'comint-dynamic-complete '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'comint-dynamic-complete-filename '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'comint-dynamic-list-filename-completions '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'comint-replace-by-expanded-filename '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling replace operations in setcursor mode (setplist 'query-replace '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'query-replace-regexp '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling Select and Paste in setcursor mode (setplist 'menu-bar-select-yank '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling List All Buffers in setcursor mode (setplist 'list-buffers '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling split-window-vertically in setcursor mode (setplist 'split-window-vertically '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;; Disabling File menu entries in logo-inferior (setplist 'find-file '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'dired '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'recover-session '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'insert-file '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) (setplist 'delete-frame '(menu-enable (and (not (eq major-mode 'inferior-logo-mode)) (cddr (filtered-frame-list 'frame-live-p))))) (setplist 'make-frame-on-display '(menu-enable (not (eq major-mode 'inferior-logo-mode)))) ;;; ====================== test code ============================== ; (define-key inferior-logo-mode-map "\M-\C-t" 'logo-test) ; (defun logo-test () ; (interactive) ; (prin1 (selected-frame)) ; (set-frame-size (selected-frame) ; (+ 1 process-term-columns) ; (+ 2 process-term-rows))) ;;; ====================== end test code ========================== (defun inferior-logo-mode () "Major mode for interacting with an inferior Logo process. Simulating two-dimensional nonsequential display. Key and mouse bindings are as in comint-mode, except for C-l, which does not re-center. We do not want re-centering in inferior-logo mode. Instead it sends the point to the end of current input, or to the process-mark \\=(point where command line starts\\=). Emacs sets the end of current input marker automatically. If you want to override this, set the comint-last-input-end manually with C-@ . DEL, Backspace, and C-d work only within the limits of command \\=(input\\=) line. C-k, C-y and mouse-2 \\=(mouse paste\\=) work only on the whole command line. No matter where your point is C-k will always kill input line, and C-y and mouse-2 will always yank-back last X-selection or first entry from kill-ring \\=(if X-selection does not exist\\=). The following commands are available: \\{inferior-logo-mode-map}" (interactive) (comint-mode) (setq comint-prompt-regexp "^[^\n]*\\(?\\|>\\|~\\|\|\\)+\\ +") (setq major-mode 'inferior-logo-mode) (setq mode-name "Inferior Logo") (setq mode-line-process '(": %s")) (use-local-map inferior-logo-mode-map) (set-syntax-table inferior-logo-mode-syntax-table) (logo-inferior-mode-variables) (set-process-filter (get-process "logo") 'logo-default-filter) (setq mouse-yank-at-point t) ;; Make sure there's no other windows in inferior logo mode frame (delete-other-windows) (run-hooks 'inferior-logo-mode-hook)) ;;;###autoload (defun run-logo () (interactive) (setq pop-up-frames logo-frames) (logo-term-setup) (add-hook 'comint-mode-hook (lambda () (setq comint-terminal-return (symbol-function 'logo-terminal-return)) (setq comint-strip-input-function (symbol-function 'logo-strip-newline)) (setq comint-insert-previous-input-function (symbol-function 'comint-overwrite-previous-input)))) (let ((process-defines-term (list logo-term process-term-columns process-term-rows))) (set-buffer (apply 'make-comint "logo" logo-binary-name nil nil))) (inferior-logo-mode) (setq logo-buffer "*logo*") (let ((frame (window-frame (get-buffer-window (logo-switch-buffer "*logo*"))))) ;; Must force redisplay here (preventing Gnome Nautilus resizing) (sit-for .1) ;; Making sure that display is set the way Logo expects it! ;; Need one more to put 80 in one row (logo-frame-resize frame)) ;; Overriding any user settings (setq transient-mark-mode nil) (setq truncate-lines nil) (setq pop-up-frames nil) (auto-fill-mode -1) ;; Loading .loops - initialization file (and logo-load-language (eq logo-language 'dot-loops) (logo-load-init-file))) ;;;###autoload (add-hook 'same-window-buffer-names "*logo*") ;;; =========================================================== (defun logo-resize-frame () "Resize the logo inferior buffer frame to requred size." (interactive) (logo-frame-resize (selected-frame))) (defun logo-frame-resize (frame) "Resize the logo inferior buffer frame to requred size." (set-frame-size frame (+ 1 process-term-columns) (+ 2 process-term-rows (if (and (fboundp 'tool-bar-mode) tool-bar-mode) (tool-bar-lines-needed) 0)))) (defun logo-load-init-file () "Load .loops initialization file into Logo." (interactive) (let ((init-file (concat logo-tutorial-path "/dot.loops"))) (and (file-readable-p init-file) (setq logo-language 'dot-loops) (comint-send-string (logo-proc) (concat "load " (logoize-path init-file) "\n"))))) (defun logo-remove-init-file () "Restore Berkeley Logo Standard language." (interactive) (setq logo-language 'standard) (comint-send-string (logo-proc) "restore.standard erase \"restore.standard \n")) (defun logo-set-default-language () "Set default language level on startup." (interactive) (and (yes-or-no-p (concat "Do you want to make " (if (eq logo-language 'standard) " Standard Ucblogo " " Ucblogo + LOOPS ") "default startup language?")) (if (eq logo-language 'standard) (logo-edit-dot-emacs "^[ \t]*([ \t]*setq[ \t]+logo-language[ \t]+'dot-loops[ \t]*)") (logo-edit-dot-emacs "^[ \t;]*([ \t]*setq[ \t]+logo-language[ \t]+'dot-loops[ \t]*)" "(setq logo-language 'dot-loops)\n")))) (defun logo-edit-dot-emacs (string &optional replacement) "Edit .emacs to set default language level." (let ((dot-emacs (substitute-in-file-name "$HOME/.emacs"))) (if (and (file-readable-p dot-emacs) (file-writable-p dot-emacs)) (progn (find-file dot-emacs) (goto-char (point-max)) (let ((start (re-search-backward string nil t))) (cond ;; 'standard' is the default anyway ((and (not start) (not replacement)) 'do-nothing) ;; No previous references - setting 'dot-loops' ((not start) (goto-char (point-max)) (newline) (insert replacement)) ;; Setting 'standard' -- just commenting out ((not replacement) (insert ";")) ;; Setting 'dot-loops' (t (delete-matching-lines string) (insert replacement)))) (save-buffer) (kill-buffer (current-buffer))) (error "Check permisions on your .emacs file")))) (defun logo-structure-compile () "Start loops.compiler on the workspace." (interactive) (comint-send-string (logo-proc) "pr [] ws.compile \n")) (defun logo-save-compiled () "Save compiled procedures to a file." (interactive) (comint-send-string (logo-proc) "(save.compiled) \n")) (defun logo-idle-function (output) "Resets busy flag if Logo idling." (if (string-match "^[ \t]*\\?\\ \\'" output) (setq logo-busy-p nil))) (defun logo-toggle-to-logo (&optional n) "Toggle from edit to Logo process buffer and vice-versa." (interactive "P") (if (equal (buffer-name) logo-buffer) (let ((ed-buffer (nth (1- (prefix-numeric-value n)) logo-edit-buflist))) (if ed-buffer (logo-popup-frames logo-frames (logo-switch-buffer ed-buffer)) (error "No logo files opened"))) (if logo-buffer (logo-popup-frames logo-frames (logo-switch-buffer logo-buffer)) (error "No logo process buffer")))) (defun logo-set-input-mark () "Setting comint-last-input-end at the end of Logo command line manually." (interactive) (set-marker comint-last-input-end (point)) (message "Logo input mark set.")) (defun logo-find-input-end () "Returns point to current input end -- end of Logo command line." (interactive) (goto-char comint-last-input-end)) ;;; setcursor hystory popup menu (defcustom logo-history-menu-length 56 "*Maximum length to display in the history-menu." :type 'integer :group 'mouse) (defcustom logo-dynamic-menu-depth (let ((pixels (x-display-pixel-height))) (cond ((> pixels 1023) (min 42 comint-input-ring-size)) ((> pixels 863) (min 36 comint-input-ring-size)) ((> pixels 767) (min 32 comint-input-ring-size)) ((> pixels 599) (min 25 comint-input-ring-size)) (t (min 20 comint-input-ring-size)))) "*Maximum number of entries in the dynamic-menu." :type 'integer :group 'mouse) (defun logo-update-history-menu (string) (let ((front (car (cdr logo-history-menu))) (menu-string (if (<= (length string) logo-history-menu-length) string (concat (substring string 0 (/ logo-history-menu-length 2)) "..." (substring string (- (/ logo-history-menu-length 2))))))) ;; Don't let the menu string be all dashes ;; because that has a special meaning in a menu. (if (string-match "\\`-+\\'" menu-string) (setq menu-string (concat menu-string " "))) (setcdr logo-history-menu (cons (cons string (cons menu-string 'logo-menu-select-history)) (cdr logo-history-menu))) (if (> (length (cdr logo-history-menu)) logo-dynamic-menu-depth) (setcdr (nthcdr logo-dynamic-menu-depth logo-history-menu) nil)))) (put 'logo-menu-select-history 'apropos-inhibit t) (defun logo-menu-select-history () "Pop-up a menu with input history items." (interactive "*") (push-mark (point)) (comint-overwrite-previous-input last-command-event)) (defun logo-setcursor-mouse-1 (event) "Sending point to comint-last-input-end after click with mouse-1. Avoiding beeping after clicking to focus inferior-logo buffer." (interactive "@e") (mouse-set-point event) ;; Jump only if point is out of logo command line (if (or (< (point) (marker-position (process-mark (logo-proc)))) (> (point) (marker-position comint-last-input-end))) (goto-char comint-last-input-end))) ;;; ======================== Logo debugging ======================== ;; ;;; Logo-debug mode (defvar logo-procedures nil "part of logo contents list.") (defvar logo-variables nil "part of logo contents list.") (defvar logo-properties nil "part of logo contents list.") (defvar logo-debug-string nil "mode line identifier.") (defvar logo-debug-command nil "trace step or erase") (defvar logo-debug-mode nil "Mode variable for logo-debug minor mode.") (make-variable-buffer-local 'logo-debug-mode) (defvar logo-debug-mode-map nil) (if logo-debug-mode-map nil (setq logo-debug-mode-map (make-sparse-keymap)) ;; Overriding dangerous keys in View-mode (define-key logo-help-mode-map "E" 'ignore) (define-key logo-help-mode-map "e" 'ignore) (define-key logo-help-mode-map "Q" 'ignore) (define-key logo-help-mode-map "c" 'ignore) (define-key logo-help-mode-map "C" 'ignore) ;; mouse bindings (define-key logo-debug-mode-map [down-mouse-1] 'logo-mouse-set-point) (define-key logo-debug-mode-map [mouse-1] 'logo-xor-debug) (define-key logo-debug-mode-map [down-mouse-2] 'logo-mouse-set-point) (define-key logo-debug-mode-map [mouse-2] 'logo-or-debug) (define-key logo-debug-mode-map [down-mouse-3] 'logo-mouse-set-point) (define-key logo-debug-mode-map [mouse-3] 'logo-and-go-debug)) (defun logo-debug-mode () "Logo debug minor mode. Mouse bindings are as in XFM file-manager. Mouse-1 De-selects everything previously selected in category (procedures, variables, properties) and selects chosen name. Mouse-2 toggles selection for name. Mouse-3 selects and quits debug buffer. `q' key also quits buffer and sends the selected contents list to Logo. \\{logo-debug-mode-map}" (interactive) (logo-debug-mode-initialize) (setq logo-debug-mode t)) (defun logo-debug-mode-initialize () (or (assq 'logo-debug-mode minor-mode-map-alist) (setq minor-mode-map-alist (cons (cons 'logo-debug-mode logo-debug-mode-map) minor-mode-map-alist))) (if (not (assq 'logo-debug-mode minor-mode-alist)) (setq minor-mode-alist (cons (list 'logo-debug-mode logo-debug-string) minor-mode-alist)) (setcdr (assq 'logo-debug-mode minor-mode-alist) (list logo-debug-string))) (logo-debug-mode-sintax)) (defun logo-debug-mode-sintax () "Syntax changes to view/fundamental mode." ;; Logo specific word constituents (modify-syntax-entry ?. "w ") (modify-syntax-entry ?? "w ") (modify-syntax-entry ?_ "w ") (modify-syntax-entry ?: "w ") (modify-syntax-entry ?, "w ") ;; These are here to handle names in CSLS match program (modify-syntax-entry ?^ "w ") (modify-syntax-entry ?# "w ") (modify-syntax-entry ?@ "w ") (modify-syntax-entry ?& "w ") (modify-syntax-entry ?! "w ") (modify-syntax-entry ?' "w ") ;; These are for nut-cases that enjoy constructing names with `\' (modify-syntax-entry ?+ "w ") (modify-syntax-entry ?- "w ") (modify-syntax-entry ?* "w ") (modify-syntax-entry ?/ "w ") (modify-syntax-entry ?< "w ") (modify-syntax-entry ?> "w ") (modify-syntax-entry ?~ "w ")) (defun logo-debug-function () "Initializes debug mode." (and (equal (buffer-file-name) logo-debug-file) (logo-debug-mode))) (defun logo-debug-select (command) "Show contents for selection." (if (not (file-writable-p logo-debug-file)) (error "Check your write permission on %s" logo-debug-file)) (setq logo-debug-command command) (logo-flush-contents) (logo-send-command (concat "emacs.debug " (logoize-path logo-debug-file) (cond ((string= "trace" command) " \"traced untrace contents") ((string= "step" command) " \"stepped unstep contents") ;; Just display contents -- for erase (t " [[] [] []]")))) ;; I guess 5 seconds should do even on *very* slow machine (with-timeout (5 (error "Logo did not write to %s file" logo-debug-file)) (while (or (not (file-readable-p logo-debug-file)) logo-busy-p) (sleep-for 0.3))) (unwind-protect (progn (remove-hook 'view-mode-hook 'logo-help-function) (view-file logo-debug-file) (setq buffer-read-only nil) (fill-region (point-min) (point-max) 'left) (setq buffer-read-only t) (logo-debug-overlay) (save-buffer 0) (delete-file logo-debug-file)) (add-hook 'view-mode-hook 'logo-help-function))) (defun logo-debug-overlay () "Arrange overlays for debug buffer." (goto-char (point-min)) (re-search-forward "PROCEDURES:") (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'bold) (beginning-of-line 3) (let ((proc-beg (point))) (re-search-forward "VARIABLES:") (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'bold) (end-of-line 0) (overlay-put (make-overlay proc-beg (point)) 'category 'logo-procedures) (beginning-of-line 4) (let ((var-beg (point))) (re-search-forward "PROPERTIES:") (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'bold) (end-of-line 0) (overlay-put (make-overlay var-beg (point)) 'category 'logo-variables)) (beginning-of-line 4) (overlay-put (make-overlay (point) (point-max)) 'category 'logo-properties) (goto-char proc-beg) (logo-mark-debugged) (goto-char proc-beg))) (defun logo-mark-debugged () "Marking previously traced or stepped names." (while (and (skip-chars-forward "^(") (not (eobp))) (or (progn (forward-char) (skip-syntax-forward "\w" (point-max)) (if (looking-at ")") (progn (add-to-list (overlay-get (car (overlays-at (point))) 'category) (current-word t)) (logo-highlight 'highlight)))) (forward-char)))) (defun logo-trace () "Select objects for tracing." (interactive) (setq logo-debug-string " Logo-TRACE") (logo-debug-select "trace")) (defun logo-step () "Select objects for stepping." (interactive) (setq logo-debug-string " Logo-STEP") (logo-debug-select "step")) (defun logo-erase () "Select objects for erasing from Logo workspace." (interactive) (setq logo-debug-string " Logo-ERASE") (logo-debug-select "erase")) (defun logo-untrace-all () "Untracing contents." (interactive) (logo-send-command "untrace contents")) (defun logo-unstep-all () "Unstepping contents." (interactive) (logo-send-command "unstep contents")) (defun logo-send-command (command) "Send debug command to process Logo." (comint-send-string (logo-proc) (concat command " pr []\n"))) (defun logoize-path (path) "Convert path to logo path." (concat "\"" (logoize-help path))) (defun logoize-help (path) "Double the `/'" (if (string-match "\\(\\`\\|[^/]\\)\\(/\\)[^/]" path) (logoize-help (replace-match "//" t t path 2)) path)) (defun logo-highlight (face) "Highlight debug selection." (save-excursion (let* ((beg (progn (skip-syntax-backward "\w") (point))) (end (progn (skip-syntax-forward "\w") (point))) (highlight (or (logo-overlaid-p (overlays-at beg) beg end) (make-overlay beg end)))) (overlay-put highlight 'face face)))) (defun logo-overlaid-p (overlays beg end) "Use existing overlay if created?" (cond ((null overlays) nil) ((and (= (overlay-start (car overlays)) beg) (= (overlay-end (car overlays)) end)) (car overlays)) (t (logo-overlaid-p (cdr overlays) beg end)))) (defun logo-extinguish () "Turn off highlighting for category." (save-excursion (mark-paragraph) (while (< (point) (mark)) (forward-word 1) (if (cdr (overlays-at (1- (point)))) (logo-highlight 'default))))) (defun logo-and-go-debug (event) "Close debug window and send names to logo." (interactive "@e") (mouse-set-point event) (let* ((word (current-word t)) (overlay (overlays-at (point))) (category (and overlay (or (overlay-get (car overlay) 'category) (condition-case nil (overlay-get (car (cdr overlay)) 'category) (error nil)))))) (if (or (not word) (not (= (point) logo-mouse-pos)) (not category)) (message "Mouse-3 adds and sends to logo -- point to `name' and try again.") (add-to-list category word) (if (< emacs-major-version 20) (view-exit) (View-kill-and-leave))))) (defun logo-or-debug (event) "Add or remove `name' to appropriate list of names for debugging." (interactive "@e") (mouse-set-point event) (let* ((word (current-word t)) (overlay (overlays-at (point))) (category (and overlay (or (overlay-get (car overlay) 'category) (condition-case nil (overlay-get (car (cdr overlay)) 'category) (error nil)))))) (if (or (not word) (not (= (point) logo-mouse-pos)) (not category)) (message "Mouse-2 reverses choice -- point to `name' and try again.") (if (member word (eval category)) (progn (logo-highlight 'default) (set category (delete word (eval category)))) (logo-highlight 'highlight) (add-to-list category word))))) (defun logo-xor-debug (event) "Remove all and add `name' to appropriate list of names for debugging." (interactive "@e") (mouse-set-point event) (let* ((word (current-word t)) (overlay (overlays-at (point))) (category (and overlay (or (overlay-get (car overlay) 'category) (condition-case nil (overlay-get (car (cdr overlay)) 'category) (error nil)))))) (if (or (not word) (not (= (point) logo-mouse-pos)) (not category)) (message "Mouse-1 flushes all, then adds to list -- point to `name' and try again.") (logo-extinguish) (logo-highlight 'highlight) (logo-flush-contents category) (add-to-list category word)))) (defun logo-send-debug () "Send debug request to logo process." (logo-send-command (concat logo-debug-command "[" (logo-contents-to-string (list logo-procedures logo-variables logo-properties)) (if (string= logo-debug-command "erase") " gc" "")))) (defun logo-flush-contents (&optional category) "Flushing three parts of contents list." (if category (set category nil) (setq logo-procedures nil) (setq logo-variables nil) (setq logo-properties nil))) (defun logo-contents-to-string (contents) "convert contents list to string." (cond ((stringp contents) contents) ((null contents) "]") (t (concat (if (listp (car contents)) "[" " ") (logo-contents-to-string (car contents)) (logo-contents-to-string (cdr contents)))))) ;;; ========================== LOOPS ========================== ;;; =========================================================== (defun menu-bar-select-loops-image () "Select LOOPS image from dynamic menu." (interactive "*") (push-mark (point)) (logo-send-command (concat "load " (logoize-path last-command-event)))) (defun loops-save-image (filename) (interactive (list (read-file-name "Image file: " default-directory (expand-file-name "loops.lgimg" default-directory) nil "loops.lgimg"))) (or (null filename) (string-equal filename "") (progn ;; If arg is just a directory, ;; use the default file name, but in that directory. (if (file-directory-p filename) (setq filename (concat (file-name-as-directory filename) "loops.lgimg"))) (and (file-exists-p filename) (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) (error "Canceled"))))) (logo-send-command (concat "save.image " (logoize-path (expand-file-name filename)))) (with-timeout (5 (error "Logo did not write to %s file" filename)) (while (or (not (file-readable-p filename)) logo-busy-p) (sleep-for 0.3))) (setq loops-image-menu (loops-fill-image-menu (let ((dir (file-name-directory filename))) (if (not (string-equal dir default-directory)) dir nil)))) (fset 'loops-image-menu (cons 'keymap loops-image-menu)) (find-file filename) (logo-mode-on t)) ;;; ===================== Inspector Modes ===================== (defvar loops-inspector-name "LOOPS-Inspector" "Variable holding the name of Inspector Frame") (defvar loops-inspector-file nil "Temporary file for loops methods & objects output.") (if (not loops-inspector-file) (setq loops-inspector-file (make-temp-name (concat "/tmp/" loops-inspector-name)))) (defvar loops-csource-file nil "Temporary file for loops methods & objects output.") (if (not loops-csource-file) (setq loops-csource-file (make-temp-name (concat "/tmp/" loops-inspector-name)))) (make-variable-buffer-local 'revert-without-query) (defvar loops-inspect-string " Inspector" "mode line identifier.") (defvar loops-inspect-mode nil "Mode variable for logo-debug minor mode.") (make-variable-buffer-local 'loops-inspect-mode) (defvar loops-show-string " Show-Compiled" "mode line identifier.") (defvar loops-show-mode nil "Mode variable for logo-debug minor mode.") (make-variable-buffer-local 'loops-show-mode) (defvar loops-inspect-mode-map nil) (if loops-inspect-mode-map nil (setq loops-inspect-mode-map (make-sparse-keymap)) ;; mouse bindings (define-key loops-inspect-mode-map [down-mouse-1] 'logo-mouse-set-point) ;(define-key loops-inspect-mode-map [mouse-1] 'loops-show-compiled) (define-key loops-inspect-mode-map [down-mouse-2] 'logo-mouse-set-point) (define-key loops-inspect-mode-map [mouse-2] 'loops-show-compiled) (define-key loops-inspect-mode-map [down-mouse-3] 'logo-mouse-set-point) (define-key loops-inspect-mode-map [mouse-3] 'loops-show-raw)) (defvar loops-show-mode-map nil) (if loops-show-mode-map nil (setq loops-show-mode-map (make-sparse-keymap)) (define-key loops-show-mode-map [down-mouse-1] 'logo-mouse-set-point) (define-key loops-show-mode-map [mouse-1] 'logo-mouse-set-point) (define-key loops-show-mode-map [down-mouse-2] 'ignore) (define-key loops-show-mode-map [mouse-2] 'ignore) (define-key loops-show-mode-map [down-mouse-3] 'ignore) (define-key loops-show-mode-map [mouse-3] 'ignore)) (defun loops-inspect-mode () (interactive) (loops-inspect-mode-initialize) (setq loops-inspect-mode t)) (defun loops-show-mode () (interactive) (loops-show-mode-initialize) (setq loops-show-mode t)) (defun loops-inspect-mode-initialize () (or (assq 'loops-inspect-mode minor-mode-map-alist) (setq minor-mode-map-alist (cons (cons 'loops-inspect-mode loops-inspect-mode-map) minor-mode-map-alist))) (if (not (assq 'loops-inspect-mode minor-mode-alist)) (setq minor-mode-alist (cons (list 'loops-inspect-mode loops-inspect-string) minor-mode-alist)) (setcdr (assq 'loops-inspect-mode minor-mode-alist) (list loops-inspect-string))) (logo-debug-mode-sintax) (loops-inspect-overlay)) (defvar loops-method-beg nil) (defvar loops-top-beg nil) (defvar loops-virtual-beg nil) (defun loops-inspect-overlay () "Arrange overlays for debug buffer." (let ((overlays (overlay-lists))) (mapcar 'delete-overlay (append (car overlays) (cdr overlays)))) (goto-char (point-min)) (re-search-forward "COMPILED-METHODS:") (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'bold) (beginning-of-line 3) (setq loops-method-beg (point)) (re-search-forward "TOP-LEVEL-OBJECTS:") (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'bold) (end-of-line 0) (overlay-put (make-overlay loops-method-beg (point)) 'category 'loops-methods) (beginning-of-line 4) (setq loops-top-beg (point)) (re-search-forward "VIRTUAL-OBJECTS:") (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'bold) (end-of-line 0) (overlay-put (make-overlay loops-top-beg (point)) 'category 'loops-top) (beginning-of-line 4) (setq loops-virtual-beg (point)) (overlay-put (make-overlay (point) (point-max)) 'category 'loops-virtual) (goto-char loops-method-beg)) (defun loops-show-mode-initialize () (or (assq 'loops-show-mode minor-mode-map-alist) (setq minor-mode-map-alist (cons (cons 'loops-show-mode loops-show-mode-map) minor-mode-map-alist))) (if (not (assq 'loops-show-mode minor-mode-alist)) (setq minor-mode-alist (cons (list 'loops-show-mode loops-show-string) minor-mode-alist)) (setcdr (assq 'loops-show-mode minor-mode-alist) (list loops-show-string))) (set-syntax-table logo-mode-syntax-table) (logo-syntax-colors) (if logo-syntax-highlight (logo-font-lock-mode 1) (logo-font-lock-mode -1))) (defun loops-start-inspector () "Opening LOOPS Inspector frame." (interactive) ;; forcing new frame (let ((frame (car (filtered-frame-list (lambda (x) (string-equal loops-inspector-name (frame-parameter x 'name))))))) (if frame (progn (raise-frame frame) (select-frame frame)) (if (not (file-writable-p loops-inspector-file)) (error "Check your write permission on %s" loops-inspector-file)) (select-frame (make-frame-command)) (set-frame-name loops-inspector-name) (switch-to-buffer (create-file-buffer loops-inspector-file)) (write-file loops-inspector-file) (delete-file loops-inspector-file)) (loops-methods-objects "Waiting for Logo output "))) (defun loops-methods-objects (msg) "Show methods & objects for inspection." (logo-send-command (concat "inspect.methods.objects " (logoize-path loops-inspector-file))) (select-window (frame-first-window)) ;; I guess 60 seconds should do! This is *very* slow (with-timeout (60 (error "Logo did not write to %s file" loops-inspector-file)) (while (or (not (file-readable-p loops-inspector-file)) logo-busy-p) (setq msg (concat msg ".")) (with-timeout (0.01) (momentary-string-display msg (point-max) ?\ " ")) (sleep-for 1))) (unwind-protect (progn (let ((revert-without-query (cons loops-inspector-name revert-without-query))) (revert-buffer t t) (fill-region (point-min) (point-max) 'left) (setq buffer-read-only t) (loops-inspect-mode) (save-buffer 0))) (delete-file loops-inspector-file))) (defun loops-show-compiled (event) (interactive "@e") (mouse-set-point event) (if logo-busy-p (error "Logo is busy")) (logo-send-command (concat "show.method.object " "\"" (loops-xor-show event) " " (logoize-path loops-csource-file) " " "\"true")) (loops-show)) (defun loops-show-raw (event) (interactive "@e") (mouse-set-point event) (if logo-busy-p (error "Logo is busy")) (logo-send-command (concat "(show.method.object " "\"" (loops-xor-show event) " " (logoize-path loops-csource-file) ")")) (loops-show)) (defun loops-show () ;; I guess 5 seconds should do! (with-timeout (5 (error "Logo did not write to %s file" loops-csource-file)) (while (or (not (file-readable-p loops-csource-file)) logo-busy-p) (sleep-for 0.3))) (unwind-protect (progn (let ((revert-without-query (cons loops-inspector-name revert-without-query))) (find-file-read-only-other-window loops-csource-file) (setq buffer-read-only t) (loops-show-mode) (save-buffer 0))) (delete-file loops-csource-file))) (defun loops-xor-show (event) "Remove previous highlighting, and highlight new name." (mouse-set-point event) (let* ((word (current-word t)) (overlay (overlays-at (point))) (category (and overlay (or (overlay-get (car overlay) 'category) (condition-case nil (overlay-get (car (cdr overlay)) 'category) (error nil)))))) (if (or (not word) (not (= (point) logo-mouse-pos)) (not category)) (message "Point to Method/Object `name' and try again.") (loops-extinguish) (logo-highlight 'highlight)) word)) (defun loops-extinguish () "Turn off highlighting for category." (letrec ((extinguish (lambda () (while (< (point) (mark)) (forward-word 1) (if (cdr (overlays-at (1- (point)))) (logo-highlight 'default)))))) (save-excursion (goto-char loops-method-beg) (mark-paragraph) (extinguish) (goto-char loops-top-beg) (mark-paragraph) (extinguish) (goto-char (point-max)) (push-mark) (goto-char loops-virtual-beg) (extinguish)))) ;;; ====================== Browser Modes ========================== (defvar loops-browser-name "Class-Browser" "Variable holding the name of Browser Frame") (defvar loops-browser-file nil "Temporary file for loops class tree output.") (if (not loops-browser-file) (setq loops-browser-file (make-temp-name (concat "/tmp/" loops-browser-name)))) (defvar loops-image-name "loops-" "") (defvar loops-class-file nil "Temporary file for loops image file.") (if (not loops-class-file) (setq loops-class-file (or (let ((img-file (expand-file-name (concat (make-temp-name (concat default-directory loops-image-name)) ".lgimg")))) (and (file-writable-p img-file) img-file)) (let ((img-file (substitute-in-file-name (concat (make-temp-name (concat "$HOME/" loops-image-name)) ".lgimg")))) (and (file-writable-p img-file) img-file)) (make-temp-name (concat "/tmp/" loops-image-name ".lgimg"))))) (defvar loops-browse-mode nil "") (define-derived-mode loops-browse-mode outline-mode "Browser" "Major mode for browsing LOOPS classes.\n\n{loops-browse-mode-map}" (setq-default outline-regexp "[\t\^L]+")) (define-key loops-browse-mode-map [down-mouse-1] 'logo-mouse-set-point) (define-key loops-browse-mode-map [mouse-1] 'show-children) (define-key loops-browse-mode-map [down-mouse-2] 'logo-mouse-set-point) (define-key loops-browse-mode-map [mouse-2] 'hide-subtree) (define-key loops-browse-mode-map [down-mouse-3] 'logo-mouse-set-point) (define-key loops-browse-mode-map [mouse-3] 'loops-view-class) ;;; Class view mode (defvar loops-view-mode-hook nil "") (defvar loops-view-mode nil "") (define-derived-mode loops-view-mode logo-mode "Class-view" "Major mode for viewing LOOPS classes.\n\n{loops-view-mode-map}" (add-hook 'loops-view-mode-hook (lambda () (setq buffer-read-only t) (setq revert-without-query (cons (file-name-nondirectory loops-class-file) revert-without-query))))) (defun loops-popup-context-menu (event) (interactive "@e") (mouse-set-point event) (let* ((overlay (car (overlays-at (point)))) (context (and (overlayp overlay) (overlay-get overlay 'context)))) (cond ((equal context 'prologue) (eval (x-popup-menu t '(keymap (loops-new-class "New-class (using current class as superclass)" . t) (loops-edit-class "Edit-class (current class)" . t) "Browser Editor: Class")))) ((equal context 'object) (eval (x-popup-menu t '(keymap (loops-edit-class "Edit-class (current class)" . t) "Browser Editor: Object")))) ((equal context 'method) (eval (x-popup-menu t '(keymap (loops-edit-methods "Edit-methods (altering behavior of defined objects)" . t) (loops-new-method "New-method (altering behavior of defined objects)" . t) "Browser Editor: Method")))) (t (error "Point to one of three text areas, and try again"))))) (define-key loops-view-mode-map [S-down-mouse-2] 'loops-popup-context-menu) (defun loops-browse-overlay () "Arrange overlays for class browser buffer." (let ((overlays (overlay-lists))) (mapcar 'delete-overlay (append (car overlays) (cdr overlays)))) (goto-char (point-min)) (let ((class-beg (point))) (overlay-put (make-overlay (point) (point-max)) 'category 'loops-classes)) (goto-char (point-min))) (defun loops-view-overlay () "Arrange overlays for class view buffer." (let ((overlays (overlay-lists))) (mapcar 'delete-overlay (append (car overlays) (cdr overlays)))) (goto-char (point-min)) (loops-insert-coments) (goto-char (point-min)) (let ((prologue (progn (re-search-forward "^[ \t]*;+[ \t]* end of IDE inherit statement\\([ \t]+\\|$\\)") (make-overlay (point-min) (match-end 0)))) (object (let ((start (+ (point) 1))) (re-search-forward "^[ \t]*;+[ \t]* start of class method definition\\([ \t]+\\|$\\)") (make-overlay start (progn (beginning-of-line) (- (point) 1))))) (methods (make-overlay (point) (point-max)))) (overlay-put prologue 'context 'prologue) (overlay-put object 'context 'object) (overlay-put methods 'context 'method) (goto-char (point-min)))) (defun loops-insert-coments () "Insert comments for diffrent areas of the class definition." (setq buffer-read-only nil) (let ((inherit (re-search-forward "^[ \t]*;+[ \t]* end of IDE inherit statement\\([ \t]+\\|$\\)" (+ (point) 512) t))) (or inherit (progn (logo-next-line) (insert ";; start of IDE inherit statement\n") (if (looking-at "^[ \t]*inherit\\.from[ \t]+") (logo-next-line) (insert "\n")) (insert ";; end of IDE inherit statement\n")))) (let ((method (re-search-forward "^[ \t]*;+[ \t]* start of class method definition\\([ \t]+\\|$\\)" (+ (point) 1024) t))) (or method (progn (re-search-forward "^[ \t]*lambda[ \t]+") (beginning-of-line) (insert ";; start of class method definition\n")))) (setq buffer-read-only t)) (defun logo-next-line () (beginning-of-line 2) (while (and (not (eobp)) (or (logo-indent-p t) (logo-in-string-p))) (beginning-of-line 2))) (defun loops-start-browser () "Opening LOOPS Browser frame." (interactive) ;; forcing new frame (let ((frame (car (filtered-frame-list (lambda (x) (string-equal loops-browser-name (frame-parameter x 'name))))))) (if frame (progn (raise-frame frame) (select-frame frame)) (if (not (file-writable-p loops-browser-file)) (error "Check your write permission on %s" loops-browser-file)) (select-frame (make-frame-command)) (set-frame-name loops-browser-name) (switch-to-buffer (create-file-buffer loops-browser-file)) (write-file loops-browser-file) (delete-file loops-browser-file)) (loops-classes "Waiting for Logo output "))) (defun loops-classes (msg) "Show Classes for inspection." (logo-send-command (concat "browse.classes " (logoize-path loops-browser-file))) (select-window (frame-first-window)) ;; I guess 60 seconds should do! This is *very* slow (with-timeout (60 (error "Logo did not write to %s file" loops-browser-file)) (while (or (not (file-readable-p loops-browser-file)) logo-busy-p) (setq msg (concat msg ".")) (with-timeout (0.01) (momentary-string-display msg (point-max) ?\ " ")) (sleep-for 1))) (unwind-protect (progn (let ((revert-without-query (cons loops-browser-name revert-without-query))) (revert-buffer t t) (setq default-tab-width 3) (loops-browse-overlay) (setq buffer-read-only t) (loops-browse-mode) (logo-debug-mode-sintax) (hide-subtree) (show-children 2) (save-buffer 0)) (delete-file loops-browser-file)))) (defun loops-class-start (class) (re-search-forward (concat "^[ \t]*to " (regexp-quote class) "\\([ \t]+\\|$\\)") nil t)) (defun loops-view-class (event) (interactive "@e") (if logo-busy-p (error "Logo is busy")) (let ((class (loops-xor-edit event))) (if class (progn (if (not (file-exists-p loops-class-file)) (progn ;; I guess 5 seconds should do! (if (not (file-writable-p loops-class-file)) (error "Check your write permission on %s" loops-class-file)) (loops-save-image-dont-ask loops-class-file) (with-timeout (5 (error "Logo did not write to %s file" loops-class-file)) (while (or (not (file-readable-p loops-class-file)) logo-busy-p) (sleep-for 0.3))) (find-file-other-window loops-class-file)) (if (get-buffer-window (file-name-nondirectory loops-class-file) nil) (switch-to-buffer-other-window (file-name-nondirectory loops-class-file)) (set-buffer (file-name-nondirectory loops-class-file)))) (loops-view-mode) (widen) (goto-char (point-min)) (if (not (loops-class-start class)) (error "Class: %s not found" class) (beginning-of-line) (logo-mark-definition) (narrow-to-region (point) (mark)) (loops-view-overlay)))))) (defun loops-save-image-dont-ask (filename) (logo-send-command (concat "save.image " (logoize-path (expand-file-name filename))))) (defun loops-xor-edit (event) "Remove previous highlighting, and highlight new name." (mouse-set-point event) (let* ((word (current-word t)) (overlay (overlays-at (point))) (category (and overlay (or (overlay-get (car overlay) 'category) (condition-case nil (overlay-get (car (cdr overlay)) 'category) (error nil)))))) (if (or (not word) (not (= (point) logo-mouse-pos)) (not category)) (message "Point to Class `name' and try again.") (loops-browser-extinguish) (logo-highlight 'highlight)) word)) (defun loops-browser-extinguish () "Turn off highlighting for category." (letrec ((extinguish (lambda (end) (while (< (point) end) (forward-word 1) (if (cdr (overlays-at (1- (point)))) (logo-highlight 'default)))))) (save-excursion (widen) (goto-char (point-min)) (extinguish (point-max))))) ;;; Class edit mode (defvar loops-edit-mode-hook nil "") (defvar loops-edit-mode nil "") (define-derived-mode loops-edit-mode logo-mode "Class-edit" "Major mode for editing LOOPS classes.\n\n{loops-edit-mode-map}" (add-hook 'loops-edit-mode-hook (lambda () (setq buffer-read-only nil) (setq revert-without-query (cons (file-name-nondirectory loops-class-file) revert-without-query))))) (defvar loops-popup-edit-map (make-sparse-keymap "Edit Class Menu")) (fset 'loops-popup-edit-menu loops-popup-edit-map) (define-key loops-popup-edit-map [send-class] '("Send Class to LOOPS" . loops-send-class)) (define-key loops-edit-mode-map [S-down-mouse-2] 'loops-popup-edit-menu) (defun loops-edit-class () (interactive) (loops-edit-mode)) (defun loops-send-class () "Send newly edited class to LOOPS." (interactive) (goto-char (point-min)) (re-search-forward "^[ \t]*to[ \t]+\\(\\w+\\)") (let ((class (buffer-substring-no-properties (match-beginning 1) (match-end 1)))) (logo-send-file t t (concat "push \".accept.method \"" class " \n" (buffer-substring-no-properties (point-min) (point-max)))))) ;;; ======================== end code ============================= (provide 'logo) ;;; logo.el ends here ucblogo-5.5/emacs/tutorial.lg0100644000161300001330000005473707327637274014250 0ustar bhdoe;; tutorial.lg -- TUTORIAL for logo-mode ;; ;; YOU SHOULD READ THE TEXT AND CARRY OUT THE ACTIONS INDICATED HEREIN ;; =================================================================== ;; ;; First I'll assume that you have a 3 button mouse, and will call the ;; buttons; mouse-1, mouse-2, and mouse-3 -- starting from left. ;; ;; Now click mouse-1 on the `Logo-start' menu (menu-bar top right), ;; and choose `Run Logo Other Frame'. (If you have already started and ;; tested ucblogo/logo-mode installation, then skip to TUTORIAL.) ;; ;; This should pop-up a new emacs frame with title *logo*, and Logo ;; should greet you in it with: ;; ;; Welcome to Berkeley Logo version 5.1 ;; ? ;; ;; If you can see this, then both Logo and emacs logo-mode, are probably ;; properly installed. Let's test one more thing. Position the cursor on ;; the line of Logo code (below) that starts with `ct repeat 120 [...' ;; and hit C-x C-e (Control-x Control-e). ct repeat 120 [setcursor list random 75 random 23 type standout cursor] ;; You should see 120 pairs of highlighted numbers appear scattered in ;; *logo* frame. If there were no beeps and error messages, you have a ;; working version of logo-mode. ;; ;; ;; T U T O R I A L ;; ;; You write logo programs in this window (frame), which I will refer to ;; as edit buffer, to distinguish it from the other window which I will ;; call logo buffer. ;; ;; Let's clean the logo buffer (from scattered numbers) first. Move the ;; focus to logo buffer (make it active), write ct (Logo command ;; CLEARTEXT), and press Enter. Depending on the focus policy of your ;; Window Manager (basically, there are two -- click-to-focus and ;; focus-follows-pointer) you may have heard a beep when you wrote the ;; first letter (c). Not to worry, this was just emacs telling you that ;; you started writing out of Logo command line. The reason is that you ;; had to click the window to give it focus, which also shifted the ;; cursor away from Logo command line. (That's why I prefer focus follows ;; pointer policy -- no clicking is necessary.) You can also return to ;; Logo command line by pressing C-l (Control-l). ;; ;; Now we can start with one graphical example: ;; Actually, you should be writing this, but I'll do it -- for now. to spiro :side :angle :step :limit if :side > :limit [stop] fd :side rt :angle spiro sum :side :step :angle :step :limit end ;; Position the cursor (cursor is not the I beam showing current mouse ;; position) somewhere on the definition of procedure spiro (above). It ;; doesn't really matter where, as long as it is between the `t' (of ;; `to') and the first empty line below 'end'. Now press C-M-x (left ;; Control-Alt-x or Control-Meta-x). This will send the definition of ;; procedure spiro to Logo, and Logo will acknowledge that by writing ;; new prompt (? ) on a new line. ;; ;;; REMARK: ;;; The key-chord C-M-x (Ctrl-Alt-x) will not always work, and as it is ;;; the most frequently used keyboard shortcut (much faster than using ;;; Send Definition from Logo-send menu), additional instructions are in ;;; order. Some window managers (KDE 2.1 for instance) use this same ;;; combination for their own purposes, and will therefore intercept this ;;; key-chord. You can still use Esc C-x combination (Esc always works in ;;; the place of Meta or Alt key), but this is much slower that C-M-x. The ;;; only way to restore the functionality of C-M-x in logo mode is to ;;; disable this key combination in the KDE Control Center. ;; ;; Then shift the focus to logo buffer and write (in logo buffer) this ;; command: spiro 1 121 2 160 ;(and press Enter -- I will not repeat this again) ;; Logo popped up a new window (black) where the turtle did it's thing. ;; ;; Then continue in logo buffer: ;; ;; setpc 4 (sets the pen color to red) ;; spiro 1 91 2 160 ;; ;; And now one important instruction -- say you would like to run spiro ;; again, but with changed inputs: ;; ;; press (still in logo buffer) M-p (left Alt-p), and the last command ;; you entered will appear (in this case `spiro 1 91 2 160'). (If you get ;; an error message instead, then you are not on the command line -- just ;; hit C-l and repeat M-p.) Then press again M-p (`setpc 4' will appear), and ;; again. Now we have the command line we want (spiro 1 121 2 160). Place ;; the cursor on `0' of `160' and change the command line into ;; spiro 1 92 1 140 ;; ;; You can hit Enter anywhere on the command line (in this case if you ;; edited the line backwards, you would end with cursor on `2'), and Logo ;; will respond by drawing a new pattern in graphics window. ;; ;; Try to retrieve the `setpc 4' command by pressing M-p repeatedly. If you ;; overshoot, you can also move back in command-line history with M-n ;; (Alt-n). When you have found it, change the 4 to 7 and hit Enter on it to ;; change the pen color back to white. ;; ;; ;; Now, you should be ready to work on your own: ;; Try to write a procedure `triangle' (that draws a triangle) in the ;; space below. (I have started it.) to triangle :side end ;; When you have completed it, send it to Logo (C-M-x), and run it ;; (from logo buffer) with -- say `triangle 120' . ;; ;; So far I have mostly explained how to send a procedure definition from ;; edit buffer to Logo. Now we are going to look at some other ;; possibilities. ;; ;; You can send from edit buffer command lines as well. Take a look at ;; those instruction lines below. cs st repeat 4 [fd 100 rt 90] ;; Place the cursor, and press C-x C-e on each one. Every time, when you ;; sent the line, Logo responded with showing another prompt in logo ;; buffer (? ), but also carrying out the instruction in graphics window. ;; Therefore instead of a triangle (from the previous example) we see a ;; square now. ;; ;; This is rather slow, so there is a faster way as well. We can send a ;; whole region to Logo. First change slightly the repeat command. Change ;; 100 into 50. Then place the cursor on the blank line above `cs' and ;; drag mouse-1 to below `repeat 4 [fd 50 rt 90]'. This will highlight ;; the region. Now press C-c r (or C-c C-r) and emacs will send the ;; marked region to Logo. Logo will react by drawing a smaller square. ;; However, note that sending commands are designed primarily to send ;; procedure definitions to Logo. Giving Logo direct instructions is ;; easier from logo buffer. ;; ;; There are several other commands for sending (communication with ;; Logo). One of more important is `C-c b' or `C-c C-b', which sends the ;; whole buffer. This is the command you would normally use when you open ;; a new source file, and want to send the contents to Logo. To check ;; all communication commands click on the `Logo-send' menu on the menu ;; bar of edit buffer. You will notice there several send commands that end ;; with `... & Go'. These are here for archaic reasons only, and will work ;; only if you started Logo with `Run Logo Other Window' or `Run Logo Same ;; window'. If you followed the instructions to start Logo in `Other Frame' ;; (which is the most convenient and safe way) than you still have to shift ;; the focus manually (with the mouse). ;; ;; Writing Logo source code in edit buffer is relatively comfortable, ;; because logo-mode recognizes Logo syntax and will automatically mark ;; (flash) delimiters `({[', and will not get confused by a single ". It ;; also knows about Logo syntax for strings `||', so delimiters inside || ;; will not be marked. It will also automatically indent Logo code ;; (according to the indenting style set forth by Brian's CSLS books). ;; ;; This indenting business can cause some confusion at first as Enter and ;; Tab keys may seem to be malfunctioning. Enter (Return) is bound to ;; newline-and-indent command, so it will insert newline (which everybody ;; expects) but will also indent the new line if the surrounding code ;; warrants that. To understand this, place the cursor at the end of the ;; line (below), after `... I hope]]' but before `)' and press Enter. (if "false [print [This will not be printed -- I hope]] ) ;; The cursor and `)' will drop one line down, but not flush ;; left. Instead cursor will be under `"' in `"false'. That is because ;; this line is now implicitly continued (all delimiters are not closed ;; as we just dropped down the closing `)' ). ;; Now (still at the same position) write this: ;; [print [This will be printed]] ;; The closing `)' should remain to the right of last `]]'. ;; ;; This looks like two lines now, but to Logo it is only one. To check ;; this -- with the cursor on any of these "two physical" lines press C-x ;; C-e. Logo will respond by printing (in logo buffer) ;; ;; This will be printed ;; ? ;; ;; If you press Tab on any of these two physical lines, nothing will ;; happen. Lines are properly indented, and there is nothing for Tab to ;; do. To show you that Tab does work, take a look at the same two lines ;; (below). (if "false [print [This will not be printed -- I hope]] [print [This will be printed]]) ;; Now press Tab on both of them (first on the top line). They will ;; indent properly. ;; ;; There are several other options available for editing. To see them, ;; click on the `Logo-edit' menu. The last three (accessed through ;; Preferences submenu), actually, have nothing to do with editing -- ;; but I had to stick them somewhere :-). `Toggle Syntax ;; Highlighting' should be self explanatory. Click on it, and this ;; text will revert to default text face -- no coloring. As syntax ;; highlighting is actually useful when working through this tutorial ;; (makes it easier to see what is tutorial text, and what is Logo ;; code), click again on `Toggle Syntax Highlighting' to restore it. ;; ;; `Toggle Novice Management' menu option takes a bit more explaining. ;; I have disabled several standard emacs commands, that I feel could cause ;; either the loss of source code, confusion, or simply frustration of ;; a novice user. Emacs has an overwhelming number of commands (heck, ;; I probably know less than 1/10), and some are freely available ;; on the menu-bar. Let's try one disabled command. Click on Files menu, ;; and choose `Kill Current Buffer' option. This window will split in two, ;; with information about invoked command showing in lower part. Read what ;; it says, and then press N . That would always be the safest course of ;; action, unless you are absolutely sure of what you're doing. If you ;; really want to execute the command press Space. And, of-course, if ;; you are not a novice emacs user, and all this annoys you -- click on ;; `Toggle Novice Management' to get rid of it. ;; ;;`Toggle Abbreviation Expansion' menu disables or enables the Logo ;; common abbreviation expansion. Current state of abbreviation ;; expansion is visible on the mode line; if it reads (Logo), expansion ;; is disabled, if it reads (Logo Abbrev) it is enabled. To see how ;; expansion works, place the cursor directly after the FD on the next ;; line of Logo code. repeat 3 [fd ] ;; Then press space, and fd will expand to forward (with the space ;; added after it. To disable expansion (just once), restore the line, ;; place the cursor after FD again, hit escape, and then space. Space ;; will be added, but no expansion will have happened. Expansion works ;; when any of the following characters is entered after the word that ;; constitutes one of Logo abbreviations: space, newline, ], ), and ;; }. If you do not want the current abbreviation expanded, all of the ;; trigger characters can be escaped (just like space). ;; ;; One of the nice features of logo-mode is that it allows ;; simultaneous editing of two or more source files. To test this ;; click on `Files' menu on the menu-bar of edit buffer, and choose ;; `Logo-mode Files>>Open Logo File...'. Emacs will pop a new frame ;; and drop it in dired (directory) mode. There you can either choose ;; an existing source file (by clicking mouse-2 on it) or use ;; `Files>>Open File...' menu to create a new source file. If you ;; create new file, do not forget to name it `some-name.lg'. Without ;; `.lg' extension, new file will not be opened in logo-mode. ;; However if you forgot (.lg extension), or you opened Logo source ;; file that neither has the extension, nor Logo mode-line as the ;; first line, use `Files>>Logo-mode Files>>Convert to Logo-mode' ;; choice from the pull-down menu. (Only files opened in fundamental ;; mode can be converted.) ;; ;; Do this now. (Click on `Files>>Logo-mode Files>>Open Logo File...' ;; and open tutor1.lg file.) ;; ;; Now (with focus on tutor1.lg buffer) send the whole buffer to Logo with ;; C-c C-b . Logo will respond with new (? ) prompt. ;; ;; Before we try to run queens or insert.sort procedures, take a close ;; look at this code. If you were going to say that it doesn't really ;; look like standard Logo, you would be right. To execute this, we ;; must load .loops extensions. Click on `LOOPS' pull-down menu in ;; *logo* buffer and choose `Language>>Ucblogo + LOOPS'. Logo will ;; respond with: ;; ;; ? ALLOWGETSET and UNBURYONEDIT disabled ;; loading LOOPS ... Lisp layer OK ... OOP layer OK ;; ? ;; ;; Just a brief explanation of what happened with this `loading LOOPS ;; ...'. We have loaded .loops initialization file which -- technically ;; speaking is not part of standard Berkeley Logo, and most users will ;; not need, nor appreciate the changes introduced with it. I insist ;; on loading it now, as it is needed to work through this part of ;; tutorial. When you start Logo next time, you do not have to load ;; it, and if you want to get rid of it completely, uncomment one line ;; in your .emacs file. (To understand fully what LOOPS does, check ;; the `LOOPS User Manual' in `Help>>Logo-Help' menu. BTW -- it stands ;; for Logo Object Oriented Programming System.) ;; ;; You can test the insert-sort program now by sending the following ;; line (below) to Logo with C-x C-e . show insert.sort [5 4 3 111 22] ;; This was running very slowly. To improve the performance, you have ;; to compile both insert.sort, and queens procedures. To do that, ;; click on `Logo' menu in logo buffer and choose ;; `Compiler>>Compile Workspace'. Logo will respond with: ;; ;; compiling insert.sort ... OK ;; compiling queens ... OK ;; compiling spiro ... nothing to do for spiro ;; compiling triangle ... nothing to do for triangle ;; compilation completed ;; ? ;; ;; Try insert-sort again. Mark the line `show insert.sort [...' ;; (above) by dragging mouse-1 over it and then yank it back (paste ;; it) by pressing mouse-2 in logo buffer (press Enter after ;; that). Of-course -- you would normally use this way (pasting) to ;; copy from other applications running on your X display. This time, ;; sort was running much faster. ;; ;; Try running `queens' program. Enter `(queens 6 "false)' in logo ;; buffer. Logo will respond with: ;; ;; position 1 [2 4 6 1 3 5] ;; position 2 [3 6 2 5 1 4] ;; position 3 [4 1 5 2 6 3] ;; position 4 [5 3 1 6 4 2] ;; ? ;; ;; If you want to run insert.sort program on a changed input list, (instead ;; of using M-p repeatedly) you can press and hold shift key, and press ;; mouse-2 button (anywhere in logo buffer). This will pop `Setcursor Menu'. ;; Drag the pointer to `List Input History' and release it on ;; `show insert.sort [5 4 3 111 22]' entry. This will copy that input ;; line to logo buffer. ;; ;; If you want to save compiled versions of insert.sort and queens, ;; click on `Logo' menu in logo buffer and choose `Compiler>>Save ;; compiled procedures ...'. Logo will ask -- `Enter file name to ;; save to: '. Input any name you wish (but end it with .lgo) and hit ;; enter. (You do not have to quote the name, but it doesn't hurt if ;; you do.) To inspect the compiled code, you can open just saved file ;; using the same procedure as before: Click on `Files>>Logo-mode ;; Files>>Open Logo File...' ;; ;; To avoid possible misunderstandings about compiling Logo code, you ;; should realize two facts: One -- you can compile only procedures ;; that use LOOPS extensions (LETREC, COND, and CASE), and two -- ;; compiled code is just a standard Logo source code, that runs at the ;; same speed as if it were hand written in standard Logo. ;; ;; If you don't need LOOPS extensions any more, you can restore ;; standard ucblogo by clicking on `LOOPS' menu and choosing ;; `Language>>Standard Ucblogo'. Logo will respond with: ;; ;; ? Standard Berkeley Logo restored. ;; ? ;; ;; With standard language restored, you can't run insert.sort any ;; more. If you try, Logo will respond with an error message. If by ;; any chance you want to work with LOOPS extensions most of the time, ;; you can change the language again to `ucblogo + LOOPS' and click ;; on `LOOPS>>Language>>Set Startup Default' menu. This will force emacs ;; to load LOOPS extensions every time you start Logo. Of-course you ;; can `Set Startup Default' to Standard Ucblogo the same way. ;; ;; ;; HELP system: ;; ;; With focus in the second edit buffer (tutor1.lg), click with ;; mouse-3 on the Logo command `foreach' (second line in the procedure ;; `queens'). The tutor1.lg buffer will disappear and help file for ;; `foreach' will show instead. To return to tutor1.lg buffer press ;; `q' in help buffer. If you want to see all procedures that ucblogo ;; has help for, click on `Help' menu in edit buffer, and choose ;; Logo-help>>Help Contents. This buffer will disappear and ;; HELPCONTENTS file will open. There, you can click on any name to ;; show help for that procedure. To return here press `q' in ;; HELPCONTENTS buffer. ;; ;; If you want to read ucblogo user manual (in TeX-info format), click on ;; `Help' menu and choose Logo-help>>User Manual. You move through ;; user-manual by clicking mouse-2 on links (words that change color when ;; mouse pointer is over them). To exit user-manual, press `q'. ;; ;; Another form of help are completion facilities. Focus tutor1.lg ;; buffer, move to the end of the file and write letters `ins' . Then ;; (with the cursor just after s) hit M-/ (Alt-/ or ESC /). Letters ;; `ins' will expand to insert. Hit M-/ again, and completion will ;; change to insert.sort, hit again ... Emacs will find all possible ;; completions for word `ins' that exist in tutor1.lg and tutorial.lg ;; buffers. If there are many completions, a faster way of choosing is ;; by hitting C-M-/ (Ctrl-Alt-/ or ESC Ctrl-/) after the word ;; `ins'. Emacs will open a window with all completions listed. Click ;; mouse-2, on the one you want, and letters `ins' will expand to the ;; chosen word. In our current situation (with tutorial.lg buffer ;; present) emacs will find a lot of useless completion words like ;; installation, insist, but that is only because tutorial.lg buffer ;; consists mostly of English text, and not of Logo code. In a real ;; logo source buffer, you will mostly get previously defined names of ;; procedures and variables, which is what you probably want. ;; ;; The second form of completion facilities is completion for Logo ;; defined keywords (names of primitive and library procedures). Again ;; in tutor1.lg buffer, clear any previous completions of `ins' , and ;; write letters `set' (with the cursor just after t) hit ESC TAB . Emacs ;; will open a window with the listing of all possible keyword ;; completions. Click with mouse-2 on the one you want, and `set' will ;; expand to that keyword. ;; ;; Interactive TRACE STEP and ERASE (choosing) ;; In logo buffer click on `Logo' menu and choose Logo-debug>>Trace... ;; You will get a buffer with three regions: ;; ;; PROCEDURES: ;; ;; insert.sort queens spiro triangle ;; ;; VARIABLES: ;; ;; ;; PROPERTIES: ;; ;; ;; Here we have four defined procedures (insert.sort ... spiro ;; triangle). If we click on any one of them, we will mark that ;; procedure for tracing. Mouse-1 chooses the pointed procedure, ;; deselects everything else. Mouse-2 toggles selection for pointed ;; procedure. Mouse-3 chooses the pointed procedure, sends all ;; selected procedures to Logo, and exits debug buffer. To quit debug ;; mode, you can also press `q'. This also sends selected procedures ;; to Logo. All mouse actions are confirmed by highlighting relevant ;; procedure names. If you open debug buffer again, all procedures ;; that were selected (for tracing or stepping) before, will be ;; highlighted (and placed in parentheses). ;; ;; Try this now. Click on `Logo>>Logo-debug>>Erase...' menu. Read the ;; mode-line of this buffer. It should say: (Fundamental Logo-ERASE ;; View). This is just to make sure that you don't choose procedures ;; for tracing or stepping, while you're actually erasing them. Click ;; mouse-1 on the word `triangle'. Triangle should now be ;; highlighted. (Don't drag the mouse while clicking!) Press `q' and ;; you're back in logo buffer. Now try to run triangle; press shift ;; mouse-2 (to invoke `List Input History' menu), choose `triangle ;; 120', and hit Enter. Logo should respond with: ;; ;; I don't know how to triangle ;; ? ;; ;; =========================================== ;; ;; For detailed instructions on how to use logo-mode, read the README ;; file in /usr/local/lib/logo/emacs/ directory. ;; ;; To end this tutorial (or any future logo-mode sessions) click on ;; `Files' menu and choose `Exit Emacs' option. Emacs will ask if you ;; want to save file (meaning the source file you were working on -- ;; right now, this file) to which you normally answer `Yes'. Then it will ;; ask; `Active processes exist; kill them and exit anyway?', to which ;; you click on `Yes'. (This is actually asking if you want to kill ;; Logo.) ;; ;; DO NOT - EVER - try to kill Logo by clicking on X in the top right ;; corner of logo buffer window (if your window manager has that X). This ;; will kill logo frame, but *not* Logo itself, and you will loose ;; the communication channel with it. You will not be able to use ;; `Logo-start' menu on edit buffer, because as far as logo-mode is ;; concerned Logo is still running, and two Logo processes are not ;; allowed. You can, however, type `bye' on the Logo command line to kill ;; it. In that case you can also restart it from `Logo-start' menu. ;; ;; If you started this tutorial from a "real" Logo source file, and ;; you want to return to that file and continue working on it -- then ;; instead of `Exit Emacs', use `Files>>Kill Current Buffer' ;; option. Tutorial buffer will disappear, and the file you have been ;; working on before will show again. bye ;-) ucblogo-5.5/emacs/README0100644000161300001330000005703307327625602012721 0ustar bhdoeThis file documents version 2.9 of logo.el. Logo.el is written for GNU Emacs 20.5 or newer, running under X11. You will (of-course) need Berkeley Logo (*v5.1* or newer) installed on your system. It is *not* designed to be used with Xemacs, Gnu Emacs compiled without X support or Gnu Emacs started with -nw option. The last two will partly work, but I did not test it that way. ============ INSTALLATION ============ Installing the Berkeley Logo package installs Logo-mode also. See the README file in the main ucblogo directory. EACH USER who wants to use Logo-mode must run the shell command install-logo-mode ------------------------------------------------ Description of options for fine-tuning: Set this to change the size of the frame (window) for Logo-inferior-process buffer. If these forms are not present, the size is set to 80x24. (This will work properly only with ucblogo 5.1 or newer.) (setq logo-term-columns nn) (setq logo-term-rows mm) Where nn and mm is whatever makes you happy. By default logo-mode will indent continued lines in logo (edit) buffer when RET-urn key is pressed. To insert a newline without indenting use LFD (C-j) key. To reverse this behavior (reverse should probably be considered "normal" behavior), add this form. (setq logo-standard-indent t) By default logo-mode starts with syntax highlighting enabled. If you do not want it, set this: (setq logo-syntax-highlight nil) If you feel that the default syntax highlighting is slowing your system too much, set this: (setq logo-lazy-lock-mode t) By default logo-mode starts with novice command management enabled. If you don't want it set this: (setq logo-novice-management nil) By default logo-mode will start Logo process in setcursor mode. To change this permanently set: (setq logo-setcursor-start nil) Default text input mode in setcursor mode is set to overwrite. To change this permanently set: (setq logo-setcursor-overwrite nil) By default, the old text, after recalling the previous input in setcursor mode will be cleared to the end of the line. If that gets in your way, set this: (setq logo-setcursor-spaces-old n) where n is from 0 to any number. However, spaces are never pushed beyond end of the line. By default two spaces are pushed ahead of end of the new input in setcursor mode. If that gets in your way, set this: (setq logo-setcursor-spaces-new n) where n is from 0 to any number. However, spaces are never pushed beyond end of the line. If emacs lags behind during indenting Logo procedures, or simply when hitting return key (you must be working on a *very* slow system to notice this last one), add this form. (setq logo-unbalanced-distance 4096) On a very slow machine go down to 2048. By default, this is set to 8192, but it is doubtful that you will ever write a single implicitly continued logo line that will be 8K long. If you have installed ucblogo info files translated into another language, then set this: (setq logo-info-file-trans "/your-info-path/file-name.info") However, for this to work - somebody has to write translation first. To the best of my knowledge only Croatian translation exists. Therefore by default this is set to "/usr/local/info/ucbl-hr.info" . If you change this to another language you must also update the `Help' menu entry by setting this: (setq logo-info-trans "(De)") This "(De)" would be in case your translation is German, but you can use longer words as well. By default this is set to "(Hr)". If you don't care for this at all, set (setq logo-info-trans nil) With this set menu entry for translated manual will disappear. By default emacs enables changes to Logo language through Logo>>Language, and Logo>>Compiler menus. This has to do with .loops initialization file. If you do not want to use this facility, set this: (setq logo-load-language nil) Logo mode automatically sets the depth of setcursor input history menu to safe value for the display resolution it is running on. (20 entries for 640x480, 25 for 800x600 ...) To change this set following: (setq logo-dynamic-menu-depth n) where n is any number (up to ... 48). However note that if you use larger number, (depending on your display resolution, and emacs font size) you may not be able to see nor use all menu entries. If you don't want me messing with your default emacs colors, then set this line: (setq dont-mess-with-logo-colors t) If you don't want parens matching on cursor movement, then set this line: (setq logo-flash-on-movement nil) If you want to change the delay after matching parentheses on cursor movement, set this to any number of seconds you wish: (setq logo-matching-delay-time seconds) Default delay is set to 2 seconds, but even a very long delay -- say, 5 seconds would be OK, as you don't have to wait for it to complete. Delay will be reset if you move the cursor again. By default logo-mode starts with automatic expansion of common Logo abbreviations enabled, If you do not want this, set: (setq logo-expand-common-abbrevs nil) For those that are translating Logo primitive names into another language, (I know that the translation into French is underway), add this form to enable the expansion of new primitives: (define-abbrev-table 'logo-mode-abbrev-table '(("op" "output") ("pr" "print") ... ...)) of course, using your new names instead of those used here. 4. There are several other options settable in .emacs file, but they deal mostly with problem corrections. If I have done my work properly, and if you have installed ucblogo (release 5.1 or newer) as instructed in ucblogo README file, they will not be necessary. Read logo.el file (first five pages) for the description of other options. (For instance if Emacs can't find Logo help files, debug menu doesn't work etc. ...) ======================================== USING BERKELEY LOGO WITH EMACS LOGO MODE ======================================== To start logo mode, open one Logo source file in emacs. As far as emacs is concerned Logo source file is the file that ends with .lg , .lgo , or a file that has this `;;; -*- logo -*-' on a first line. Start ucblogo from a `Logo-start' menu. You can start Logo in `Other Frame',or `Same Window'. The *BEST* way is `Other Frame', and I definitely suggest using it. (The `Same Window' is given for archaic reasons only.) Due to availability of setcursor mode I insist on a minimum window (frame) size when Logo starts -- 81x26 (that is if the usable size is left at 80x24). Do not change frame size of Inferior Logo buffer (by dragging corners with the mouse), or Logo output will be garbled. On the other hand - stretching the height of Logo edit frame is perfectly OK. Editing and sending Logo source code: ===================================== You write Logo code in Logo edit buffer. All standard emacs editing features are supported here. The notable difference from standard behavior is automatic indenting bound to RET (enter) key. You can check special Logo editing features by pulling down `Logo-edit' menu. All functions that are bound to a key sequence will show that sequence as well. To see commands for sending source code (or parts of it) to Logo, pull down `Logo-send' menu. Choices that are shaded (in all of these menus) denote that this option is presently not available. For instance if `Send Region' is shaded it simply means that no region has been selected. You can have several source files opened, but only one Logo process buffer. That is the reason for all three choices on `Logo-start' menu being shaded after you have started Logo. Syntax highlighting is turned on by default (unless you have disabled it in .emacs file). However you can always turn it off/on with `Toggle Syntax Highlighting' choice in `Logo-edit' pull-down menu. Following syntax classes are highlighted: Comments - (red) text. Strings - (brown) text. Start and end of Logo procedure definition (TO .MACRO DEFINE .DEFMACRO END) - (blue) text. Variables (actually :var.name) - (light blue) text. Highlighting of beginning and end of Logo definitions is not so dependable as functions that mark procedure boundaries (used for code indenting and sending). TO, .MACRO, and END will not be highlighted if they are indented. For `adventurous' novices (meaning mostly Emacs novices) I have included novice command management feature. This simply tags potentially dangerous commands, and they are not executed immediately. Instead, emacs will pop a window with warning, and basic instructions what to do next. You can still execute the command if you decide so. If you find this disturbing (I do) then turn it off with Logo-edit>>Preferences>>Toggle Novice Management choice from menu-bar, or set it permanently in .emacs file. Interacting with Logo: ====================== To run and test your procedures switch to Inferior Logo buffer. If you have started Logo in `Same Window', to switch -- you have to use `C-c l'. Otherwise simply move the mouse pointer to Logo buffer. The usual goodies from Scheme (or Lisp modes) are present in Logo mode as well. You can step with `M-p' / `M-n' (C-up / C-down, should also work, if not trapped by your Window Manager) through the previous inputs to Logo in all modes, and edit these inputs as you wish. When finished with editing (input) simply hit Return key wherever you are in the input line. Emacs will correctly grab the whole input and send it to Logo. You can use S-down-mouse-2 (shift and press mouse-2) anywhere on the Inferior Logo window to pop-up the `List Input History' menu. Release mouse on any of the entries, and that input will be inserted on command line. Several standard editing keys work "slightly" different in Inferior Logo mode. Delete and Backspace keys work only within current command (input) line. Kill and yank (paste) commands work only on input line, by killing or yanking the whole input. Do not bother aiming with the mouse accurately. No matter where you are in Inferior Logo buffer, mouse-2 will paste new input line, overwriting the old line. The old input is cleared, so don't try pasting two inputs hoping they will concatenate. You can not tell emacs where is the end of input line, by positioning the point there. That is chosen automatically. (Actually this is not entirely true -- if emacs ever gets hopelessly confused about the position of logo-input-marker, you can set it manually with `C-@'.) The whole purpose for this yanking (pasting) business is to transfer input lines from other applications running on your X display, therefore X-selection always takes precedence over emacs kill-ring. (To retrieve previous inputs from your current Logo/logo-mode session use `M-p' instead.) Probably the *most useful* key to remember in Inferior Logo mode is `C-l'. This is not bound to `recenter' as in the rest of logo-mode buffers, but to `logo-find-input-end' which takes you back to the end of Logo command line (in case you had wondered off). To stop a "runaway" Logo hit `C-c C-c' in Inferior Logo buffer. If this doesn't work use one of the choices from from `Signals' pull-down menu in Inferior buffer. `BREAK' (`C-c C-c') to which Logo should respond with "Stopping..." `QUIT' to which Logo should respond with "Pausing..." `KILL' to which emacs responds with "Process logo killed" Signals menu is not part of logo.el, so there are no Logo specific choices there - it is built into comint mode. You do not have to worry (as you should if using Logo without logo-mode) about saving your source files before you test any of them. Even if Logo crashes in Inferior Logo buffer (with a message like ... segmentation fault ...), your sources are still intact in Logo edit buffer. Simply restart Logo with `Logo-start' menu, and re-send your procedures to it with any of the choices on `Logo-send' pull-down menu. Workspace Management: ===================== To choose procedures for tracing or stepping, use `Logo-debug' sub-menu under `Logo' pull-down menu in Inferior Logo buffer. Debug buffer lists all names currently defined, and lets you select procedures (variables or properties) for tracing or stepping. Mouse bindings are as in XFM. Mouse-1 selects only the pointed name (de-selects everything else), mouse-2 toggles the selection for the name, mouse-3 selects pointed name, quits debug-buffer and sends all selected names to Logo. `q' key also quits debug-buffer and sends all selected names to Logo. When you open `Trace...' or `Step...' menus, the names that were traced or stepped before will be highlighted (and placed in parentheses). The last entry under `Logo>>Logo-debug' menu is `Erase'. You can mark (with the same mechanism as for tracing); procedures, variables or plists for erasing. After `q' key is pressed, marked names will be erased from Logo workspace, and GC will run automatically. To check which is the buffer you're actually working with (trace, step or erase), as all three look alike -- read the buffer mode line. For erase buffer it will state: `(Fundamental Logo-ERASE View)' etc. Help system: ============ Logo-mode has a very simple help system. Help works in source buffers. Press mouse-3 on any valid Logo name, and the help file (for that procedure) will open. To exit hit `q'. If the help for the procedure doesn't exist, HELPCONTENTS file will be opened. There you can choose as many help files as you want (with mouse-3). Hit `q' in HELPCONTENTS to return to the source file. If you want to check HELPCONTENTS, either click mouse-3 on a word which is not defined in Logo, or use `Logo-help' sub-menu on emacs `Help' pull-down menu. This option is available only on Logo edit frame menu bar. To get better organized and more comprehensive help, browse through Logo User Manual by pulling down the `Help' menu and choosing from `Logo-help' sub-menu, `User Manual'. That will work if you have installed ucblogo.info files (normally installed automatically). To exit from Logo User Manual buffer hit `q'. To get help for logo-mode itself hit `C-h m' in any of emacs logo mode buffers. Although completion facilities are not part of the help system, you can regard them as such. Two types of completion are available in logo edit buffers. Completion for Logo keywords (actually standardly defined names of Logo primitive and library procedures) and completion for words that were already used in any of opened logo edit buffers. To perform completion for Logo keywords write a few starting letters and hit ESC TAB. This will open a window with a list of all possible Logo keyword completions. Click mouse-2 on the one you want, and your keyword will be completed in edit buffer. To perform completion on a word that is not standardly defined Logo name (this works both in edit and Logo process buffers), write a few letters, and hit M-/ (Alt-/). If possible, emacs will complete the word with the word you have used before in this, or any other Logo buffer currently opened. If there are more possible completions, cycle through them by repeatedly pressing M-/, until you find the one you want. The other way to accomplish the same result is to hit C-M-/ (Ctrl-Alt-/) and emacs will open a window with all available completions listed. Click mouse-2 on the one you want. Logo common abbreviations are expanded when one of these characters is entered after the word that constitutes abbreviation: space, newline, ], }, and ). To disable this in the current session click on Logo-Edit>>Preferences>>Toggle Abbreviation Expansion. You can reactivate expansion using the same menu. Current state of abbreviation expansion is visible on the mode line; if it reads (Logo), expansion is disabled, if it reads (Logo Abbrev) it is enabled. If you want to disable the expansion only on the current word, escape the character that triggers the expansion. E.g.: if you do not want to expand OP to OUTPUT after hitting space key, press escape key, and then the space key. The expansion will not occur this time, but next time you hit space after the abbreviation, the expansion will be carried out. Obvious *NOT To DOs* when running Logo in Logo mode: ==================================================== Entering `edit "whatever' in Inferior Logo buffer defeats the purpose of using Logo mode. Whatever you edit this way will be lost (unless you save it manually). You will not be able to use logo-mode editing features this way, even if your EDITOR environment variable is set to emacs. This will also block Logo -- no interaction from other logo-mode buffers will be possible. Entering `load "whatever' in Inferior Logo buffer is not the right way to do it. Use `Open Logo File...' choice from `Files>>Logo-mode Files' pull-down menu in Logo edit buffer. Emacs will pop-up a new frame (that is, if you started Logo with `Run Logo Other Frame') and drop it in a `Dired' mode, with default directory (the directory where the first source file resides) displayed. Then choose (mouse-2) the desired file. This way you can see both source files at the same time. To send this file to Logo, simply hit `C-c b'. If you opened Logo source file that neither has the `.lg' extension, nor Logo mode-line as the first line, use `Files>>Logo-mode Files>>Convert to Logo-mode' choice from the pull-down menu. (Only files opened in fundamental mode can be converted.) If you started Logo with `Run Logo Same Window' choice, you can still have several source files opened. Switch between them with `C-c l' key using prefix. (If you have three files opened `C-u 1 C-c l' switches from Inferior Logo buffer to the newest source buffer, and `C-u 3 C-c l' switches to the oldest buffer -- or just use emacs `Buffers' menu to switch.) There is no need to use help, trace or step Logo commands manually. They can't hurt, but logo-mode provides interactive, mouse driven interface, which is easier to use. Do not define Logo procedures by typing them directly to Logo in Inferior Logo buffer. This will work OK, but you will not be able to change them later on. `M-p' will retrieve them line by line, and not as a whole definition. Instead, simply enter definitions in Logo edit buffer and send them over with `C-M-x'. The key-chord C-M-x (Ctrl-Alt-x) will not always work, and as it is the most frequently used keyboard shortcut (much faster than using Send Definition from Logo-send menu), additional instructions are in order. Some window managers (KDE 2.1 for instance) use this same combination for their own purposes, and will therefore intercept this key-chord. You can still use Esc C-x combination (Esc always works in the place of Meta or Alt key), but this is much slower that C-M-x. The only way to restore the functionality of C-M-x in logo mode is to disable this key combination in the KDE Control Center. If you have been using SETCURSOR command in Inferior Logo mode, and Inferior Logo buffer is cluttered with old text, do *not* try to clear the buffer using emacs. Instead, use Logo to do the job -- enter `ct' (CLEARTEXT) command on Logo input line. Not so obvious *NOT To DOs*: ============================ Do not leave blank lines (spaces only) inside Logo string constants. Indenting and procedure sending functions in logo-mode depend on this. If you really need a blank line in Logo string, you can use this: make "foo "|abc || def| instead of this: make "foo "|abc def| As far as Logo is concerned, result is the same. Logo-mode, however will malfunction on the second. Although you can leave blank lines and comment lines (comments only) inside procedure definitions in Logo edit buffer, their use is restricted to areas between lines that are not continued, or are implicitly continued (Lisp style). Do not use blank lines between explicitly continued Logo lines (lines that end with `~'). Neither Logo, nor logo-mode function properly in these circumstances. You can use comment only lines between two explicitly continued Logo lines, but you must end them with `~'. However, you are on your own here -- in some cases Logo will reject those. This is what I was talking about: to worldtree ;; comment make "world ~ tree "world ~ (list ;; comment (tree "France leaves [Paris Dijon Avignon]) ;; comment (tree "China leaves [Beijing Shanghai Guangzhou Suzhou]) ... This works OK. However if you try to insert a comment line between make "world ~ tree "world ~ lines, Logo will print error message when worldtree is run. Do not use names like `x\;y' `x\(y' `x| |y' `x|;|y' `x\\y' or some such for your procedures and variables. Although Logo will accept this, you will not be able to mark these names in Workspace Management (Debug) buffer. I have allowed some rather weird characters to accommodate Brian's MATCH program, but that's as far as I'll go. Do not use yank (paste) facility to paste procedure definitions directly to Inferior Logo buffer -- this will not work. Yank can be used only to paste the command line (input) directly to Logo. This probably sounds ambiguous, therefore one small example: Let's say that you have in another editor window (it can be another copy of emacs, or whatever) this procedure: to remove1 :e :l op filter [[x] [op or not equalp :e :x memberp :x ?rest]] :l end and you want to test it in current Logo/logo-mode session. If you yank it directly to Inferior Logo buffer, it will arrive as one line (setcursor mode), and Logo will not accept this as a procedure definition. Instead, yank it to Logo edit buffer, and use `C-M-x' to send it to Logo. On the other hand (once Logo has received the procedure definition), you can use yank to paste from other editor test inputs to procedure remove1. For instance, you can yank: `show remove1 2 [1 2 3 1 2 3 1 2 3]' directly to Inferior Logo buffer and hit return. Logo should respond by printing following: ? show remove1 2 [1 2 3 1 2 3 1 2 3] [1 2 3 1 2 3 1 3] ? This is an oversimplified example, but, there will be times (when testing tree recursive procedures -- for instance) where the test input will be several lines long elaborately constructed tree list... Do *not* try to close Logo by clicking on X in the upper right corner of *logo* frame (or by using close option on the upper left corner of the *logo* frame). This will close that frame, and make Logo unaccessible to you, but it will *not* kill Logo. If you want to kill Logo, type `bye' in *logo* buffer. Not so obvious *To DOs*: ======================== One of the facilities built into logo-mode is automatic loading of .loops initialization file from your home directory - if it exists. The idea here is not so much to write additions to Logo library (although it can be used for that as well), but to alter the standard behavior of Logo interpreter. The last version (v.0.9) adds LOOPS, a rudimentary Logo Object Oriented Programming System (just an experiment). As an example of what can be done with initialization file, copy the included .loops (dot.loops) file to your home directory, and start Logo. Click on `LOOPS>>Language>>Ucblogo + LOOPS' menu, and emacs will load .loops extensions into Logo. The Compiler sub-menu on Logo pull-down menu in Inferior Logo buffer is LOOPS specific. To understand what it does, and -- indeed, how to use LOOPS extensions click on `Help>>Logo-help>>LOOPS User Manual'. *(Part of the LOOPS User Manual needs updating.)* =============================== COMMENTS BUG REPORTS AND To-DOs =============================== Logo-mode is tested only on Intel machines running Linux and FreeBSD. I have no access to anything else. The original work started on emacs 19.34.1(b), but that version is no longer supported. Logo-mode v2.9 will work only with emacs 20.5 and newer. Your safest bet is to upgrade to the latest version. Right now I have a lot "To-DO", but am willing to listen to "reasonable" suggestions. For more information, comments, or bug reports, send e-mail to ucblogo-5.5/emacs/letrec.el0100644000161300001330000000603407270062710013624 0ustar bhdoe;;; letrec.el ;; Copyright (C) 2001 by Hrvoje Blazevic (hrvoje.blazevic@ri.tel.hr) ;; Logo.el is free software distributed under the terms ;; of the GNU General Public License, version 2, or (at your option) ;; any later version. ;; Logo.el 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. ;;; Commentary: ;; This file defines extensions to emacs lisp: ;; filter, letrec ... ;; We need to increase `funcall' depth for recursive calls here. (or (> max-lisp-eval-depth 1200) (setq max-lisp-eval-depth 1200)) (or (> max-specpdl-size 3600) (setq max-specpdl-size 3600)) (eval-and-compile (defun letrec-transformer (proc-text) "Insert `funcall' before all local function calls." (if (null proc-text) nil (if (consp (car proc-text)) (cond ((memq (caar proc-text) p-names) (cons (cons 'funcall (letrec-transformer (car proc-text))) (letrec-transformer (cdr proc-text)))) ((and (eq (caar proc-text) 'quote) (not (functionp (car (cdar proc-text))))) (cons (car proc-text) (letrec-transformer (cdr proc-text)))) (t (cons (letrec-transformer (car proc-text)) (letrec-transformer (cdr proc-text))))) (cons (car proc-text) (letrec-transformer (cdr proc-text))))))) (defmacro letrec (procs &rest body-forms) "Defining local functions in e-lisp -- similar to Scheme letrec. Uses `let' syntax. First argument, PROCS is a list of name to lambda bindings. Binding names to value expressions is supported -- however, see the note below. Scope in letrec is true Scheme letrec scope -- local functions defined this way can be both -- recursive, and mutually recursive. Note: Just like in Scheme, you can not have the variable and the local function of the same name. If you use the local function as an argument to a functional like `mapcar', you must *not* quote the local function name. (defun letrec-test (num-list) (letrec ((add100 (lambda (x) (+ x 100)))) (mapcar add100 num-list))) Unlike Scheme, a value binding can refer to lexically previously defined bindings in its value expression -- ergo; scope in this case behaves like `let*' scope." (let* ((p-names (mapcar (lambda (x) (if (functionp (cadr x)) (car x) '(x))) procs)) (funcall-procs (mapcar (lambda (p) (list (car p) (letrec-transformer (cadr p)))) procs))) `(let ,(mapcar (lambda (x) (list (car x))) procs) ,@(mapcar (lambda (x) `(setq ,(car x) ,(if (functionp (cadr x)) `(function ,(cadr x)) `(identity ,(cadr x))))) funcall-procs) ,@(letrec-transformer body-forms)))) (defun filter (pred lst) "Returns a filtered list of all elements of list LST, for which the predicate PRED returned t." (letrec ((f (lambda (lst) (if (null lst) nil (if (funcall pred (car lst)) (cons (car lst) (f (cdr lst))) (f (cdr lst))))))) (f lst))) (provide 'letrec) ;; letrec.el ends here ucblogo-5.5/emacs/dot.LOOPS0100644000161300001330000006325407270062710013437 0ustar bhdoe;;; -*- logo -*- ;;; ;;; LOOPS -- ucbLogo Object Oriented Programming System -- ;;; ;;; ... a pretentious name for a short Berkeley Logo initializing file ;;; that makes it feasible to apply principles described in Scheme and ;;; the Art of Programming. ;;;; LOOPS ;;; object compiler to object.maker [:&args&] local [&proc& proc.&text &static& var.&list var.&tmp val.&list &lambda& &optional& formal.&names &locals& init.&static &formals& &method& &binding& &class&] make "&class& first :&args& make "&args& bf :&args& make "proc.&text text :&class& ;; parsing class optional formal parameters & binding arguments ;; most of this is done by Logo parser -- the only intervention is: ;; extracting formal names and stripping default input numbers, ;; which make no sense in this context make "formal.&names filter [[&x] [op not.tf numberp :&x]] map [ [&x] [(if.tf listp :&x [op first :&x] [op :&x])]] first :proc.&text local :formal.&names define "&optional& fput first :proc.&text [[op map "thing :formal.&names]] (foreach apply "&optional& :&args& :formal.&names [[&a &f] [make :&f :&a]]) er (list "&optional&) ;; inheritance if.tf equalp first first bf :proc.&text "inherit.from [ run lput quoted :&class& first bf :proc.&text make "proc.&text bf :proc.&text] ;; temporary -- compile time bindings make "proc.&text bf :proc.&text make "&binding& first :proc.&text (while [not (or [equalp first :&binding& "static] [equalp first :&binding& "lambda] [emptyp bf :proc.&text])] [run :&binding& make "proc.&text bf :proc.&text make "&binding& first :proc.&text]) ;; setting up static storage make "var.&list [] make "&static& first :proc.&text ;; checking for top-level object if.tf not namep "unq.&object.name [ local [unq.&object.name method.&stack export.&stack] make "unq.&object.name gensym make "method.&stack [] make "export.&stack []] make "&proc& (word :unq.&object.name ". gensym ". :&class&) er lput (list :&proc&) [[] []] bury lput (list :&proc&) [[] []] (while [equalp first :&static& "static] [;; get names make "var.&tmp firsts last :&static& ;; get values & push method name if keyword "method.export found make "val.&list (map [ [&x &y] [if.tf equalp first first :&x "method.export [push "method.&stack :&y]] [op begin :&x]] bfs last :&static& :var.&tmp) ;; bind name-value pairs (foreach :var.&tmp :val.&list [[&r &l] [pprop :&proc& :&r :&l]]) make "var.&list se :var.&list :var.&tmp ;; making bindings visible in next STATIC line during compile ;; time -- that's why all these &&&... local :var.&tmp (foreach :var.&tmp :val.&list [[&r &l] [make :&r :&l]]) ;; try next static line make "proc.&text bf :proc.&text make "&static& first :proc.&text]) ;; mandatory LAMBDA line make "&lambda& first :proc.&text if not (and [equalp first :&lambda& "lambda] [equalp first last :&lambda& ":]) [ (pr [ERROR: Missing or incorrect LAMBDA line in:] :&class&) pr :&lambda& pr [it should look like this:] pr [lambda :messagename] throw "toplevel] ;; building object make "&locals& list "local :var.&list make "init.&static map.se [ [&var] [op (list "make word "" :&var "gprop word "" :&proc& word "" :&var)] ] :var.&list ;; stripping column from message name make "&formals& (list bf last :&lambda&) ;; compiling methods make "&method& (reduce [[x y] [op (word :x ". :y)]] lput "&method bl split.word :&class& ".) if.tf or memberp :&class& :.accept.method [not definedp :&method&] [ define :&method& compile.object fput [] insert.method bf :proc.&text bury :&method& make ".accept.method remove :&class& :.accept.method] ;; compiling object op compile.object (fput :&formals& fput :&locals& fput :init.&static (list (list "op char 40 ".and (list ".maybeoutput :&method&) char 41 ))) end ;;; auxiliary procedures ;; exporting methods from subclass .macro method.export :class.list :method.text foreach :class.list [[&x] [push "export.&stack :&x]] op (list insert.invoke :method.text) end ;; checking method before compilation to insert.method :text if.tf emptyp :method.&stack [op :text] if.tf not.tf memberp :&class& :export.&stack [op :text] if.tf not.tf listp :text [op :text] op insert.invoke :text end to delegate :object :msg if.tf definedp :object [op invoke :object :msg] op invoke thing :object :msg end ;; unsafe send -- for uniform syntax 'send "objectname ...' to send [:msg.list] 2 op send.helper first :msg.list end to send.helper :send.object if.tf listp :send.object ~ [op apply :send.object (list (fput :send.object bf :msg.list))] if.tf definedp :send.object ~ [op apply :send.object (list (fput :send.object bf :msg.list))] op send.helper thing :send.object end ;; indirect addressing -- all storage classes should understand ;; message indirect to indirect [:message] 2 op apply "send (fput send first :message "indirect bf :message) end ;; used in DO messages -- gets the value of the object to #self op send "self "self end ;; pacifying Logo 5beta to static :ignore end ;; pacifying Logo 5beta to lambda pr [ERROR: You probably tried to execute 'somename.class' procedure] pr [USAGE: define "objectname (object.maker "somename.class [initexp ...])] pr [| |: then send messages ... (send "objectname "somemessage ...)] throw "toplevel end ;; defining top-level object -- need the object name to new :object.name :definition define :object.name :definition push "loops.object.stack :object.name end make "loops.object.stack [] ;; Emacs IDE procedures to inspect.methods.objects :file_elisp_code local [o.prop] localmake "wr_elisp_code writer localmake "printwidthlimit 2048 localmake "printdepthlimit 16 openwrite :file_elisp_code setwrite :file_elisp_code pr "COMPILED-METHODS: pr [] pr filter [equalp "&method last split.word ? ".] first buried pr [] pr "TOP-LEVEL-OBJECTS: pr [] make "loops.object.stack filter [not memberp ? ?rest] :loops.object.stack pr (se "base.object "loops :loops.object.stack) pr [] pr "VIRTUAL-OBJECTS: pr [] make "o.prop filter [make "o.prop split.word ? ". (and equalp first first :o.prop "g [numberp last first :o.prop] [equalp last :o.prop "class])] last buried if not emptyp :o.prop [foreach objects.group :o.prop [pr ? pr []]] close :file_elisp_code setwrite :wr_elisp_code end to objects.group :lst if.tf emptyp bf :lst [op (list :lst)] local [first result] make "first first :lst make "result objects.group bf :lst if.tf (equalp (first split.word :first ".) (first split.word first bf :lst ".)) ~ [op fput fput :first first :result bf :result] op fput (list :first) :result end to show.method.object :method :file_elisp_code [:pretty "false] 3 localmake "wr_elisp_code writer localmake "printwidthlimit 2048 localmake "printdepthlimit 64 openwrite :file_elisp_code setwrite :file_elisp_code ifelse.tf definedp :method [ foreach fulltext :method [pr ?]] [ ;localmake "virtual.o plist :method local "virtual.o make "virtual.o plist :method ifelse.tf :pretty [ localmake "template [[x y] [show (list "localmake word "\" :x quoted :y)]]] [ localmake "template [[x y] [show list :x :y]]] (foreach filter [oddp count ?rest] :virtual.o filter [evenp count ?rest] :virtual.o :template)] close :file_elisp_code setwrite :wr_elisp_code end ; to show.method.object :method :file_elisp_code [:pretty "false] 3 ; localmake "wr_elisp_code writer ; localmake "printwidthlimit 2048 ; localmake "printdepthlimit 64 ; openwrite :file_elisp_code ; setwrite :file_elisp_code ; ifelse.tf definedp :method [ ; foreach fulltext :method [pr ?]] [ ; ;localmake "virtual.o plist :method ; local "virtual.o ; make "virtual.o plist :method ; ifelse.tf :pretty [ ; localmake "template ; [[x y] [show (list "localmake word "\" :x quoted :y)]]] [ ; localmake "template [[x y] [show list :x :y]]] ; (foreach filter [oddp count ?rest] :virtual.o ; filter [evenp count ?rest] :virtual.o ; :template)] ; close :file_elisp_code ; setwrite :wr_elisp_code ; end to browse.classes :file_elisp_code localmake "wr_elisp_code writer localmake "printwidthlimit 2048 localmake "printdepthlimit 16 openwrite :file_elisp_code setwrite :file_elisp_code (foreach filter [evenp count ?rest] plist "inherit.list filter [oddp count ?rest] plist "inherit.list [[from to] [pprop "inheritance.tree "inherit insert.tree :from :to gprop "inheritance.tree "inherit]]) inherit gprop "inheritance.tree "inherit " erase [[] [] [inherit.list]] close :file_elisp_code setwrite :wr_elisp_code end to inherit :tree :level if.tf emptyp :tree [stop] if.tf wordp :tree [(pr :level :tree) stop] inherit first :tree word :level char 9 inherit bf :tree :level end to inherit.from :from :to pprop "inherit.list :to :from end to insert.tree :from :to :tree if.tf or emptyp :tree [wordp :tree] [op :tree] if.tf and equalp :from first :tree [not.tf memberp :to apply "se bf :tree] [ op fput :from fput (list :to) bf :tree] op fput insert.tree :from :to first :tree insert.tree :from :to bf :tree end to edit.classes :class :file_elisp_code localmake "wr_elisp_code writer localmake "printwidthlimit 2048 localmake "printdepthlimit 64 openwrite :file_elisp_code setwrite :file_elisp_code if.tf definedp :class [ foreach fulltext :class [pr ?]] close :file_elisp_code setwrite :wr_elisp_code end to save.image [ :filename& .and [type "|Enter file name (without extension) to save to: |] [rw]] 1 bury (list [] (list "filename& "startup "printdepthlimit "printwidthlimit "bury.list) []) ;; Structures will print to 2048 elements. This is a sefeguard for circular ;; list objects. localmake "printwidthlimit 2048 localmake "printdepthlimit 1024 make "bury.list buried make "startup [ bury :bury.list (type "|Image: | last split.word :filename& "/ "| loaded.| )] if equalp first :filename& "" [make "filename& bf :filename&] if equalp last split.word :filename& ". "lgimg [ make "filename& apply "word bl split.word :filename& ".] savel (map "se contents buried) word :filename& ".lgimg end ;; Redefining method procedure? make ".accept.method [] bury [[static.make object.maker delegate send send.helper base.object new static lambda insert.method.h insert.method method.export indirect #self inspect.methods.objects objects.group show.method.object edit.classes save.image browse.classes loops inherit inherit.from insert.tree] [.accept.method loops.object.stack] [inherit.list]] ;;; base classes ;; Base object -- source commented out, only compiled code loaded ; to base.object :message ; local [object msg] ; make "object first :message ; make "msg bf :message ; op letrec [[ ; [get.sym [[txt] ; [condc [ ; [[emptyp :txt] [op "#unspecified]] ; [[equalp first :txt "gprop] ; [op first split.word bf first bf :txt ".]] ; [else [op (get.sym bf :txt)]]]]]]] ; [case [ ; [first :msg] ; [[type] [op "base.object]] ; [[erase.object] ; [localmake "symbol ; (get.sym apply "se bf bf text :object)] ; [localmake "statics filter ; [[x] [op equalp :symbol first split.word :x ".]] ; last buried] ; [er lput :statics [[] []]] ; [if not equalp :object "base.object [er (list :object)]] ; [make "loops.object.stack remove :object :loops.object.stack] ; [gc op nodes]] ; [[error] ; [(apply "pr combine "ERROR:\ bf :msg)] ; [throw "toplevel]] ; [else [(pr "ERROR: :msg "not "understood "by "object: :object)] ; [throw "toplevel]]]]] ; end ; to loops :message ; case [ ; [first bf :message] ; [[new global] ; [define first bf bf :message apply "object.maker bf bf bf :message] ; [push "loops.object.stack first bf bf :message] ; [op first bf bf :message]] ; [[virtual local] [op apply "object.maker bf bf :message]] ; [[erase.methods] ; [erase filter [equalp last split.word ? ". "&method] first buried] ; [gc op nodes]] ; [else [op delegate "base.object :message]]] ; end ;; All classes requiring static storage (which is just about all), ;; should use (dotted)pair.class as the only link to static variables. to pair.class :xinit [:yinit []] local "cons.cell make "cons.cell (list :xinit) .setbf :cons.cell :yinit static [[pair.o :cons.cell]] lambda :msg op case [ [first bf :msg] [[get getx self indirect] [first :pair.o]] [[set setx make] [.setfirst :pair.o first bf bf :msg first :pair.o]] [[gety] [bf :pair.o]] [[sety] [.setbf :pair.o first bf bf :msg bf :pair.o]] [[raw] [:pair.o]] [[p2l] [list first :pair.o bf :pair.o]] [[type] ["dotted.pair.object]] [else [delegate "base.object :msg]]] end ;; swap.pair based on pair.class to swap.pair.class :xinit [:yinit []] static [[pair.o [(send "loops "virtual "pair.class :xinit :yinit)]]] lambda :msg local "tmp op case [ [first bf :msg] [[swap] [make "tmp send "pair.o "gety] [ignore (send "pair.o "sety send "pair.o "get)] [(send "pair.o "set :tmp)]] [[type] ["swap.pair.object]] [else [delegate "pair.o :msg]]] end ;; border.class is used to create terminal objects, that can stop execution, ;; and extract results by sending messages to other objects to border.class :text [:objects []] [:msgs []] static [[text.o [(send "loops "virtual "pair.class :text)]] [objmsg.pairs [(send "loops "virtual "pair.class :objects :msgs)]]] lambda :message local [self msg] make "self first :message make "msg bf :message case [ [first :msg] [[exit.outer] [op "false]] [[erase.object] [op delegate "base.object :msg]] [else [ ;; output text and all results of terminal object msg calls ;; use 'self to send msg 'exit.outer to border.class object -- as a ;; flag to break out of the outer loop (see queens8.class) op se send "text.o "get ~ (map [[x y] [op apply "send se :x :y]] send "objmsg.pairs "get send "objmsg.pairs "gety)]]] end ;; simple counter to counter.class :init if not numberp :init [(send "base.object "error [Input must be a number!])] static [[init.val :init] [pair.o [(send "loops "virtual "pair.class :init)]]] lambda :msg op case [ [first bf :msg] [[inc] [(send "pair.o "set sum (send "pair.o "get) 1)]] [[dec] [(send "pair.o "set (send "pair.o "get) - 1)]] [[reset] [(send "pair.o "set :init.val)]] [[type] ["counter.object]] [else [delegate "pair.o :msg]]] end ;; circular counter init -> limit , init -> limit ... to rewinding.counter.class :init :limit if not numberp :limit [(send "base.object "error [Input must be a number!])] static [[init.val :init] [rewind :limit] [counter.o [(send "loops "virtual "counter.class :init)]]] lambda :msg case [ [first bf :msg] [[inc] [op ifelse (send "counter.o "get) < :rewind [(send "counter.o "inc)] [(send "counter.o "reset)]]] [[type] [op "rewinding.counter.object]] [[dec] [op delegate "base.object :msg]] [else [op delegate "counter.o :msg]]] end ;; container word/list to container.class :init static [[container.o [(send "loops "virtual "pair.class :init)]]] lambda :message local [msg self] make "msg bf :message make "self first :message op case [ [first :msg] [[bf butfirst] [ignore (send "container.o "sety first send "container.o "get)] [(send "container.o "set bf send "container.o "get)]] [[bl butlast] [ignore (send "container.o "sety last send "container.o "get)] [(send "container.o "set bl send "container.o "get)]] [[first last count pick empty? emptyp] [invoke :#target send "container.o "get]] [[word se sentence] [(send "self "do! fput word "\( :#target lput "\) first bf :msg)]] [[do] [run first bf :msg]] [[do!] [(send "self "set (send "self "do first bf :msg))]] [[item member? memberp member] [(invoke :#target first bf :msg send "container.o "get)]] [[listp list? wordp word?] [(invoke :#target send "container.o "self)]] [[flush] [(send "container.o "set ifelse listp send "container.o "get [[]] ["])]] [[type] ["container.object]] [else [delegate "container.o :message]]] end ;; word class to word.class [:init "] if not wordp :init [ (send "base.object "error [Input must be a word!])] static [[word.o [(send "loops "virtual "container.class :init)]]] lambda :msg op case [ [first bf :msg] [[type] ["word.object]] [else [delegate "word.o :msg]]] end ;; list class to list.class [:init []] if not listp :init [ (send "base.object "error [Input must be a list!])] static [[list.o [(send "loops "virtual "container.class :init)]]] lambda :msg op case [ [first bf :msg] [[fput lput] [(send "list.o "set (invoke :#target first bf bf :msg send "list.o "self))]] [[type] ["list.object]] [else [delegate "list.o :msg]]] end ;; FILO structure based on list class to stack.class static [[holder.o [(send "loops "virtual "list.class)]]] lambda :msg op case [ [first bf :msg] [[push] [(send "holder.o "fput first bf bf :msg)]] [[pop] [ifelse.tf send "holder.o "empty? [(send "holder.o "error [Stack is empty])] [ignore send "holder.o "bf send "holder.o "gety]]] [[top] [ifelse.tf send "holder.o "empty? [(send "holder.o "error [Stack is empty])] [send "holder.o "first]]] [[size] [send "holder.o "count]] [[type] ["stack.object]] [else [delegate "holder.o :msg]]] end ;; double ended list class to double.end.class [:init []] if not listp :init [(send "base.object "error [Input must be a list!])] static [[cell.o [ (send "loops "virtual "pair.class :init ifelse emptyp :init [:init] [last.pair :init])]]] lambda :message local [msg self tmp] make "msg bf :message make "self first :message case [ [first :msg] [[lput] [make "tmp (list first bf :msg)] [ifelse.tf emptyp send "cell.o "get [ignore (send "cell.o "set :tmp)] [.setbf (send "cell.o "gety) :tmp]] [op (send "cell.o "sety :tmp)]] [[first indirect] [op first send "cell.o "get]] [[bf butfirst] [op (send "cell.o "set bf send "cell.o "get)]] [[last] [op first send "cell.o "gety]] [[empty? emptyp] [op emptyp send "cell.o "get]] [[fput] [if.tf emptyp send "cell.o "get [op (send "self "lput first bf :msg)]] [make "tmp (list first bf :msg)] [.setbf :tmp send "cell.o "get] [op (send "cell.o "set :tmp)]] [[import] [ignore (send "cell.o "sety last.pair fput "x first bf :msg)] [op (send "cell.o "set first bf :msg)]] [[bl butlast] [op (send "self "import bl send "cell.o "get)]] [[count] [op count send "cell.o "get]] [[flush] [op (send "self "import [])]] [[member? memberp] [op memberp first bf :msg send "cell.o "get]] [[member] [op member first bf :msg send "cell.o "get]] [[shift.left] [make "tmp first send "cell.o "get] [ignore send "self "bf] [ignore (send "self "lput :tmp)] [op send "cell.o "get]] [[shift.right] [make "tmp first send "cell.o "gety] [ignore send "self "bl] [op (send "self "fput :tmp)]] [[export self] [op map "identity send "cell.o "get]] [[type] [op "double.ended.list.object]] [else [op delegate "cell.o :message]]] end ;; queue based on double ended class to queue.class static [[del.o [(send "loops "virtual "double.end.class)]]] lambda :message local [tmp msg self] make "msg bf :message make "self first :message case [ [first :msg] [[enqueue] [op first (send "del.o "lput first bf :msg)]] [[dequeue] [make "tmp send "self "front] [ignore send "del.o "bf] [op :tmp]] [[front] [if.tf send "del.o "empty? [(send "del.o "error [queue is empty])]] [op send "del.o "first]] [[type] [op "queue.object]] [[lput fput bf butfirst bl butlast first last shift.left shift.right] [op delegate "base.object :message]] [else [op delegate "del.o :message]]] end ;; circular list storage to circular.class static [[pointer [[mark]]]] static [[start.o [localmake "cl (list :pointer) .setbf :cl :cl] [(send "loops "virtual "pair.class :cl)]]] static [[end.o [(send "loops "virtual "pair.class (send "start.o "get))]]] lambda :message local [tmp msg self] make "msg bf :message make "self first :message op letrec [[ [open [[] [.setbf (send "end.o "get) []] [op (send "start.o "get)]]] [close [[] [.setbf (send "end.o "get) (send "start.o "get)] [op (send "start.o "get)]]] [bl.pair [[clst] [if.tf .eq first bf bf :clst :pointer [op :clst]] [op (bl.pair bf :clst)]]]] [case [ [first :msg] [[lput] [make "tmp (send "end.o "get)] [.setbf :tmp (list first bf :msg)] [.setbf bf :tmp (send "start.o "get)] [op bf (send "end.o "set bf :tmp)]] [[fput] [make "tmp bf (send "start.o "get)] [.setbf (send "start.o "get) (list first bf :msg)] [.setbf bf (send "start.o "get) :tmp] [if.tf .eq first (send "end.o "get) :pointer [ ignore (send "end.o "set bf (send "start.o "get))]] [op (send "start.o "get)]] [[bf butfirst] [.setfirst (send "start.o "set bf (send "start.o "get)) :pointer] [make "tmp (send "start.o "get)] [.setbf (send "end.o "get) :tmp] [op :tmp]] [[bl butlast] [make "tmp (send "start.o "get)] [.setbf (send "end.o "set (bl.pair bf :tmp)) :tmp] [op :tmp]] [[first indirect] [op first bf (send "start.o "get)]] [[last] [op first (send "end.o "get)]] [[empty? emptyp] [op .eq first bf (send "start.o "get) :pointer]] [[count] [make "tmp count bf (open)] [ignore (close)] [op :tmp]] [[export] [make "tmp map "identity bf (open)] [ignore (close)] [op :tmp]] [[import] [make "tmp (send "start.o "set fput :pointer first bf :msg)] [.setbf (send "end.o "set last.pair :tmp) :tmp] [op (send "self "export)]] [[flush] [op (send "self "import [])]] [[memberp member?] [make "tmp memberp first bf :msg bf (open)] [ignore (close)] [op :tmp]] [[member] [op member first bf :msg (send "self "export)]] [[rotate] [make "tmp first bf (send "start.o "get)] [.setfirst bf (send "start.o "get) :pointer] [.setfirst (send "start.o "get) :tmp] [ignore (send "end.o "set (send "start.o "get))] [op (send "start.o "set bf (send "start.o "get))]] [[type] [op "circular.list.object]] [[set] [op delegate "base.object :message]] [else [op delegate "start.o :message]]]]] end ;; Inheritance tree pprop "inheritance.tree "inherit [pair.class [swap.pair.class] [counter.class [rewinding.counter.class]] [container.class [word.class] [list.class [stack.class]]] [double.end.class [queue.class]] [border.class] [circular.class]] bury [[counter.class rewinding.counter.class queue.class container.class list.class word.class stack.class circular.class pair.class swap.pair.class double.end.class border.class] [] [inheritance.tree]] ;;; compiled code to base.object :message local [object msg] make "object first :message make "msg bf :message op run [local "get.sym make "get.sym [[txt] [run [if.tf emptyp :txt [op "#unspecified] if.tf equalp first :txt "gprop [op first split.word bf first bf :txt ".] op ( invoke :get.sym bf :txt )]]] local "dummy.letrec make "dummy.letrec [[] [run [local "#target make "#target run [first :msg] ifelse.tf memberp :#target [type] [op "base.object] [ifelse.tf memberp :#target [erase.object] [localmake "symbol ( invoke :get.sym apply "se bf bf text :object ) localmake "statics filter [[x] [op equalp :symbol first split.word :x ".]] last buried er lput :statics [[] []] if not equalp :object "base.object [er ( list :object )] make "loops.object.stack remove :object :loops.object.stack gc op nodes] [ifelse.tf memberp :#target [error] [( apply "pr combine "ERROR\:\ bf :msg ) throw "toplevel] [( pr "ERROR: :msg "not "understood "by "object: :object ) throw "toplevel]]]]]] run [( invoke :dummy.letrec )]] end to loops :message run [local "#target make "#target run [first bf :message] ifelse.tf memberp :#target [new global] [define first bf bf :message apply "object.maker bf bf bf :message push "loops.object.stack first bf bf :message op first bf bf :message] [ifelse.tf memberp :#target [virtual local] [op apply "object.maker bf bf :message] [ifelse.tf memberp :#target [erase.methods] [erase filter [equalp last split.word ? ". "&method] first buried gc op nodes] [op delegate "base.object :message]]]] end bury [[base.object loops loops.compiler] [] []] pr "| OOP layer OK| ;;; End of .LOOPS ucblogo-5.5/emacs/dot.logo0100644000161300001330000004161107326342542013502 0ustar bhdoe;;; -*- logo -*- ;;; ;;; .logo -- Logo initialization file (v.0.9.0) Hrvoje Blazevic ;;; ;; Reversing 5.1 changes ;; Don't like getter/setter syntax "simplification". .LOOPS is ;; slow even without ALLOWGETSET. UNBURYONEDIT is meaningless ;; in logo-mode, and can possibly get in the way. make "state.allowgetset :allowgetset make "state.unburyonedit :unburyonedit bury [[] [state.allowgetset state.unburyonedit] []] erase [[] [allowgetset unburyonedit] []] pr [ALLOWGETSET and UNBURYONEDIT disabled] type "|loading LOOPS ... | wait 0 ;; Allowing changes to Logo primitives make "redefp "true ;; Preserving original definitions copydef "if.tf "if copydef "ifelse.tf "ifelse copydef "not.tf "not copydef "and.tf "and copydef "or.tf "or copydef "test.tf "test ;; Freeing names erase [if ifelse not and or test] ;;; New definitions .macro if :tf.val :run.true [:run.false []] 2 op (if.tf equalp :tf.val "false [:run.false] [:run.true]) end .macro ifelse :tf.val :run.true :run.false op (if.tf equalp :tf.val "false [:run.false] [:run.true]) end to not :thing.not op (if.tf equalp :thing.not "false ["true] ["false]) end to true op "true end to false op "false end copydef "else "true copydef "t "true to and [:form.and ["true]] [:forms.and] 2 if.tf emptyp :forms.and [op run :form.and] if run :form.and [op apply "and :forms.and] op "false end to or [:form.or ["false]] [:forms.or] 2 if.tf emptyp :forms.or [op run :form.or] cond.if run :form.or op apply "or :forms.or end .macro cond.if :#cond.val if :#cond.val [op list "op :#cond.val] op [] end to .and [:form.and ["true]] [:forms.and] 2 if.tf emptyp :forms.and [op first lput "#unspecified runresult :form.and] if.tf not first lput "#unspecified runresult :form.and [op "false] op apply ".and :forms.and end .macro test :any.value op (list "test.tf "not.tf "not quoted :any.value) end ;;; Extended prefix operators copydef "difference.s "difference copydef "quotient.s "quotient erase [difference quotient equal? greater? less? before?] to difference :first.num [:rest.nums] 2 if.tf emptyp :rest.nums [op minus :first.num] op :first.num - (apply "sum :rest.nums) end to quotient :first.num [:rest.nums] 2 if.tf emptyp :rest.nums [op (1 / :first.num)] op :first.num / (apply "product :rest.nums) end to equal? :elt [:rest] 2 op emptyp find [not.tf equalp ? :elt] :rest end to less? :elt [:nums] 2 if.tf emptyp :nums [op "true] if.tf :elt < first :nums [op apply "less? :nums] op "false end to greater? :elt [:nums] 2 if.tf emptyp :nums [op "true] if.tf greaterp :elt first :nums [op apply "greater? :nums] op "false end to before? :wd [:wds] 2 if.tf emptyp :wds [op "true] if.tf beforep :wd first :wds [op apply "before? :wds] op "false end to lesseq? :elt [:nums] 2 if.tf emptyp :nums [op "true] if.tf :elt > first :nums [op "false] op apply "lesseq? :nums end to greatereq? :elt [:nums] 2 if.tf emptyp :nums [op "true] if.tf lessp :elt first :nums [op "false] op apply "greatereq? :nums end to beforeq? :wd [:wds] 2 if.tf emptyp :wds [op "true] if.tf beforep first :wds :wd [op "false] op apply "beforeq? :wds end ;;; Cleaning up ;; Prohibit further changes of primitives ern "redefp bury [if ifelse not true false else or and .and test cond.if] bury [difference equal? greater? less? greatereq? lesseq? beforeq? quotient before? difference.s quotient.s] ;;; Defining High Level Structures ;;; Letrec .macro letrec :in.letrec local [body.letrec method.&stack] make "method.&stack [] make "body.letrec fput "dummy.letrec (list fput [] bf :in.letrec) op insert.invoke letrec.helper lput :body.letrec first :in.letrec end to letrec.helper :clauses.letrec if.tf emptyp :clauses.letrec [op (list "run [(dummy.letrec)])] push "method.&stack first first :clauses.letrec op (se "local (word "" first :method.&stack) "make (word "" first :method.&stack) bf first :clauses.letrec letrec.helper bf :clauses.letrec) end to insert.invoke :text if.tf emptyp :text [op []] if.tf wordp first :text [ op (or [(and [equalp first :text "\(] [memberp first bf :text :method.&stack] [(se first :text "invoke word ": first bf :text insert.invoke bf bf :text)])] [se first :text insert.invoke bf :text])] op (if.tf listp first :text [fput insert.invoke runparse first :text insert.invoke bf :text] [fput first :text insert.invoke bf :text]) end ;;; Cond -- 2 versions ;; universal -- operation and command .macro cond.ifelse :#cond.val :#cond.rest op ifelse :#cond.val [(list :#cond.val)] [:#cond.rest] end .macro cond :cond.clauses local [fclauses lclause] make "lclause last :cond.clauses (if.tf and [wordp first :lclause] [memberp first :lclause [else true t]] [make "lclause apply "se bf :lclause make "fclauses bl :cond.clauses] [make "fclauses :cond.clauses make "lclause ["#unspecified]]) op cond.helper :fclauses end to cond.helper :cond.clauses if.tf emptyp :cond.clauses [op :lclause] if.tf emptyp bf first :cond.clauses [ op (se "cond.ifelse first first :cond.clauses (list cond.helper bf :cond.clauses))] op (se "ifelse.tf first first :cond.clauses (list apply "se bf first :cond.clauses) (list cond.helper bf :cond.clauses)) end ;; command only -- slightly faster .macro condc :cond.clauses local [fclauses lclause] make "lclause last :cond.clauses (if.tf and [wordp first :lclause] [memberp first :lclause [else true t]] [make "lclause apply "se bf :lclause make "fclauses bl :cond.clauses] [make "fclauses :cond.clauses make "lclause ["#unspecified]]) op condc.helper :fclauses end to condc.helper :cond.clauses if.tf emptyp :cond.clauses [op :lclause] if.tf emptyp bf first :cond.clauses [ op (se "cond.if first first :cond.clauses condc.helper bf :cond.clauses)] op (se "if.tf first first :cond.clauses (list apply "se bf first :cond.clauses) condc.helper bf :cond.clauses) end ;;; Case ;; universal -- operation and command, but *must* output a value .macro case :case.clauses local [fclauses lclause] make "lclause last :case.clauses (if.tf and [wordp first :lclause] [memberp first :lclause [else true t]] [make "lclause apply "se bf :lclause make "fclauses bl bf :case.clauses] [make "fclauses bf :case.clauses make "lclause ["#unspecified]]) op (se (list "local ""#target "make ""#target "run first :case.clauses) case.helper :fclauses) end to case.helper :first.clauses if.tf emptyp :first.clauses [op :lclause] op (se "ifelse.tf "memberp ":#target (list first first :first.clauses) (list apply "se bf first :first.clauses) (list case.helper bf :first.clauses)) end ;;; casec ;; command only -- mix code, true forms do not have to output .macro casec :case.clauses local [fclauses lclause] make "lclause last :case.clauses (if.tf and [wordp first :lclause] [memberp first :lclause [else true t]] [make "lclause apply "se lput [op "#unspecified] bf :lclause make "fclauses bl bf :case.clauses] [make "fclauses bf :case.clauses make "lclause [op "#unspecified]]) op (se (list "local ""#target "make ""#target "run first :case.clauses) casec.helper :fclauses) end to casec.helper :first.clauses if.tf emptyp :first.clauses [op :lclause] op (se "ifelse.tf "memberp ":#target (list first first :first.clauses) (list apply "se lput [op "#unspecified] bf first :first.clauses) (list casec.helper bf :first.clauses)) end ;;; Compiler -- source is commented out. Only the compiled code gets loaded. ; to loops.compiler [:proc procedures] 1 ; letrec [[ ; [compile.proc [[proc] ; [if emptyp :proc [op []]] ; [local "struct.min] ; [op ifelse.tf ; (and [wordp first :proc] ; [macrop first :proc] ; [not gprop "compiler.cap first :proc] ; [not.tf emptyp bf :proc] ; [listp first bf :proc]) ; [make "compiled "true ; se (list "run macroexpand list first :proc ; (compile.proc first bf :proc)) ; (compile.proc bf bf :proc)] ; [or [and [listp first :proc] ; [fput (compile.proc first :proc) ; (compile.proc bf :proc)]] ; [fput first :proc (compile.proc bf :proc)]]]]] ; [compile.ws [[proc.lst compiled] ; [if.tf emptyp :proc.lst [stop]] ; [.type (se "compiling first :proc.lst "|... |)] ; [wait 0] ; [(invoke (or [and [macrop first :proc.lst] ; [".defmacro]] ; ["define]) ; first :proc.lst (compile.proc text first :proc.lst))] ; [.pr (if.tf :compiled ; [.and [pprop "compiled.procs first :proc.lst "true] ; ["OK]] ; [(se [nothing to do for] first :proc.lst)])] ; [(compile.ws bf :proc.lst "false)]]]] ; [ifelse listp :proc [(compile.ws filter "procedurep :proc "false)] ; [(compile.ws filter "procedurep (list :proc) "false)]] ; [.pr [compilation completed]]] ; end ;;; Invoking the compiler from logo-mode with Compile Workspace ;; ;; Using ws.compile instead of loops.compiler ;; Filtering out all procedure names that end with .class ;; Compiling Class templates, firstly makes no sense, secondly, ;; will make Class unusable to the OBJECT.MAKER ;; ;;; ws.compile to ws.compile local "split (loops.compiler filter [[x] [make "split split.word :x ". op not (and [1 < count :split] [equalp last :split "class])]] procedures) end to compile.object :text if.tf emptyp :text [op []] if.tf (and [wordp first :text] [macrop first :text] [not gprop "compiler.cap first :text] [not.tf emptyp bf :text] [listp first bf :text]) ~ [op se (list "run macroexpand list first :text compile.object first bf :text) compile.object bf bf :text] if.tf listp first :text ~ [op fput compile.object first :text compile.object bf :text] op fput first :text compile.object bf :text end to .type :text if.tf :.verbose [type :text] end to .pr :text if.tf :.verbose [pr :text] end ;; specifying compiler output make ".verbose "true ;; Saving *only* compiled procedures. to save.compiled [:filename .and [type "|Enter file name to save to: |] [rw]] 1 if.tf namep "printwidthlimit ~ [localmake "width :printwidthlimit ern "printwidthlimit] if.tf namep "printdepthlimit ~ [localmake "depth :printdepthlimit ern "printdepthlimit] if equalp first :filename "" [make "filename bf :filename] local "oldwriter make "oldwriter writer openwrite :filename setwrite :filename po (filter [[proc] [op not.tf emptyp gprop "compiled.procs :proc]] procedures) setwrite :oldwriter close :filename if.tf namep "width [make "printwidthlimit :width] if.tf namep "depth [make "printdepthlimit :depth] end ;;; Compiler Capabilities ;;; ;;; Capabilities have this format: property = name of High Level Procedure ;;; value = "false ;;; ;;; You can add your own compiler capabilities, providing you follow ;;; these rules: High level procedure (structure) you define must have ;;; one input only - a list. And, of-course it must be a macro -- ;;; otherwise there is nothing for compiler to do. After you have ;;; defined (and tested) your procedure add your pprop line to lines ;;; below. That is all. pprop "compiler.cap "letrec "false pprop "compiler.cap "cond "false pprop "compiler.cap "condc "false pprop "compiler.cap "case "false pprop "compiler.cap "casec "false bury [[insert.invoke letrec letrec.helper cond cond.helper loops.compiler compile.object save.compiled case .pr case.helper casec casec.helper .type ws.compile condc condc.helper cond.ifelse] [.verbose] [compiler.cap compiled.procs]] ;;; End of interpreter changes (.logo) ;;; Additions to Logo library to before :first.wd [:rest.wds] 2 if emptyp :rest.wds [op :first.wd] if beforep first :rest.wds :first.wd [op apply "before :rest.wds] op apply "before fput :first.wd bf :rest.wds end to max :first [:rest] 2 if emptyp :rest [op :first] if greaterp :first first :rest [op apply "max fput :first bf :rest] op apply "max :rest end to min :first [:rest] 2 if emptyp :rest [op :first] if lessp :first first :rest [op apply "min fput :first bf :rest] op apply "min :rest end to evenp :number op zerop remainder :number 2 end copydef "even? "evenp to oddp :number op not evenp :number end copydef "odd? "oddp to zerop :number op equalp :number 0 end copydef "zero? "zerop to identity :stuff op :stuff end to last.pair :lst if emptyp bf :lst [op :lst] op last.pair bf :lst end to split.word :string [:delimiter "\ ] 2 local "result if emptyp :string [op (list ")] make "result split.word bf :string :delimiter if equalp first :string :delimiter [op fput " :result] op fput word first :string first :result bf :result end to time :instruction.list localmake "start first first shell [date "+%s"] pr runresult :instruction.list (pr "Elapsed "time: (first first shell [date "+%s"]) - :start "seconds) end .macro begin :begin.forms op apply "se :begin.forms end bury [before max min evenp even? oddp odd? zerop zero? identity last.pair split.word time begin] ;;; Restoring Standard Berkeley Logo ;;; This is of practical value only if used within Emacs logo-mode to restore.standard make "redefp "true copydef "if "if.tf copydef "ifelse "ifelse.tf copydef "not "not.tf copydef "and "and.tf copydef "or "or.tf copydef "test "test.tf copydef "difference "difference.s copydef "quotient "quotient.s copydef "equal? "equalp copydef "greater? "greaterp copydef "less? "lessp copydef "before? "beforep ;; .logo make "allowgetset :state.allowgetset make "unburyonedit :state.unburyonedit bury [[] [allowgetset unburyonedit] []] erase [ [if.tf ifelse.tf not.tf and.tf or.tf test.tf false else t true .and insert.invoke letrec letrec.helper cond cond.helper cond.if cond.ifelse condc condc.helper loops.compiler ws.compile save.compiled case case.helper difference.s quotient.s lesseq? greatereq? beforeq? .type .pr casec casec.helper begin] [.verbose state.allowgetset state.unburyonedit] [compiler.cap compiled.procs]] ;; loops erase [ [object.maker static.make compile.object bucket.class base.object counter.class send rewinding.counter.class container.class stack.class delegate #self border.class browse.classes circular.class double.end.class edit.classes indirect inherit inherit.from insert.method insert.tree inspect.methods.objects lambda list.class loops new objects.group pair.class queue.class save.image send.helper show.method.object static swap.pair.class word.class] [.accept.method loops.object.stack] [inheritance.tree]] ern "redefp gc ignore nodes gc ignore nodes gc pr [Standard Berkeley Logo restored.] end bury [restore.standard loops.compiler] ;;; Compiled code to loops.compiler [:proc procedures] 1 run [local "compile.proc make "compile.proc [[proc] [if emptyp :proc [op []]] [local "struct.min] [op ifelse.tf ( and [wordp first :proc] [macrop first :proc] [not gprop "compiler.cap first :proc] [not.tf emptyp bf :proc] [listp first bf :proc] ) [make "compiled "true se ( list "run macroexpand list first :proc ( invoke :compile.proc first bf :proc ) ) ( invoke :compile.proc bf bf :proc )] [or [and [listp first :proc] [fput ( invoke :compile.proc first :proc ) ( invoke :compile.proc bf :proc )]] [fput first :proc ( invoke :compile.proc bf :proc )]]]] local "compile.ws make "compile.ws [[proc.lst compiled] [if.tf emptyp :proc.lst [stop]] [.type ( se "compiling first :proc.lst "|... | )] [wait 0] [( invoke ( or [and [macrop first :proc.lst] [".defmacro]] ["define] ) first :proc.lst ( invoke :compile.proc text first :proc.lst ) )] [.pr ( if.tf :compiled [.and [pprop "compiled.procs first :proc.lst "true] ["OK]] [( se [nothing to do for] first :proc.lst )] )] [( invoke :compile.ws bf :proc.lst "false )]] local "dummy.letrec make "dummy.letrec [[] [ifelse listp :proc [( invoke :compile.ws filter "procedurep :proc "false )] [( invoke :compile.ws filter "procedurep ( list :proc ) "false )]] [.pr [compilation completed]]] run [( invoke :dummy.letrec )]] end type [Lisp layer OK ...] ;;; End of .logo ucblogo-5.5/emacs/comint-logo.el0100644000161300001330000031500007326444636014606 0ustar bhdoe;;; comint-logo.el --- general command interpreter in a window stuff ;; Copyright (C) 1988, 90, 92, 93, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc. ;; Author: Olin Shivers then ;; Simon Marshall ;; Maintainer: FSF ;; Keywords: processes ;; This file is part of GNU Emacs. ;; GNU Emacs 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 Emacs 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 Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; Please send me bug reports, bug fixes, and extensions, so that I can ;; merge them into the master source. ;; - Olin Shivers (shivers@cs.cmu.edu) ;; - Simon Marshall (simon@gnu.ai.mit.edu) ;; This file defines a general command-interpreter-in-a-buffer package ;; (comint mode). The idea is that you can build specific process-in-a-buffer ;; modes on top of comint mode -- e.g., lisp, shell, scheme, T, soar, .... ;; This way, all these specific packages share a common base functionality, ;; and a common set of bindings, which makes them easier to use (and ;; saves code, implementation time, etc., etc.). ;; Several packages are already defined using comint mode: ;; - shell.el defines a shell-in-a-buffer mode. ;; - cmulisp.el defines a simple lisp-in-a-buffer mode. ;; ;; - The file cmuscheme.el defines a scheme-in-a-buffer mode. ;; - The file tea.el tunes scheme and inferior-scheme modes for T. ;; - The file soar.el tunes lisp and inferior-lisp modes for Soar. ;; - cmutex.el defines tex and latex modes that invoke tex, latex, bibtex, ;; previewers, and printers from within emacs. ;; - background.el allows csh-like job control inside emacs. ;; It is pretty easy to make new derived modes for other processes. ;; For documentation on the functionality provided by comint mode, and ;; the hooks available for customising it, see the comments below. ;; For further information on the standard derived modes (shell, ;; inferior-lisp, inferior-scheme, ...), see the relevant source files. ;; For hints on converting existing process modes (e.g., tex-mode, ;; background, dbx, gdb, kermit, prolog, telnet) to use comint-mode ;; instead of shell-mode, see the notes at the end of this file. ;; Brief Command Documentation: ;;============================================================================ ;; Comint Mode Commands: (common to all derived modes, like shell & cmulisp ;; mode) ;; ;; m-p comint-previous-input Cycle backwards in input history ;; m-n comint-next-input Cycle forwards ;; m-r comint-previous-matching-input Previous input matching a regexp ;; m-s comint-next-matching-input Next input that matches ;; m-c-l comint-show-output Show last batch of process output ;; return comint-send-input ;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff ;; c-c c-a comint-bol-or-process-mark First time, move point to bol; ;; second time, move to process-mark. ;; c-c c-u comint-kill-input ^u ;; c-c c-w backward-kill-word ^w ;; c-c c-c comint-interrupt-subjob ^c ;; c-c c-z comint-stop-subjob ^z ;; c-c c-\ comint-quit-subjob ^\ ;; c-c c-o comint-kill-output Delete last batch of process output ;; c-c c-r comint-show-output Show last batch of process output ;; c-c c-l comint-dynamic-list-input-ring List input history ;; ;; Not bound by default in comint-mode (some are in shell mode) ;; comint-run Run a program under comint-mode ;; send-invisible Read a line w/o echo, and send to proc ;; comint-dynamic-complete-filename Complete filename at point. ;; comint-dynamic-complete-variable Complete variable name at point. ;; comint-dynamic-list-filename-completions List completions in help buffer. ;; comint-replace-by-expanded-filename Expand and complete filename at point; ;; replace with expanded/completed name. ;; comint-replace-by-expanded-history Expand history at point; ;; replace with expanded name. ;; comint-magic-space Expand history and add (a) space(s). ;; comint-kill-subjob No mercy. ;; comint-show-maximum-output Show as much output as possible. ;; comint-continue-subjob Send CONT signal to buffer's process ;; group. Useful if you accidentally ;; suspend your process (with C-c C-z). ;; comint-get-next-from-history Fetch successive input history lines ;; comint-accumulate Combine lines to send them together ;; as input. ;; comint-goto-process-mark Move point to where process-mark is. ;; comint-set-process-mark Set process-mark to point. ;; comint-mode-hook is the comint mode hook. Basically for your keybindings. ;;; Code: (require 'ring) ;; Buffer Local Variables: ;;============================================================================ ;; Comint mode buffer local variables: ;; comint-prompt-regexp string comint-bol uses to match prompt ;; comint-delimiter-argument-list list For delimiters and arguments ;; comint-last-input-start marker Handy if inferior always echoes ;; comint-last-input-end marker For comint-kill-output command ;; comint-input-ring-size integer For the input history ;; comint-input-ring ring mechanism ;; comint-input-ring-index number ... ;; comint-save-input-ring-index number ... ;; comint-input-autoexpand symbol ... ;; comint-input-ignoredups boolean ... ;; comint-last-input-match string ... ;; comint-dynamic-complete-functions hook For the completion mechanism ;; comint-completion-fignore list ... ;; comint-file-name-chars string ... ;; comint-file-name-quote-list list ... ;; comint-get-old-input function Hooks for specific ;; comint-input-filter-functions hook process-in-a-buffer ;; comint-output-filter-functions hook function modes. ;; comint-preoutput-filter-functions hook ;; comint-input-filter function ... ;; comint-input-sender function ... ;; comint-eol-on-send boolean ... ;; comint-process-echoes boolean ... ;; comint-scroll-to-bottom-on-input symbol For scroll behavior ;; comint-scroll-to-bottom-on-output symbol ... ;; comint-scroll-show-maximum-output boolean ... ;; comint-accum-marker maker For comint-accumulate ;; ;; 2d-nonsequential additions ;; comint-terminal-return function ... ;; comint-strip-input-function function ... ;; comint-insert-previous-input-function function ... ;; ;; Comint mode non-buffer local variables: ;; comint-completion-addsuffix boolean/cons For file name ;; comint-completion-autolist boolean completion behavior ;; comint-completion-recexact boolean ... (defgroup comint nil "General command interpreter in a window stuff." :group 'processes) (defgroup comint-completion nil "Completion facilities in comint" :group 'comint) (defgroup comint-source nil "Source finding facilities in comint" :prefix "comint-" :group 'comint) (defvar comint-prompt-regexp "^" "Regexp to recognise prompts in the inferior process. Defaults to \"^\", the null string at BOL. Good choices: Canonical Lisp: \"^[^> \\n]*>+:? *\" (Lucid, franz, kcl, T, cscheme, oaklisp) Lucid Common Lisp: \"^\\\\(>\\\\|\\\\(->\\\\)+\\\\) *\" franz: \"^\\\\(->\\\\|<[0-9]*>:\\\\) *\" kcl: \"^>+ *\" shell: \"^[^#$%>\\n]*[#$%>] *\" T: \"^>+ *\" This is a good thing to set in mode hooks.") (defvar comint-delimiter-argument-list () "List of characters to recognise as separate arguments in input. Strings comprising a character in this list will separate the arguments surrounding them, and also be regarded as arguments in their own right (unlike whitespace). See `comint-arguments'. Defaults to the empty list. For shells, a good value is (?\\| ?& ?< ?> ?\\( ?\\) ?;). This is a good thing to set in mode hooks.") (defcustom comint-input-autoexpand nil "*If non-nil, expand input command history references on completion. This mirrors the optional behavior of tcsh (its autoexpand and histlit). If the value is `input', then the expansion is seen on input. If the value is `history', then the expansion is only when inserting into the buffer's input ring. See also `comint-magic-space' and `comint-dynamic-complete'. This variable is buffer-local." :type '(choice (const :tag "off" nil) (const input) (const history) (other :tag "on" t)) :group 'comint) (defcustom comint-input-ignoredups nil "*If non-nil, don't add input matching the last on the input ring. This mirrors the optional behavior of bash. This variable is buffer-local." :type 'boolean :group 'comint) (defcustom comint-input-ring-file-name nil "*If non-nil, name of the file to read/write input history. See also `comint-read-input-ring' and `comint-write-input-ring'. This variable is buffer-local, and is a good thing to set in mode hooks." :type 'boolean :group 'comint) (defcustom comint-scroll-to-bottom-on-input nil "*Controls whether input to interpreter causes window to scroll. If nil, then do not scroll. If t or `all', scroll all windows showing buffer. If `this', scroll only the selected window. The default is nil. See `comint-preinput-scroll-to-bottom'. This variable is buffer-local." :type '(choice (const :tag "off" nil) (const t) (const all) (const this)) :group 'comint) (defcustom comint-scroll-to-bottom-on-output nil "*Controls whether interpreter output causes window to scroll. If nil, then do not scroll. If t or `all', scroll all windows showing buffer. If `this', scroll only the selected window. If `others', scroll only those that are not the selected window. The default is nil. See variable `comint-scroll-show-maximum-output' and function `comint-postoutput-scroll-to-bottom'. This variable is buffer-local." :type '(choice (const :tag "off" nil) (const t) (const all) (const this) (const others)) :group 'comint) (defcustom comint-scroll-show-maximum-output nil "*Controls how interpreter output causes window to scroll. If non-nil, then show the maximum output when the window is scrolled. See variable `comint-scroll-to-bottom-on-output' and function `comint-postoutput-scroll-to-bottom'. This variable is buffer-local." :type 'boolean :group 'comint) (defcustom comint-buffer-maximum-size 1024 "*The maximum size in lines for comint buffers. Comint buffers are truncated from the top to be no greater than this number, if the function `comint-truncate-buffer' is on `comint-output-filter-functions'." :type 'integer :group 'comint) (defvar comint-input-ring-size 32 "Size of input history ring.") (defcustom comint-process-echoes nil "*If non-nil, assume that the subprocess echoes any input. If so, delete one copy of the input so that only one copy eventually appears in the buffer. This variable is buffer-local." :type 'boolean :group 'comint) ;; AIX puts the name of the person being su'd to in front of the prompt. ;; kinit prints a prompt like `Password for devnull@GNU.ORG: '. ;; ksu prints a prompt like `Kerberos password for devnull/root@GNU.ORG: '. ;; ssh-add prints a prompt like `Enter passphrase: '. ;; Some implementations of passwd use "Password (again)" as the 2nd prompt. (defcustom comint-password-prompt-regexp "\\(\\([Oo]ld \\|[Nn]ew \\|Kerberos \\|'s \\|login \\|^\\)\ [Pp]assword\\( (again)\\)?\\|pass phrase\\|Enter passphrase\\)\ \\( for [^@ \t\n]+@[^@ \t\n]+\\)?:\\s *\\'" "*Regexp matching prompts for passwords in the inferior process. This is used by `comint-watch-for-password-prompt'." :type 'regexp :group 'comint) ;; Here are the per-interpreter hooks. (defvar comint-get-old-input (function comint-get-old-input-default) "Function that returns old text in comint mode. This function is called when return is typed while the point is in old text. It returns the text to be submitted as process input. The default is `comint-get-old-input-default', which grabs the current line, and strips off leading text matching `comint-prompt-regexp'.") (defvar comint-dynamic-complete-functions '(comint-replace-by-expanded-history comint-dynamic-complete-filename) "List of functions called to perform completion. Functions should return non-nil if completion was performed. See also `comint-dynamic-complete'. This is a good thing to set in mode hooks.") (defvar comint-input-filter (function (lambda (str) (not (string-match "\\`\\s *\\'" str)))) "Predicate for filtering additions to input history. Takes one argument, the input. If non-nil, the input may be saved on the input history list. Default is to save anything that isn't all whitespace.") (defvar comint-input-filter-functions '() "Functions to call before input is sent to the process. These functions get one argument, a string containing the text to send. This variable is buffer-local.") (defvar comint-output-filter-functions '(comint-postoutput-scroll-to-bottom) "Functions to call after output is inserted into the buffer. One possible function is `comint-postoutput-scroll-to-bottom'. These functions get one argument, a string containing the text as originally inserted. Note that this might not be the same as the buffer contents between `comint-last-output-start' and the buffer's `process-mark', if other filter functions have already modified the buffer. See also `comint-preoutput-filter-functions'. This variable is buffer-local.") (defvar comint-input-sender (function comint-simple-send) "Function to actually send to PROCESS the STRING submitted by user. Usually this is just `comint-simple-send', but if your mode needs to massage the input string, put a different function here. `comint-simple-send' just sends the string plus a newline. This is called from the user command `comint-send-input'.") (defcustom comint-eol-on-send t "*Non-nil means go to the end of the line before sending input. See `comint-send-input'." :type 'boolean :group 'comint) (defcustom comint-mode-hook '() "Called upon entry into comint-mode This is run before the process is cranked up." :type 'hook :group 'comint) (defcustom comint-exec-hook '() "Called each time a process is exec'd by `comint-exec'. This is called after the process is cranked up. It is useful for things that must be done each time a process is executed in a comint mode buffer (e.g., `(process-kill-without-query)'). In contrast, the `comint-mode-hook' is only executed once when the buffer is created." :type 'hook :group 'comint) (defvar comint-mode-map nil) (defvar comint-ptyp t "Non-nil if communications via pty; false if by pipe. Buffer local. This is to work around a bug in Emacs process signaling.") (defvar comint-input-ring nil) (defvar comint-last-input-start) (defvar comint-last-input-end) (defvar comint-last-output-start) (defvar comint-input-ring-index nil "Index of last matched history element.") (defvar comint-matching-input-from-input-string "" "Input previously used to match input history.") (defvar comint-save-input-ring-index "Last input ring index which you copied. This is to support the command \\[comint-get-next-from-history].") (defvar comint-accum-marker nil "Non-nil if you are accumulating input lines to send as input together. The command \\[comint-accumulate] sets this.") ;; 2d-nonsequential additions (defvar comint-terminal-return nil "Function that inserts hard or soft newline.") (defvar comint-strip-input-function nil "Use this function to modify input sent to prcess. Used to remove newlines in logo-mode.") (defvar comint-insert-previous-input-function nil "Function that inserts matching input.") (defvar process-defines-term nil "Pacifying the compiler.") (put 'comint-replace-by-expanded-history 'menu-enable 'comint-input-autoexpand) (put 'comint-input-ring 'permanent-local t) (put 'comint-input-ring-index 'permanent-local t) (put 'comint-save-input-ring-index 'permanent-local t) (put 'comint-input-autoexpand 'permanent-local t) (put 'comint-input-filter-functions 'permanent-local t) (put 'comint-output-filter-functions 'permanent-local t) (put 'comint-insert-previous-input-function'permanent-local t) (put 'comint-preoutput-filter-functions 'permanent-local t) (put 'comint-scroll-to-bottom-on-input 'permanent-local t) (put 'comint-scroll-to-bottom-on-output 'permanent-local t) (put 'comint-scroll-show-maximum-output 'permanent-local t) (put 'comint-ptyp 'permanent-local t) (put 'comint-mode 'mode-class 'special) (defun comint-mode () "Major mode for interacting with an inferior interpreter. Interpreter name is same as buffer name, sans the asterisks. Return at end of buffer sends line as input. Return not at end copies rest of line to end and sends it. Setting variable `comint-eol-on-send' means jump to the end of the line before submitting new input. This mode is customised to create major modes such as Inferior Lisp mode, Shell mode, etc. This can be done by setting the hooks `comint-input-filter-functions', `comint-input-filter', `comint-input-sender' and `comint-get-old-input' to appropriate functions, and the variable `comint-prompt-regexp' to the appropriate regular expression. An input history is maintained of size `comint-input-ring-size', and can be accessed with the commands \\[comint-next-input], \\[comint-previous-input], and \\[comint-dynamic-list-input-ring]. Input ring history expansion can be achieved with the commands \\[comint-replace-by-expanded-history] or \\[comint-magic-space]. Input ring expansion is controlled by the variable `comint-input-autoexpand', and addition is controlled by the variable `comint-input-ignoredups'. Commands with no default key bindings include `send-invisible', `comint-dynamic-complete', `comint-dynamic-list-filename-completions', and `comint-magic-space'. Input to, and output from, the subprocess can cause the window to scroll to the end of the buffer. See variables `comint-output-filter-functions', `comint-preoutput-filter-functions', `comint-scroll-to-bottom-on-input', and `comint-scroll-to-bottom-on-output'. If you accidentally suspend your process, use \\[comint-continue-subjob] to continue it. \\{comint-mode-map} Entry to this mode runs the hooks on `comint-mode-hook'." (interactive) ;; Do not remove this. All major modes must do this. (kill-all-local-variables) (setq major-mode 'comint-mode) (setq mode-name "Comint") (setq mode-line-process '(":%s")) (use-local-map comint-mode-map) (make-local-variable 'comint-last-input-start) (setq comint-last-input-start (make-marker)) (set-marker comint-last-input-start (point-min)) (make-local-variable 'comint-last-input-end) (setq comint-last-input-end (make-marker)) (set-marker comint-last-input-end (point-min)) (make-local-variable 'comint-last-output-start) (setq comint-last-output-start (make-marker)) (make-local-variable 'comint-prompt-regexp) ; Don't set; default (make-local-variable 'comint-input-ring-size) ; ...to global val. (make-local-variable 'comint-input-ring) (make-local-variable 'comint-input-ring-file-name) (or (and (boundp 'comint-input-ring) comint-input-ring) (setq comint-input-ring (make-ring comint-input-ring-size))) (make-local-variable 'comint-input-ring-index) (make-local-variable 'comint-save-input-ring-index) (or (and (boundp 'comint-input-ring-index) comint-input-ring-index) (setq comint-input-ring-index nil)) (or (and (boundp 'comint-save-input-ring-index) comint-save-input-ring-index) (setq comint-save-input-ring-index nil)) (make-local-variable 'comint-matching-input-from-input-string) (make-local-variable 'comint-input-autoexpand) (make-local-variable 'comint-input-ignoredups) (make-local-variable 'comint-delimiter-argument-list) (make-local-hook 'comint-dynamic-complete-functions) (make-local-variable 'comint-completion-fignore) (make-local-variable 'comint-get-old-input) (make-local-hook 'comint-input-filter-functions) (make-local-variable 'comint-input-filter) (make-local-variable 'comint-input-sender) (make-local-variable 'comint-eol-on-send) (make-local-variable 'comint-scroll-to-bottom-on-input) (make-local-variable 'comint-scroll-to-bottom-on-output) (make-local-variable 'comint-scroll-show-maximum-output) (make-local-hook 'pre-command-hook) (add-hook 'pre-command-hook 'comint-preinput-scroll-to-bottom t t) (make-local-hook 'comint-output-filter-functions) (make-local-hook 'comint-exec-hook) (make-local-variable 'comint-ptyp) (make-local-variable 'comint-process-echoes) (make-local-variable 'comint-file-name-chars) (make-local-variable 'comint-file-name-quote-list) (make-local-variable 'comint-accum-marker) (setq comint-accum-marker (make-marker)) (set-marker comint-accum-marker nil) ;; 2d-nonsequential additions (make-local-variable 'comint-terminal-return) (setq comint-terminal-return (symbol-function 'identity)) (make-local-variable 'comint-strip-input-function) (setq comint-strip-input-function (symbol-function 'identity)) (make-local-variable 'comint-insert-previous-input-function) (setq comint-insert-previous-input-function (function comint-insert-previous-matching-input)) ;; (run-hooks 'comint-mode-hook)) (if comint-mode-map nil ;; Keys: (setq comint-mode-map (make-sparse-keymap)) (define-key comint-mode-map "\ep" 'comint-previous-input) (define-key comint-mode-map "\en" 'comint-next-input) (define-key comint-mode-map [C-up] 'comint-previous-input) (define-key comint-mode-map [C-down] 'comint-next-input) (define-key comint-mode-map "\er" 'comint-previous-matching-input) (define-key comint-mode-map "\es" 'comint-next-matching-input) (define-key comint-mode-map [?\C-c ?\M-r] 'comint-previous-matching-input-from-input) (define-key comint-mode-map [?\C-c ?\M-s] 'comint-next-matching-input-from-input) (define-key comint-mode-map "\e\C-l" 'comint-show-output) (define-key comint-mode-map "\C-m" 'comint-send-input) (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof) (define-key comint-mode-map "\C-c " 'comint-accumulate) (define-key comint-mode-map "\C-c\C-x" 'comint-get-next-from-history) (define-key comint-mode-map "\C-c\C-a" 'comint-bol-or-process-mark) (define-key comint-mode-map "\C-c\C-u" 'comint-kill-input) (define-key comint-mode-map "\C-c\C-w" 'backward-kill-word) (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob) (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob) (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob) (define-key comint-mode-map "\C-c\C-m" 'comint-copy-old-input) (define-key comint-mode-map "\C-c\C-o" 'comint-kill-output) (define-key comint-mode-map "\C-c\C-r" 'comint-show-output) (define-key comint-mode-map "\C-c\C-e" 'comint-show-maximum-output) (define-key comint-mode-map "\C-c\C-l" 'comint-dynamic-list-input-ring) (define-key comint-mode-map "\C-c\C-n" 'comint-next-prompt) (define-key comint-mode-map "\C-c\C-p" 'comint-previous-prompt) (define-key comint-mode-map "\C-c\C-d" 'comint-send-eof) ;; Menu bars: ;; completion: (define-key comint-mode-map [menu-bar completion] (cons "Complete" (make-sparse-keymap "Complete"))) (define-key comint-mode-map [menu-bar completion complete-expand] '("Expand File Name" . comint-replace-by-expanded-filename)) (define-key comint-mode-map [menu-bar completion complete-listing] '("File Completion Listing" . comint-dynamic-list-filename-completions)) (define-key comint-mode-map [menu-bar completion complete-file] '("Complete File Name" . comint-dynamic-complete-filename)) (define-key comint-mode-map [menu-bar completion complete] '("Complete Before Point" . comint-dynamic-complete)) ;; Input history: (define-key comint-mode-map [menu-bar inout] (cons "In/Out" (make-sparse-keymap "In/Out"))) (define-key comint-mode-map [menu-bar inout kill-output] '("Kill Current Output Group" . comint-kill-output)) (define-key comint-mode-map [menu-bar inout next-prompt] '("Forward Output Group" . comint-next-prompt)) (define-key comint-mode-map [menu-bar inout previous-prompt] '("Backward Output Group" . comint-previous-prompt)) (define-key comint-mode-map [menu-bar inout show-maximum-output] '("Show Maximum Output" . comint-show-maximum-output)) (define-key comint-mode-map [menu-bar inout show-output] '("Show Current Output Group" . comint-show-output)) (define-key comint-mode-map [menu-bar inout kill-input] '("Kill Current Input" . comint-kill-input)) (define-key comint-mode-map [menu-bar inout copy-input] '("Copy Old Input" . comint-copy-old-input)) (define-key comint-mode-map [menu-bar inout forward-matching-history] '("Forward Matching Input..." . comint-forward-matching-input)) (define-key comint-mode-map [menu-bar inout backward-matching-history] '("Backward Matching Input..." . comint-backward-matching-input)) (define-key comint-mode-map [menu-bar inout next-matching-history] '("Next Matching Input..." . comint-next-matching-input)) (define-key comint-mode-map [menu-bar inout previous-matching-history] '("Previous Matching Input..." . comint-previous-matching-input)) (define-key comint-mode-map [menu-bar inout next-matching-history-from-input] '("Next Matching Current Input" . comint-next-matching-input-from-input)) (define-key comint-mode-map [menu-bar inout previous-matching-history-from-input] '("Previous Matching Current Input" . comint-previous-matching-input-from-input)) (define-key comint-mode-map [menu-bar inout next-history] '("Next Input" . comint-next-input)) (define-key comint-mode-map [menu-bar inout previous-history] '("Previous Input" . comint-previous-input)) (define-key comint-mode-map [menu-bar inout list-history] '("List Input History" . comint-dynamic-list-input-ring)) (define-key comint-mode-map [menu-bar inout expand-history] '("Expand History Before Point" . comint-replace-by-expanded-history)) ;; Signals (define-key comint-mode-map [menu-bar signals] (cons "Signals" (make-sparse-keymap "Signals"))) (define-key comint-mode-map [menu-bar signals eof] '("EOF" . comint-send-eof)) (define-key comint-mode-map [menu-bar signals kill] '("KILL" . comint-kill-subjob)) (define-key comint-mode-map [menu-bar signals quit] '("QUIT" . comint-quit-subjob)) (define-key comint-mode-map [menu-bar signals cont] '("CONT" . comint-continue-subjob)) (define-key comint-mode-map [menu-bar signals stop] '("STOP" . comint-stop-subjob)) (define-key comint-mode-map [menu-bar signals break] '("BREAK" . comint-interrupt-subjob)) ;; Put them in the menu bar: (setq menu-bar-final-items (append '(completion inout signals) menu-bar-final-items)) ) (defun comint-check-proc (buffer) "Return t if there is a living process associated w/buffer BUFFER. Living means the status is `open', `run', or `stop'. BUFFER can be either a buffer or the name of one." (let ((proc (get-buffer-process buffer))) (and proc (memq (process-status proc) '(open run stop))))) ;;;###autoload (defun make-comint (name program &optional startfile &rest switches) "Make a comint process NAME in a buffer, running PROGRAM. The name of the buffer is made by surrounding NAME with `*'s. PROGRAM should be either a string denoting an executable program to create via `start-process', or a cons pair of the form (HOST . SERVICE) denoting a TCP connection to be opened via `open-network-stream'. If there is already a running process in that buffer, it is not restarted. Optional third arg STARTFILE is the name of a file to send the contents of to the process. If PROGRAM is a string, any more args are arguments to PROGRAM." (or (fboundp 'start-process) (error "Multi-processing is not supported for this system")) (let ((buffer (get-buffer-create (concat "*" name "*")))) ;; If no process, or nuked process, crank up a new one and put buffer in ;; comint mode. Otherwise, leave buffer and existing process alone. (cond ((not (comint-check-proc buffer)) (save-excursion (set-buffer buffer) (comint-mode)) ; Install local vars, mode, keymap, ... (comint-exec buffer name program startfile switches))) buffer)) ;;;###autoload (defun comint-run (program) "Run PROGRAM in a comint buffer and switch to it. The buffer name is made by surrounding the file name of PROGRAM with `*'s. The file name is used to make a symbol name, such as `comint-sh-hook', and any hooks on this symbol are run in the buffer. See `make-comint' and `comint-exec'." (interactive "sRun program: ") (let ((name (file-name-nondirectory program))) (switch-to-buffer (make-comint name program)) (run-hooks (intern-soft (concat "comint-" name "-hook"))))) (defun comint-exec (buffer name command startfile switches) "Start up a process in buffer BUFFER for comint modes. Blasts any old process running in the buffer. Doesn't set the buffer mode. You can use this to cheaply run a series of processes in the same comint buffer. The hook `comint-exec-hook' is run after each exec." (save-excursion (set-buffer buffer) (let ((proc (get-buffer-process buffer))) ; Blast any old process. (if proc (delete-process proc))) ;; Crank up a new process (let ((proc (if (consp command) (open-network-stream name buffer (car command) (cdr command)) (comint-exec-1 name buffer command switches)))) (set-process-filter proc 'comint-output-filter) (make-local-variable 'comint-ptyp) (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe. ;; Jump to the end, and set the process mark. (goto-char (point-max)) (set-marker (process-mark proc) (point)) ;; Feed it the startfile. (cond (startfile ;;This is guaranteed to wait long enough ;;but has bad results if the comint does not prompt at all ;; (while (= size (buffer-size)) ;; (sleep-for 1)) ;;I hope 1 second is enough! (sleep-for 1) (goto-char (point-max)) (insert-file-contents startfile) (setq startfile (buffer-substring (point) (point-max))) (delete-region (point) (point-max)) (comint-send-string proc startfile))) (run-hooks 'comint-exec-hook) buffer))) ;; This auxiliary function cranks up the process for comint-exec in ;; the appropriate environment. (defun comint-exec-1 (name buffer command switches) (let ((process-environment (nconc ;; If using termcap, we specify `emacs' as the terminal type ;; because that lets us specify a width. ;; If using terminfo, we specify `dumb' because that is ;; a defined terminal type. `emacs' is not a defined terminal type ;; and there is no way for us to define it here. ;; Some programs that use terminfo get very confused ;; if TERM is not a valid terminal type. ;; ;; Some inferior process modes can define terminal type other ;; than `emacs' or `dumb' -- for an example see `logo.el'. ;; To use this, bind temporarily process-defines-term to a ;; list of three elements, as in following example ;; ;; (let ((process-defines-term ;; (list logo-term logo-term-columns logo-term-rows))) ;; (set-buffer ;; (apply 'make-comint "logo" logo-binary-name nil nil))) ;; (cond ((and (boundp 'process-defines-term) process-defines-term) (list (concat "TERM=" (car process-defines-term)) (format "COLUMNS=%d" (cadr process-defines-term)) (format "LINES=%d" (car (cddr process-defines-term))))) ((and (boundp 'system-uses-terminfo) system-uses-terminfo) (list "TERM=dumb" "TERMCAP=" (format "COLUMNS=%d" (frame-width)))) (t (list "TERM=emacs" (format "TERMCAP=emacs:co#%d:tc=unknown:" (frame-width))))) (if (getenv "EMACS") nil (list "EMACS=t")) process-environment)) (default-directory (if (file-accessible-directory-p default-directory) default-directory (char-to-string directory-sep-char))) proc decoding encoding changed) (setq proc (apply 'start-process name buffer command switches)) (let ((coding-systems (process-coding-system proc))) (setq decoding (car coding-systems) encoding (cdr coding-systems))) ;; If start-process decided to use some coding system for decoding ;; data sent form the process and the coding system doesn't ;; specify EOL conversion, we had better convert CRLF to LF. (if (vectorp (coding-system-eol-type decoding)) (setq decoding (coding-system-change-eol-conversion decoding 'dos) changed t)) ;; Even if start-process left the coding system for encoding data ;; sent from the process undecided, we had better use the same one ;; as what we use for decoding. But, we should suppress EOL ;; conversion. (if (and decoding (not encoding)) (setq encoding (coding-system-change-eol-conversion decoding 'unix) changed t)) (if changed (set-process-coding-system proc decoding encoding)) proc)) ;; Input history processing in a buffer ;; =========================================================================== ;; Useful input history functions, courtesy of the Ergo group. ;; Eleven commands: ;; comint-dynamic-list-input-ring List history in help buffer. ;; comint-previous-input Previous input... ;; comint-previous-matching-input ...matching a string. ;; comint-previous-matching-input-from-input ... matching the current input. ;; comint-next-input Next input... ;; comint-next-matching-input ...matching a string. ;; comint-next-matching-input-from-input ... matching the current input. ;; comint-backward-matching-input Backwards input... ;; comint-forward-matching-input ...matching a string. ;; comint-replace-by-expanded-history Expand history at point; ;; replace with expanded history. ;; comint-magic-space Expand history and insert space. ;; ;; Three functions: ;; comint-read-input-ring Read into comint-input-ring... ;; comint-write-input-ring Write to comint-input-ring-file-name. ;; comint-replace-by-expanded-history-before-point Workhorse function. (defun comint-read-input-ring (&optional silent) "Sets the buffer's `comint-input-ring' from a history file. The name of the file is given by the variable `comint-input-ring-file-name'. The history ring is of size `comint-input-ring-size', regardless of file size. If `comint-input-ring-file-name' is nil this function does nothing. If the optional argument SILENT is non-nil, we say nothing about a failure to read the history file. This function is useful for major mode commands and mode hooks. The structure of the history file should be one input command per line, with the most recent command last. See also `comint-input-ignoredups' and `comint-write-input-ring'." (cond ((or (null comint-input-ring-file-name) (equal comint-input-ring-file-name "")) nil) ((not (file-readable-p comint-input-ring-file-name)) (or silent (message "Cannot read history file %s" comint-input-ring-file-name))) (t (let ((history-buf (get-buffer-create " *temp*")) (file comint-input-ring-file-name) (count 0) (ring (make-ring comint-input-ring-size))) (unwind-protect (save-excursion (set-buffer history-buf) (widen) (erase-buffer) (insert-file-contents file) ;; Save restriction in case file is already visited... ;; Watch for those date stamps in history files! (goto-char (point-max)) (while (and (< count comint-input-ring-size) (re-search-backward "^[ \t]*\\([^#\n].*\\)[ \t]*$" nil t)) (let ((history (buffer-substring (match-beginning 1) (match-end 1)))) (if (or (null comint-input-ignoredups) (ring-empty-p ring) (not (string-equal (ring-ref ring 0) history))) (ring-insert-at-beginning ring history))) (setq count (1+ count)))) (kill-buffer history-buf)) (setq comint-input-ring ring comint-input-ring-index nil))))) (defun comint-write-input-ring () "Writes the buffer's `comint-input-ring' to a history file. The name of the file is given by the variable `comint-input-ring-file-name'. The original contents of the file are lost if `comint-input-ring' is not empty. If `comint-input-ring-file-name' is nil this function does nothing. Useful within process sentinels. See also `comint-read-input-ring'." (cond ((or (null comint-input-ring-file-name) (equal comint-input-ring-file-name "") (null comint-input-ring) (ring-empty-p comint-input-ring)) nil) ((not (file-writable-p comint-input-ring-file-name)) (message "Cannot write history file %s" comint-input-ring-file-name)) (t (let* ((history-buf (get-buffer-create " *Temp Input History*")) (ring comint-input-ring) (file comint-input-ring-file-name) (index (ring-length ring))) ;; Write it all out into a buffer first. Much faster, but messier, ;; than writing it one line at a time. (save-excursion (set-buffer history-buf) (erase-buffer) (while (> index 0) (setq index (1- index)) (insert (ring-ref ring index) ?\n)) (write-region (buffer-string) nil file nil 'no-message) (kill-buffer nil)))))) (defun comint-dynamic-list-input-ring () "List in help buffer the buffer's input history." (interactive) (if (or (not (ring-p comint-input-ring)) (ring-empty-p comint-input-ring)) (message "No history") (let ((history nil) (history-buffer " *Input History*") (index (1- (ring-length comint-input-ring))) (conf (current-window-configuration))) ;; We have to build up a list ourselves from the ring vector. (while (>= index 0) (setq history (cons (ring-ref comint-input-ring index) history) index (1- index))) ;; Change "completion" to "history reference" ;; to make the display accurate. (with-output-to-temp-buffer history-buffer (display-completion-list history) (set-buffer history-buffer) (forward-line 3) (while (search-backward "completion" nil 'move) (replace-match "history reference"))) (sit-for 0) (message "Hit space to flush") (let ((ch (read-event))) (if (eq ch ?\ ) (set-window-configuration conf) (setq unread-command-events (list ch))))))) (defun comint-regexp-arg (prompt) ;; Return list of regexp and prefix arg using PROMPT. (let* (;; Don't clobber this. (last-command last-command) (regexp (read-from-minibuffer prompt nil nil nil 'minibuffer-history-search-history))) (list (if (string-equal regexp "") (setcar minibuffer-history-search-history (nth 1 minibuffer-history-search-history)) regexp) (prefix-numeric-value current-prefix-arg)))) (defun comint-search-arg (arg) ;; First make sure there is a ring and that we are after the process mark (cond ((not (comint-after-pmark-p)) (error "Not at command line")) ((or (null comint-input-ring) (ring-empty-p comint-input-ring)) (error "Empty input ring")) ((zerop arg) ;; arg of zero resets search from beginning, and uses arg of 1 (setq comint-input-ring-index nil) 1) (t arg))) (defun comint-search-start (arg) ;; Index to start a directional search, starting at comint-input-ring-index (if comint-input-ring-index ;; If a search is running, offset by 1 in direction of arg (mod (+ comint-input-ring-index (if (> arg 0) 1 -1)) (ring-length comint-input-ring)) ;; For a new search, start from beginning or end, as appropriate (if (>= arg 0) 0 ; First elt for forward search (1- (ring-length comint-input-ring))))) ; Last elt for backward search (defun comint-previous-input-string (arg) "Return the string ARG places along the input ring. Moves relative to `comint-input-ring-index'." (ring-ref comint-input-ring (if comint-input-ring-index (mod (+ arg comint-input-ring-index) (ring-length comint-input-ring)) arg))) (defun comint-previous-input (arg) "Cycle backwards through input history." (interactive "*p") (comint-previous-matching-input "." arg)) (defun comint-next-input (arg) "Cycle forwards through input history." (interactive "*p") (comint-previous-input (- arg))) (defun comint-previous-matching-input-string (regexp arg) "Return the string matching REGEXP ARG places along the input ring. Moves relative to `comint-input-ring-index'." (let* ((pos (comint-previous-matching-input-string-position regexp arg))) (if pos (ring-ref comint-input-ring pos)))) (defun comint-previous-matching-input-string-position (regexp arg &optional start) "Return the index matching REGEXP ARG places along the input ring. Moves relative to START, or `comint-input-ring-index'." (if (or (not (ring-p comint-input-ring)) (ring-empty-p comint-input-ring)) (error "No history")) (let* ((len (ring-length comint-input-ring)) (motion (if (> arg 0) 1 -1)) (n (mod (- (or start (comint-search-start arg)) motion) len)) (tried-each-ring-item nil) (prev nil)) ;; Do the whole search as many times as the argument says. (while (and (/= arg 0) (not tried-each-ring-item)) ;; Step once. (setq prev n n (mod (+ n motion) len)) ;; If we haven't reached a match, step some more. (while (and (< n len) (not tried-each-ring-item) (not (string-match regexp (ring-ref comint-input-ring n)))) (setq n (mod (+ n motion) len) ;; If we have gone all the way around in this search. tried-each-ring-item (= n prev))) (setq arg (if (> arg 0) (1- arg) (1+ arg)))) ;; Now that we know which ring element to use, if we found it, return that. (if (string-match regexp (ring-ref comint-input-ring n)) n))) (defun comint-previous-matching-input (regexp arg) "Search backwards through input history for match for REGEXP. \(Previous history elements are earlier commands.) With prefix argument N, search for Nth previous match. If N is negative, find the next or Nth next match." (interactive (comint-regexp-arg "Previous input matching (regexp): ")) (setq arg (comint-search-arg arg)) (let ((pos (comint-previous-matching-input-string-position regexp arg))) ;; Has a match been found? (if (null pos) (error "Not found") (setq comint-input-ring-index pos) (message "History item: %d" (1+ pos)) (funcall comint-insert-previous-input-function (ring-ref comint-input-ring pos))))) (defun comint-insert-previous-matching-input (input) (delete-region ;; Can't use kill-region as it sets this-command (or (marker-position comint-accum-marker) (process-mark (get-buffer-process (current-buffer)))) (point)) (insert input)) (defun comint-next-matching-input (regexp arg) "Search forwards through input history for match for REGEXP. \(Later history elements are more recent commands.) With prefix argument N, search for Nth following match. If N is negative, find the previous or Nth previous match." (interactive (comint-regexp-arg "Next input matching (regexp): ")) (comint-previous-matching-input regexp (- arg))) (defun comint-previous-matching-input-from-input (arg) "Search backwards through input history for match for current input. \(Previous history elements are earlier commands.) With prefix argument N, search for Nth previous match. If N is negative, search forwards for the -Nth following match." (interactive "p") (if (not (memq last-command '(comint-previous-matching-input-from-input comint-next-matching-input-from-input))) ;; Starting a new search (setq comint-matching-input-from-input-string (buffer-substring (or (marker-position comint-accum-marker) (process-mark (get-buffer-process (current-buffer)))) (point)) comint-input-ring-index nil)) (comint-previous-matching-input (concat "^" (regexp-quote comint-matching-input-from-input-string)) arg)) (defun comint-next-matching-input-from-input (arg) "Search forwards through input history for match for current input. \(Following history elements are more recent commands.) With prefix argument N, search for Nth following match. If N is negative, search backwards for the -Nth previous match." (interactive "p") (comint-previous-matching-input-from-input (- arg))) (defun comint-replace-by-expanded-history (&optional silent start) "Expand input command history references before point. Expansion is dependent on the value of `comint-input-autoexpand'. This function depends on the buffer's idea of the input history, which may not match the command interpreter's idea, assuming it has one. Assumes history syntax is like typical Un*x shells'. However, since emacs cannot know the interpreter's idea of input line numbers, assuming it has one, it cannot expand absolute input line number references. If the optional argument SILENT is non-nil, never complain even if history reference seems erroneous. If the optional argument START is non-nil, that specifies the start of the text to scan for history references, rather than the logical beginning of line. See `comint-magic-space' and `comint-replace-by-expanded-history-before-point'. Returns t if successful." (interactive) (if (and comint-input-autoexpand (string-match "!\\|^\\^" (funcall comint-get-old-input)) (save-excursion (beginning-of-line) (looking-at comint-prompt-regexp))) ;; Looks like there might be history references in the command. (let ((previous-modified-tick (buffer-modified-tick))) (comint-replace-by-expanded-history-before-point silent start) (/= previous-modified-tick (buffer-modified-tick))))) (defun comint-replace-by-expanded-history-before-point (silent &optional start) "Expand directory stack reference before point. See `comint-replace-by-expanded-history'. Returns t if successful. If the optional argument START is non-nil, that specifies the start of the text to scan for history references, rather than the logical beginning of line." (save-excursion (let ((toend (- (save-excursion (end-of-line nil) (point)) (point))) (start (or start (progn (comint-bol nil) (point))))) (while (progn (skip-chars-forward "^!^" (save-excursion (end-of-line nil) (- (point) toend))) (< (point) (save-excursion (end-of-line nil) (- (point) toend)))) ;; This seems a bit complex. We look for references such as !!, !-num, ;; !foo, !?foo, !{bar}, !?{bar}, ^oh, ^my^, ^god^it, ^never^ends^. ;; If that wasn't enough, the plings can be suffixed with argument ;; range specifiers. ;; Argument ranges are complex too, so we hive off the input line, ;; referenced with plings, with the range string to `comint-args'. (setq comint-input-ring-index nil) (cond ((or (= (preceding-char) ?\\) (comint-within-quotes start (point))) ;; The history is quoted, or we're in quotes. (goto-char (1+ (point)))) ((looking-at "![0-9]+\\($\\|[^-]\\)") ;; We cannot know the interpreter's idea of input line numbers. (goto-char (match-end 0)) (message "Absolute reference cannot be expanded")) ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?") ;; Just a number of args from `number' lines backward. (let ((number (1- (string-to-number (buffer-substring (match-beginning 1) (match-end 1)))))) (if (<= number (ring-length comint-input-ring)) (progn (replace-match (comint-args (comint-previous-input-string number) (match-beginning 2) (match-end 2)) t t) (setq comint-input-ring-index number) (message "History item: %d" (1+ number))) (goto-char (match-end 0)) (message "Relative reference exceeds input history size")))) ((or (looking-at "!!?:?\\([0-9^$*-]+\\)") (looking-at "!!")) ;; Just a number of args from the previous input line. (replace-match (comint-args (comint-previous-input-string 0) (match-beginning 1) (match-end 1)) t t) (message "History item: previous")) ((looking-at "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?") ;; Most recent input starting with or containing (possibly ;; protected) string, maybe just a number of args. Phew. (let* ((mb1 (match-beginning 1)) (me1 (match-end 1)) (mb2 (match-beginning 2)) (me2 (match-end 2)) (exp (buffer-substring (or mb2 mb1) (or me2 me1))) (pref (if (save-match-data (looking-at "!\\?")) "" "^")) (pos (save-match-data (comint-previous-matching-input-string-position (concat pref (regexp-quote exp)) 1)))) (if (null pos) (progn (goto-char (match-end 0)) (or silent (progn (message "Not found") (ding)))) (setq comint-input-ring-index pos) (replace-match (comint-args (ring-ref comint-input-ring pos) (match-beginning 4) (match-end 4)) t t) (message "History item: %d" (1+ pos))))) ((looking-at "\\^\\([^^]+\\)\\^?\\([^^]*\\)\\^?") ;; Quick substitution on the previous input line. (let ((old (buffer-substring (match-beginning 1) (match-end 1))) (new (buffer-substring (match-beginning 2) (match-end 2))) (pos nil)) (replace-match (comint-previous-input-string 0) t t) (setq pos (point)) (goto-char (match-beginning 0)) (if (not (search-forward old pos t)) (or silent (error "Not found")) (replace-match new t t) (message "History item: substituted")))) (t (forward-char 1))))))) (defun comint-magic-space (arg) "Expand input history references before point and insert ARG spaces. A useful command to bind to SPC. See `comint-replace-by-expanded-history'." (interactive "p") (comint-replace-by-expanded-history) (self-insert-command arg)) (defun comint-within-quotes (beg end) "Return t if the number of quotes between BEG and END is odd. Quotes are single and double." (let ((countsq (comint-how-many-region "\\(^\\|[^\\\\]\\)\'" beg end)) (countdq (comint-how-many-region "\\(^\\|[^\\\\]\\)\"" beg end))) (or (= (mod countsq 2) 1) (= (mod countdq 2) 1)))) (defun comint-how-many-region (regexp beg end) "Return number of matches for REGEXP from BEG to END." (let ((count 0)) (save-excursion (save-match-data (goto-char beg) (while (re-search-forward regexp end t) (setq count (1+ count))))) count)) (defun comint-args (string begin end) ;; From STRING, return the args depending on the range specified in the text ;; from BEGIN to END. If BEGIN is nil, assume all args. Ignore leading `:'. ;; Range can be x-y, x-, -y, where x/y can be [0-9], *, ^, $. (save-match-data (if (null begin) (comint-arguments string 0 nil) (let* ((range (buffer-substring (if (eq (char-after begin) ?:) (1+ begin) begin) end)) (nth (cond ((string-match "^[*^]" range) 1) ((string-match "^-" range) 0) ((string-equal range "$") nil) (t (string-to-number range)))) (mth (cond ((string-match "[-*$]$" range) nil) ((string-match "-" range) (string-to-number (substring range (match-end 0)))) (t nth)))) (comint-arguments string nth mth))))) ;; Return a list of arguments from ARG. Break it up at the ;; delimiters in comint-delimiter-argument-list. Returned list is backwards. (defun comint-delim-arg (arg) (if (null comint-delimiter-argument-list) (list arg) (let ((args nil) (pos 0) (len (length arg))) (while (< pos len) (let ((char (aref arg pos)) (start pos)) (if (memq char comint-delimiter-argument-list) (while (and (< pos len) (eq (aref arg pos) char)) (setq pos (1+ pos))) (while (and (< pos len) (not (memq (aref arg pos) comint-delimiter-argument-list))) (setq pos (1+ pos)))) (setq args (cons (substring arg start pos) args)))) args))) (defun comint-arguments (string nth mth) "Return from STRING the NTH to MTH arguments. NTH and/or MTH can be nil, which means the last argument. Returned arguments are separated by single spaces. We assume whitespace separates arguments, except within quotes. Also, a run of one or more of a single character in `comint-delimiter-argument-list' is a separate argument. Argument 0 is the command name." ;; The first line handles ordinary characters and backslash-sequences ;; (except with w32 msdos-like shells, where backslashes are valid). ;; The second matches "-quoted strings. ;; The third matches '-quoted strings. ;; The fourth matches `-quoted strings. ;; This seems to fit the syntax of BASH 2.0. (let* ((first (if (and (eq system-type 'windows-nt) (w32-shell-dos-semantics)) "[^ \n\t\"'`]+\\|" "[^ \n\t\"'`\\]+\\|\\\\[\"'`\\]+\\|")) (argpart (concat first "\\(\"\\([^\"\\]\\|\\\\.\\)*\"\\|\ '[^']*'\\|\ `[^`]*`\\)")) (args ()) (pos 0) (count 0) beg str value quotes) ;; Build a list of all the args until we have as many as we want. (while (and (or (null mth) (<= count mth)) (string-match argpart string pos)) (if (and beg (= pos (match-beginning 0))) ;; It's contiguous, part of the same arg. (setq pos (match-end 0) quotes (or quotes (match-beginning 1))) ;; It's a new separate arg. (if beg ;; Put the previous arg, if there was one, onto ARGS. (setq str (substring string beg pos) args (if quotes (cons str args) (nconc (comint-delim-arg str) args)) count (1+ count))) (setq quotes (match-beginning 1)) (setq beg (match-beginning 0)) (setq pos (match-end 0)))) (if beg (setq str (substring string beg pos) args (if quotes (cons str args) (nconc (comint-delim-arg str) args)) count (1+ count))) (let ((n (or nth (1- count))) (m (if mth (1- (- count mth)) 0))) (mapconcat (function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " ")))) ;; ;; Input processing stuff ;; (defun comint-send-input () "Send input to process. After the process output mark, sends all text from the process mark to point as input to the process. Before the process output mark, calls value of variable `comint-get-old-input' to retrieve old input, copies it to the process mark, and sends it. If variable `comint-process-echoes' is nil, a terminal newline is also inserted into the buffer and sent to the process \(if it is non-nil, all text from the process mark to point is deleted, since it is assumed the remote process will re-echo it). Any history reference may be expanded depending on the value of the variable `comint-input-autoexpand'. The list of function names contained in the value of `comint-input-filter-functions' is called on the input before sending it. The input is entered into the input history ring, if the value of variable `comint-input-filter' returns non-nil when called on the input. If variable `comint-eol-on-send' is non-nil, then point is moved to the end of line before sending the input. The values of `comint-get-old-input', `comint-input-filter-functions', and `comint-input-filter' are chosen according to the command interpreter running in the buffer. E.g., If the interpreter is the csh, comint-get-old-input is the default: take the current line, discard any initial string matching regexp comint-prompt-regexp. comint-input-filter-functions monitors input for \"cd\", \"pushd\", and \"popd\" commands. When it sees one, it cd's the buffer. comint-input-filter is the default: returns t if the input isn't all white space. If the comint is Lucid Common Lisp, comint-get-old-input snarfs the sexp ending at point. comint-input-filter-functions does nothing. comint-input-filter returns nil if the input matches input-filter-regexp, which matches (1) all whitespace (2) :a, :c, etc. Similarly for Soar, Scheme, etc." (interactive) ;; Note that the input string does not include its terminal newline. (let ((proc (get-buffer-process (current-buffer)))) (if (not proc) (error "Current buffer has no process") (let* ((pmark (process-mark proc)) (intxt (if (>= (point) (marker-position pmark)) (progn (cond ((eq comint-eol-on-send 'end-of-input) (goto-char comint-last-input-end)) (comint-eol-on-send (end-of-line))) (buffer-substring pmark (point))) (let ((copy (funcall comint-get-old-input))) (goto-char pmark) (insert copy) copy))) (input (funcall comint-strip-input-function (if (not (eq comint-input-autoexpand 'input)) ;; Just whatever's already there intxt ;; Expand and leave it visible in buffer (comint-replace-by-expanded-history t pmark) (buffer-substring pmark (point))))) (history (if (not (eq comint-input-autoexpand 'history)) input ;; This is messy 'cos ultimately the original ;; functions used do insertion, rather than return ;; strings. We have to expand, then insert back. (funcall comint-strip-input-function (progn (comint-replace-by-expanded-history t pmark) (let ((copy (buffer-substring pmark (point))) (start (point))) (insert input) (delete-region pmark start) copy)))))) (if comint-process-echoes (delete-region pmark (point)) (insert-before-markers (funcall comint-terminal-return ?\n))) (if (and (funcall comint-input-filter history) (or (null comint-input-ignoredups) (not (ring-p comint-input-ring)) (ring-empty-p comint-input-ring) (not (string-equal (ring-ref comint-input-ring 0) history)))) (ring-insert comint-input-ring history)) (run-hook-with-args 'comint-input-filter-functions (concat input "\n")) (setq comint-save-input-ring-index comint-input-ring-index) (setq comint-input-ring-index nil) ;; Update the markers before we send the input ;; in case we get output amidst sending the input. (set-marker comint-last-input-start pmark) (set-marker comint-last-input-end (point)) (set-marker (process-mark proc) (point)) ;; clear the "accumulation" marker (set-marker comint-accum-marker nil) (funcall comint-input-sender proc input) ;; This used to call comint-output-filter-functions, ;; but that scrolled the buffer in undesirable ways. (run-hook-with-args 'comint-output-filter-functions ""))))) (defvar comint-preoutput-filter-functions nil "Functions to call before output is inserted into the buffer. These functions get one argument, a string containing the text to be inserted. They return the string as it should be inserted. This variable is buffer-local.") ;; The purpose of using this filter for comint processes ;; is to keep comint-last-input-end from moving forward ;; when output is inserted. (defun comint-output-filter (process string) ;; First check for killed buffer (let ((oprocbuf (process-buffer process))) (let ((functions comint-preoutput-filter-functions)) (while (and functions string) (setq string (funcall (car functions) string)) (setq functions (cdr functions)))) (if (and string oprocbuf (buffer-name oprocbuf)) (let ((obuf (current-buffer)) (opoint nil) (obeg nil) (oend nil)) (set-buffer oprocbuf) (setq opoint (point)) (setq obeg (point-min)) (setq oend (point-max)) (let ((buffer-read-only nil) (nchars (length string)) (ostart nil)) (widen) (goto-char (process-mark process)) (setq ostart (point)) (if (<= (point) opoint) (setq opoint (+ opoint nchars))) ;; Insert after old_begv, but before old_zv. (if (< (point) obeg) (setq obeg (+ obeg nchars))) (if (<= (point) oend) (setq oend (+ oend nchars))) (insert-before-markers string) ;; Don't insert initial prompt outside the top of the window. (if (= (window-start (selected-window)) (point)) (set-window-start (selected-window) (- (point) (length string)))) (if (and comint-last-input-end (marker-buffer comint-last-input-end) (= (point) comint-last-input-end)) (set-marker comint-last-input-end (- comint-last-input-end nchars))) (set-marker comint-last-output-start ostart) (set-marker (process-mark process) (point)) (force-mode-line-update)) (narrow-to-region obeg oend) (goto-char opoint) (run-hook-with-args 'comint-output-filter-functions string) (set-buffer obuf))))) (defun comint-preinput-scroll-to-bottom () "Go to the end of buffer in all windows showing it. Movement occurs if point in the selected window is not after the process mark, and `this-command' is an insertion command. Insertion commands recognised are `self-insert-command', `comint-magic-space', `yank', and `hilit-yank'. Depends on the value of `comint-scroll-to-bottom-on-input'. This function should be a pre-command hook." (if (and comint-scroll-to-bottom-on-input (memq this-command '(self-insert-command comint-magic-space yank hilit-yank))) (let* ((selected (selected-window)) (current (current-buffer)) (process (get-buffer-process current)) (scroll comint-scroll-to-bottom-on-input)) (if (and process (< (point) (process-mark process))) (if (eq scroll 'this) (goto-char (point-max)) (walk-windows (function (lambda (window) (if (and (eq (window-buffer window) current) (or (eq scroll t) (eq scroll 'all))) (progn (select-window window) (goto-char (point-max)) (select-window selected))))) nil t)))))) (defun comint-postoutput-scroll-to-bottom (string) "Go to the end of buffer in all windows showing it. Does not scroll if the current line is the last line in the buffer. Depends on the value of `comint-scroll-to-bottom-on-output' and `comint-scroll-show-maximum-output'. This function should be in the list `comint-output-filter-functions'." (let* ((selected (selected-window)) (current (current-buffer)) (process (get-buffer-process current)) (scroll comint-scroll-to-bottom-on-output)) (unwind-protect (if process (walk-windows (function (lambda (window) (if (eq (window-buffer window) current) (progn (select-window window) (if (and (< (point) (process-mark process)) (or (eq scroll t) (eq scroll 'all) ;; Maybe user wants point to jump to end. (and (eq scroll 'this) (eq selected window)) (and (eq scroll 'others) (not (eq selected window))) ;; If point was at the end, keep it at end. (and (marker-position comint-last-output-start) (>= (point) comint-last-output-start)))) (goto-char (process-mark process))) ;; Optionally scroll so that the text ;; ends at the bottom of the window. (if (and comint-scroll-show-maximum-output (>= (point) (process-mark process))) (save-excursion (goto-char (point-max)) (recenter -1))) (select-window selected))))) nil t)) (set-buffer current)))) (defun comint-truncate-buffer (&optional string) "Truncate the buffer to `comint-buffer-maximum-size'. This function could be on `comint-output-filter-functions' or bound to a key." (interactive) (save-excursion (goto-char (process-mark (get-buffer-process (current-buffer)))) (forward-line (- comint-buffer-maximum-size)) (beginning-of-line) (delete-region (point-min) (point)))) (defun comint-strip-ctrl-m (&optional string) "Strip trailing `^M' characters from the current output group. This function could be on `comint-output-filter-functions' or bound to a key." (interactive) (let ((pmark (process-mark (get-buffer-process (current-buffer))))) (save-excursion (condition-case nil (goto-char (if (interactive-p) comint-last-input-end comint-last-output-start)) (error nil)) (while (re-search-forward "\r+$" pmark t) (replace-match "" t t))))) (defalias 'shell-strip-ctrl-m 'comint-strip-ctrl-m) (defun comint-show-maximum-output () "Put the end of the buffer at the bottom of the window." (interactive) (goto-char (point-max)) (recenter -1)) (defun comint-get-old-input-default () "Default for `comint-get-old-input'. Take the current line, and discard any initial text matching `comint-prompt-regexp'." (save-excursion (beginning-of-line) (comint-skip-prompt) (let ((beg (point))) (end-of-line) (buffer-substring beg (point))))) (defun comint-copy-old-input () "Insert after prompt old input at point as new input to be edited. Calls `comint-get-old-input' to get old input." (interactive) (let ((input (funcall comint-get-old-input)) (process (get-buffer-process (current-buffer)))) (if (not process) (error "Current buffer has no process") (goto-char (process-mark process)) (insert input)))) (defun comint-skip-prompt () "Skip past the text matching regexp `comint-prompt-regexp'. If this takes us past the end of the current line, don't skip at all." (let ((eol (save-excursion (end-of-line) (point)))) (if (and (looking-at comint-prompt-regexp) (<= (match-end 0) eol)) (goto-char (match-end 0))))) (defun comint-after-pmark-p () "Return t if point is after the process output marker." (let ((pmark (process-mark (get-buffer-process (current-buffer))))) (<= (marker-position pmark) (point)))) (defun comint-simple-send (proc string) "Default function for sending to PROC input STRING. This just sends STRING plus a newline. To override this, set the hook `comint-input-sender'." (comint-send-string proc string) (comint-send-string proc "\n")) (defun comint-bol (arg) "Goes to the beginning of line, then skips past the prompt, if any. If prefix argument is given (\\[universal-argument]) the prompt is not skipped. The prompt skip is done by skipping text matching the regular expression `comint-prompt-regexp', a buffer local variable." (interactive "P") (beginning-of-line) (if (null arg) (comint-skip-prompt))) ;; These three functions are for entering text you don't want echoed or ;; saved -- typically passwords to ftp, telnet, or somesuch. ;; Just enter m-x send-invisible and type in your line, or add ;; `comint-watch-for-password-prompt' to `comint-output-filter-functions'. (defun comint-read-noecho (prompt &optional stars) "Read a single line of text from user without echoing, and return it. Prompt with argument PROMPT, a string. Optional argument STARS causes input to be echoed with '*' characters on the prompt line. Input ends with RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line. C-g aborts (if `inhibit-quit' is set because e.g. this function was called from a process filter and C-g is pressed, this function returns nil rather than a string). Note that the keystrokes comprising the text can still be recovered \(temporarily) with \\[view-lossage]. Some people find this worrysome. Once the caller uses the password, it can erase the password by doing (fillarray STRING 0)." (let ((ans "") (newans nil) (c 0) (echo-keystrokes 0) (cursor-in-echo-area t) (message-log-max nil) (done nil)) (while (not done) (if stars (message "%s%s" prompt (make-string (length ans) ?*)) (message "%s" prompt)) ;; Use this instead of `read-char' to avoid "Non-character input-event". (setq c (read-char-exclusive)) (cond ((= c ?\C-g) ;; This function may get called from a process filter, where ;; inhibit-quit is set. In later versions of emacs read-char ;; may clear quit-flag itself and return C-g. That would make ;; it impossible to quit this loop in a simple way, so ;; re-enable it here (for backward-compatibility the check for ;; quit-flag below would still be necessary, so this seems ;; like the simplest way to do things). (setq quit-flag t done t)) ((or (= c ?\r) (= c ?\n) (= c ?\e)) (setq done t)) ((= c ?\C-u) (fillarray ans 0) (setq ans "")) ((and (/= c ?\b) (/= c ?\177)) (setq newans (concat ans (char-to-string c))) (fillarray ans 0) (setq ans newans)) ((> (length ans) 0) (aset ans (1- (length ans)) 0) (setq ans (substring ans 0 -1))))) (if quit-flag ;; Emulate a true quit, except that we have to return a value. (prog1 (setq quit-flag nil) (message "Quit") (beep t)) (message "") ans))) (defun send-invisible (str) "Read a string without echoing. Then send it to the process running in the current buffer. The string is sent using `comint-input-sender'. Security bug: your string can still be temporarily recovered with \\[view-lossage]." (interactive "P") ; Defeat snooping via C-x ESC ESC (let ((proc (get-buffer-process (current-buffer)))) (cond ((not proc) (error "Current buffer has no process")) ((stringp str) (funcall comint-input-sender proc str)) (t (let ((str (comint-read-noecho "Non-echoed text: " t))) (if (stringp str) (send-invisible str) (message "Warning: text will be echoed"))))))) (defun comint-watch-for-password-prompt (string) "Prompt in the minibuffer for password and send without echoing. This function uses `send-invisible' to read and send a password to the buffer's process if STRING contains a password prompt defined by `comint-password-prompt-regexp'. This function could be in the list `comint-output-filter-functions'." (if (string-match comint-password-prompt-regexp string) (send-invisible nil))) ;; Low-level process communication (defalias 'comint-send-string 'process-send-string) (defalias 'comint-send-region 'process-send-region) ;; Random input hackage (defun comint-kill-output () "Kill all output from interpreter since last input. Does not delete the prompt." (interactive) (let ((proc (get-buffer-process (current-buffer))) (replacement nil)) (save-excursion (let ((pmark (progn (goto-char (process-mark proc)) (beginning-of-line nil) (point-marker)))) (delete-region comint-last-input-end pmark) (goto-char (process-mark proc)) (setq replacement (concat "*** output flushed ***\n" (buffer-substring pmark (point)))) (delete-region pmark (point)))) ;; Output message and put back prompt (comint-output-filter proc replacement))) (defun comint-show-output () "Display start of this batch of interpreter output at top of window. Sets mark to the value of point when this command is run." (interactive) (push-mark) (let ((pos (point))) (goto-char (or (marker-position comint-last-input-end) (point-max))) (beginning-of-line 0) (set-window-start (selected-window) (point)) (comint-skip-prompt))) (defun comint-interrupt-subjob () "Interrupt the current subjob. This command also kills the pending input between the process-mark and point." (interactive) (comint-kill-input) (interrupt-process nil comint-ptyp)) (defun comint-kill-subjob () "Send kill signal to the current subjob. This command also kills the pending input between the process-mark and point." (interactive) (comint-kill-input) (kill-process nil comint-ptyp)) (defun comint-quit-subjob () "Send quit signal to the current subjob. This command also kills the pending input between the process-mark and point." (interactive) (comint-kill-input) (quit-process nil comint-ptyp)) (defun comint-stop-subjob () "Stop the current subjob. This command also kills the pending input between the process-mark and point. WARNING: if there is no current subjob, you can end up suspending the top-level process running in the buffer. If you accidentally do this, use \\[comint-continue-subjob] to resume the process. (This is not a problem with most shells, since they ignore this signal.)" (interactive) (comint-kill-input) (stop-process nil comint-ptyp)) (defun comint-continue-subjob () "Send CONT signal to process buffer's process group. Useful if you accidentally suspend the top-level process." (interactive) (continue-process nil comint-ptyp)) (defun comint-kill-input () "Kill all text from last stuff output by interpreter to point." (interactive) (let ((pmark (process-mark (get-buffer-process (current-buffer))))) (if (> (point) (marker-position pmark)) (kill-region pmark (point))))) (defun comint-delchar-or-maybe-eof (arg) "Delete ARG characters forward or send an EOF to subprocess. Sends an EOF only if point is at the end of the buffer and there is no input." (interactive "p") (let ((proc (get-buffer-process (current-buffer)))) (if (and (eobp) proc (= (point) (marker-position (process-mark proc)))) (process-send-eof) (delete-char arg)))) (defun comint-send-eof () "Send an EOF to the current buffer's process." (interactive) (process-send-eof)) (defun comint-backward-matching-input (regexp arg) "Search backward through buffer for match for REGEXP. Matches are searched for on lines that match `comint-prompt-regexp'. With prefix argument N, search for Nth previous match. If N is negative, find the next or Nth next match." (interactive (comint-regexp-arg "Backward input matching (regexp): ")) (let* ((re (concat comint-prompt-regexp ".*" regexp)) (pos (save-excursion (end-of-line (if (> arg 0) 0 1)) (if (re-search-backward re nil t arg) (point))))) (if (null pos) (progn (message "Not found") (ding)) (goto-char pos) (comint-bol nil)))) (defun comint-forward-matching-input (regexp arg) "Search forward through buffer for match for REGEXP. Matches are searched for on lines that match `comint-prompt-regexp'. With prefix argument N, search for Nth following match. If N is negative, find the previous or Nth previous match." (interactive (comint-regexp-arg "Forward input matching (regexp): ")) (comint-backward-matching-input regexp (- arg))) (defun comint-next-prompt (n) "Move to end of Nth next prompt in the buffer. See `comint-prompt-regexp'." (interactive "p") (let ((paragraph-start comint-prompt-regexp)) (end-of-line (if (> n 0) 1 0)) (forward-paragraph n) (comint-skip-prompt))) (defun comint-previous-prompt (n) "Move to end of Nth previous prompt in the buffer. See `comint-prompt-regexp'." (interactive "p") (comint-next-prompt (- n))) ;; Support for source-file processing commands. ;;============================================================================ ;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have ;; commands that process files of source text (e.g. loading or compiling ;; files). So the corresponding process-in-a-buffer modes have commands ;; for doing this (e.g., lisp-load-file). The functions below are useful ;; for defining these commands. ;; ;; Alas, these guys don't do exactly the right thing for Lisp, Scheme ;; and Soar, in that they don't know anything about file extensions. ;; So the compile/load interface gets the wrong default occasionally. ;; The load-file/compile-file default mechanism could be smarter -- it ;; doesn't know about the relationship between filename extensions and ;; whether the file is source or executable. If you compile foo.lisp ;; with compile-file, then the next load-file should use foo.bin for ;; the default, not foo.lisp. This is tricky to do right, particularly ;; because the extension for executable files varies so much (.o, .bin, ;; .lbin, .mo, .vo, .ao, ...). ;; COMINT-SOURCE-DEFAULT -- determines defaults for source-file processing ;; commands. ;; ;; COMINT-CHECK-SOURCE -- if FNAME is in a modified buffer, asks you if you ;; want to save the buffer before issuing any process requests to the command ;; interpreter. ;; ;; COMINT-GET-SOURCE -- used by the source-file processing commands to prompt ;; for the file to process. ;; (COMINT-SOURCE-DEFAULT previous-dir/file source-modes) ;;============================================================================ ;; This function computes the defaults for the load-file and compile-file ;; commands for tea, soar, cmulisp, and cmuscheme modes. ;; ;; - PREVIOUS-DIR/FILE is a pair (directory . filename) from the last ;; source-file processing command. NIL if there hasn't been one yet. ;; - SOURCE-MODES is a list used to determine what buffers contain source ;; files: if the major mode of the buffer is in SOURCE-MODES, it's source. ;; Typically, (lisp-mode) or (scheme-mode). ;; ;; If the command is given while the cursor is inside a string, *and* ;; the string is an existing filename, *and* the filename is not a directory, ;; then the string is taken as default. This allows you to just position ;; your cursor over a string that's a filename and have it taken as default. ;; ;; If the command is given in a file buffer whose major mode is in ;; SOURCE-MODES, then the the filename is the default file, and the ;; file's directory is the default directory. ;; ;; If the buffer isn't a source file buffer (e.g., it's the process buffer), ;; then the default directory & file are what was used in the last source-file ;; processing command (i.e., PREVIOUS-DIR/FILE). If this is the first time ;; the command has been run (PREVIOUS-DIR/FILE is nil), the default directory ;; is the cwd, with no default file. (\"no default file\" = nil) ;; ;; SOURCE-REGEXP is typically going to be something like (tea-mode) ;; for T programs, (lisp-mode) for Lisp programs, (soar-mode lisp-mode) ;; for Soar programs, etc. ;; ;; The function returns a pair: (default-directory . default-file). (defun comint-source-default (previous-dir/file source-modes) (cond ((and buffer-file-name (memq major-mode source-modes)) (cons (file-name-directory buffer-file-name) (file-name-nondirectory buffer-file-name))) (previous-dir/file) (t (cons default-directory nil)))) ;; (COMINT-CHECK-SOURCE fname) ;;============================================================================ ;; Prior to loading or compiling (or otherwise processing) a file (in the CMU ;; process-in-a-buffer modes), this function can be called on the filename. ;; If the file is loaded into a buffer, and the buffer is modified, the user ;; is queried to see if he wants to save the buffer before proceeding with ;; the load or compile. (defun comint-check-source (fname) (let ((buff (get-file-buffer fname))) (if (and buff (buffer-modified-p buff) (y-or-n-p (format "Save buffer %s first? " (buffer-name buff)))) ;; save BUFF. (let ((old-buffer (current-buffer))) (set-buffer buff) (save-buffer) (set-buffer old-buffer))))) ;; (COMINT-GET-SOURCE prompt prev-dir/file source-modes mustmatch-p) ;;============================================================================ ;; COMINT-GET-SOURCE is used to prompt for filenames in command-interpreter ;; commands that process source files (like loading or compiling a file). ;; It prompts for the filename, provides a default, if there is one, ;; and returns the result filename. ;; ;; See COMINT-SOURCE-DEFAULT for more on determining defaults. ;; ;; PROMPT is the prompt string. PREV-DIR/FILE is the (directory . file) pair ;; from the last source processing command. SOURCE-MODES is a list of major ;; modes used to determine what file buffers contain source files. (These ;; two arguments are used for determining defaults). If MUSTMATCH-P is true, ;; then the filename reader will only accept a file that exists. ;; ;; A typical use: ;; (interactive (comint-get-source "Compile file: " prev-lisp-dir/file ;; '(lisp-mode) t)) ;; This is pretty stupid about strings. It decides we're in a string ;; if there's a quote on both sides of point on the current line. (defun comint-extract-string () "Return string around POINT that starts the current line, or nil." (save-excursion (let* ((point (point)) (bol (progn (beginning-of-line) (point))) (eol (progn (end-of-line) (point))) (start (progn (goto-char point) (and (search-backward "\"" bol t) (1+ (point))))) (end (progn (goto-char point) (and (search-forward "\"" eol t) (1- (point)))))) (and start end (buffer-substring start end))))) (defun comint-get-source (prompt prev-dir/file source-modes mustmatch-p) (let* ((def (comint-source-default prev-dir/file source-modes)) (stringfile (comint-extract-string)) (sfile-p (and stringfile (condition-case () (file-exists-p stringfile) (error nil)) (not (file-directory-p stringfile)))) (defdir (if sfile-p (file-name-directory stringfile) (car def))) (deffile (if sfile-p (file-name-nondirectory stringfile) (cdr def))) (ans (read-file-name (if deffile (format "%s(default %s) " prompt deffile) prompt) defdir (concat defdir deffile) mustmatch-p))) (list (expand-file-name (substitute-in-file-name ans))))) ;; I am somewhat divided on this string-default feature. It seems ;; to violate the principle-of-least-astonishment, in that it makes ;; the default harder to predict, so you actually have to look and see ;; what the default really is before choosing it. This can trip you up. ;; On the other hand, it can be useful, I guess. I would appreciate feedback ;; on this. ;; -Olin ;; Simple process query facility. ;; =========================================================================== ;; This function is for commands that want to send a query to the process ;; and show the response to the user. For example, a command to get the ;; arglist for a Common Lisp function might send a "(arglist 'foo)" query ;; to an inferior Common Lisp process. ;; ;; This simple facility just sends strings to the inferior process and pops ;; up a window for the process buffer so you can see what the process ;; responds with. We don't do anything fancy like try to intercept what the ;; process responds with and put it in a pop-up window or on the message ;; line. We just display the buffer. Low tech. Simple. Works good. ;; Send to the inferior process PROC the string STR. Pop-up but do not select ;; a window for the inferior process so that its response can be seen. (defun comint-proc-query (proc str) (let* ((proc-buf (process-buffer proc)) (proc-mark (process-mark proc))) (display-buffer proc-buf) (set-buffer proc-buf) ; but it's not the selected *window* (let ((proc-win (get-buffer-window proc-buf)) (proc-pt (marker-position proc-mark))) (comint-send-string proc str) ; send the query (accept-process-output proc) ; wait for some output ;; Try to position the proc window so you can see the answer. ;; This is bogus code. If you delete the (sit-for 0), it breaks. ;; I don't know why. Wizards invited to improve it. (unless (pos-visible-in-window-p proc-pt proc-win) (let ((opoint (window-point proc-win))) (set-window-point proc-win proc-mark) (sit-for 0) (if (not (pos-visible-in-window-p opoint proc-win)) (push-mark opoint) (set-window-point proc-win opoint))))))) ;; Filename/command/history completion in a buffer ;; =========================================================================== ;; Useful completion functions, courtesy of the Ergo group. ;; Six commands: ;; comint-dynamic-complete Complete or expand command, filename, ;; history at point. ;; comint-dynamic-complete-filename Complete filename at point. ;; comint-dynamic-list-filename-completions List completions in help buffer. ;; comint-replace-by-expanded-filename Expand and complete filename at point; ;; replace with expanded/completed name. ;; comint-dynamic-simple-complete Complete stub given candidates. ;; These are not installed in the comint-mode keymap. But they are ;; available for people who want them. Shell-mode installs them: ;; (define-key shell-mode-map "\t" 'comint-dynamic-complete) ;; (define-key shell-mode-map "\M-?" ;; 'comint-dynamic-list-filename-completions))) ;; ;; Commands like this are fine things to put in load hooks if you ;; want them present in specific modes. (defcustom comint-completion-autolist nil "*If non-nil, automatically list possibilities on partial completion. This mirrors the optional behavior of tcsh." :type 'boolean :group 'comint-completion) (defcustom comint-completion-addsuffix t "*If non-nil, add a `/' to completed directories, ` ' to file names. If a cons pair, it should be of the form (DIRSUFFIX . FILESUFFIX) where DIRSUFFIX and FILESUFFIX are strings added on unambiguous or exact completion. This mirrors the optional behavior of tcsh." :type 'boolean :group 'comint-completion) (defcustom comint-completion-recexact nil "*If non-nil, use shortest completion if characters cannot be added. This mirrors the optional behavior of tcsh. A non-nil value is useful if `comint-completion-autolist' is non-nil too." :type 'boolean :group 'comint-completion) (defcustom comint-completion-fignore nil "*List of suffixes to be disregarded during file completion. This mirrors the optional behavior of bash and tcsh. Note that this applies to `comint-dynamic-complete-filename' only." :type '(repeat (string :tag "Suffix")) :group 'comint-completion) (defvar comint-file-name-prefix "" "Prefix prepended to absolute file names taken from process input. This is used by comint's and shell's completion functions, and by shell's directory tracking functions.") (defvar comint-file-name-chars (if (memq system-type '(ms-dos windows-nt)) "~/A-Za-z0-9_^$!#%&{}@`'.,:()-" "~/A-Za-z0-9+@:_.$#%,={}-") "String of characters valid in a file name. Note that all non-ASCII characters are considered valid in a file name regardless of what this variable says. This is a good thing to set in mode hooks.") (defvar comint-file-name-quote-list nil "List of characters to quote with `\\' when in a file name. This is a good thing to set in mode hooks.") (defun comint-directory (directory) ;; Return expanded DIRECTORY, with `comint-file-name-prefix' if absolute. (expand-file-name (if (file-name-absolute-p directory) (concat comint-file-name-prefix directory) directory))) (defun comint-word (word-chars) "Return the word of WORD-CHARS at point, or nil if non is found. Word constituents are considered to be those in WORD-CHARS, which is like the inside of a \"[...]\" (see `skip-chars-forward'), plus all non-ASCII characters." (save-excursion (let ((non-word-chars (concat "[^\\\\" word-chars "]")) (here (point))) (while (and (re-search-backward non-word-chars nil 'move) ;;(memq (char-after (point)) shell-file-name-quote-list) (or (>= (following-char) 128) (eq (preceding-char) ?\\))) (backward-char 1)) ;; Don't go forward over a word-char (this can happen if we're at bob). (when (or (not (bobp)) (looking-at non-word-chars)) (forward-char 1)) ;; Set match-data to match the entire string. (when (< (point) here) (set-match-data (list (point) here)) (match-string 0))))) (defun comint-substitute-in-file-name (filename) "Return FILENAME with environment variables substituted. Supports additional environment variable syntax of the command interpreter (e.g., the percent notation of cmd.exe on NT)." (let ((name (substitute-in-file-name filename))) (if (memq system-type '(ms-dos windows-nt)) (let (env-var-name env-var-val) (save-match-data (while (string-match "%\\([^\\\\/]*\\)%" name) (setq env-var-name (substring name (match-beginning 1) (match-end 1))) (setq env-var-val (if (getenv env-var-name) (getenv env-var-name) "")) (setq name (replace-match env-var-val nil nil name)))))) name)) (defun comint-match-partial-filename () "Return the filename at point, or nil if non is found. Environment variables are substituted. See `comint-word'." (let ((filename (comint-word comint-file-name-chars))) (and filename (comint-substitute-in-file-name (comint-unquote-filename filename))))) (defun comint-quote-filename (filename) "Return FILENAME with magic characters quoted. Magic characters are those in `comint-file-name-quote-list'." (if (null comint-file-name-quote-list) filename (let ((regexp (format "\\(^\\|[^\\]\\)\\([%s]\\)" (mapconcat 'char-to-string comint-file-name-quote-list "")))) (save-match-data (while (string-match regexp filename) (setq filename (replace-match "\\1\\\\\\2" nil nil filename))) filename)))) (defun comint-unquote-filename (filename) "Return FILENAME with quoted characters unquoted." (if (null comint-file-name-quote-list) filename (save-match-data (let ((i 0)) (while (string-match "\\\\\\(.\\)" filename i) (setq filename (replace-match "\\1" nil nil filename)) (setq i (+ 1 (match-beginning 0))))) filename))) (defun comint-dynamic-complete () "Dynamically perform completion at point. Calls the functions in `comint-dynamic-complete-functions' to perform completion until a function returns non-nil, at which point completion is assumed to have occurred." (interactive) (run-hook-with-args-until-success 'comint-dynamic-complete-functions)) (defun comint-dynamic-complete-filename () "Dynamically complete the filename at point. Completes if after a filename. See `comint-match-partial-filename' and `comint-dynamic-complete-as-filename'. This function is similar to `comint-replace-by-expanded-filename', except that it won't change parts of the filename already entered in the buffer; it just adds completion characters to the end of the filename. A completions listing may be shown in a help buffer if completion is ambiguous. Completion is dependent on the value of `comint-completion-addsuffix', `comint-completion-recexact' and `comint-completion-fignore', and the timing of completions listing is dependent on the value of `comint-completion-autolist'. Returns t if successful." (interactive) (when (comint-match-partial-filename) (unless (window-minibuffer-p (selected-window)) (message "Completing file name...")) (comint-dynamic-complete-as-filename))) (defun comint-dynamic-complete-as-filename () "Dynamically complete at point as a filename. See `comint-dynamic-complete-filename'. Returns t if successful." (let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt))) (completion-ignored-extensions comint-completion-fignore) ;; If we bind this, it breaks remote directory tracking in rlogin.el. ;; I think it was originally bound to solve file completion problems, ;; but subsequent changes may have made this unnecessary. sm. ;;(file-name-handler-alist nil) (minibuffer-p (window-minibuffer-p (selected-window))) (success t) (dirsuffix (cond ((not comint-completion-addsuffix) "") ((not (consp comint-completion-addsuffix)) (char-to-string directory-sep-char)) (t (car comint-completion-addsuffix)))) (filesuffix (cond ((not comint-completion-addsuffix) "") ((not (consp comint-completion-addsuffix)) " ") (t (cdr comint-completion-addsuffix)))) (filename (or (comint-match-partial-filename) "")) (pathdir (file-name-directory filename)) (pathnondir (file-name-nondirectory filename)) (directory (if pathdir (comint-directory pathdir) default-directory)) (completion (file-name-completion pathnondir directory))) (cond ((null completion) (message "No completions of %s" filename) (setq success nil)) ((eq completion t) ; Means already completed "file". (insert filesuffix) (unless minibuffer-p (message "Sole completion"))) ((string-equal completion "") ; Means completion on "directory/". (comint-dynamic-list-filename-completions)) (t ; Completion string returned. (let ((file (concat (file-name-as-directory directory) completion))) (insert (comint-quote-filename (substring (directory-file-name completion) (length pathnondir)))) (cond ((symbolp (file-name-completion completion directory)) ;; We inserted a unique completion. (insert (if (file-directory-p file) dirsuffix filesuffix)) (unless minibuffer-p (message "Completed"))) ((and comint-completion-recexact comint-completion-addsuffix (string-equal pathnondir completion) (file-exists-p file)) ;; It's not unique, but user wants shortest match. (insert (if (file-directory-p file) dirsuffix filesuffix)) (unless minibuffer-p (message "Completed shortest"))) ((or comint-completion-autolist (string-equal pathnondir completion)) ;; It's not unique, list possible completions. (comint-dynamic-list-filename-completions)) (t (unless minibuffer-p (message "Partially completed"))))))) success)) (defun comint-replace-by-expanded-filename () "Dynamically expand and complete the filename at point. Replace the filename with an expanded, canonicalised and completed replacement. \"Expanded\" means environment variables (e.g., $HOME) and `~'s are replaced with the corresponding directories. \"Canonicalised\" means `..' and `.' are removed, and the filename is made absolute instead of relative. For expansion see `expand-file-name' and `substitute-in-file-name'. For completion see `comint-dynamic-complete-filename'." (interactive) (replace-match (expand-file-name (comint-match-partial-filename)) t t) (comint-dynamic-complete-filename)) (defun comint-dynamic-simple-complete (stub candidates) "Dynamically complete STUB from CANDIDATES list. This function inserts completion characters at point by completing STUB from the strings in CANDIDATES. A completions listing may be shown in a help buffer if completion is ambiguous. Returns nil if no completion was inserted. Returns `sole' if completed with the only completion match. Returns `shortest' if completed with the shortest of the completion matches. Returns `partial' if completed as far as possible with the completion matches. Returns `listed' if a completion listing was shown. See also `comint-dynamic-complete-filename'." (let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt))) (suffix (cond ((not comint-completion-addsuffix) "") ((not (consp comint-completion-addsuffix)) " ") (t (cdr comint-completion-addsuffix)))) (candidates (mapcar (function (lambda (x) (list x))) candidates)) (completions (all-completions stub candidates))) (cond ((null completions) (message "No completions of %s" stub) nil) ((= 1 (length completions)) ; Gotcha! (let ((completion (car completions))) (if (string-equal completion stub) (message "Sole completion") (insert (substring completion (length stub))) (message "Completed")) (insert suffix) 'sole)) (t ; There's no unique completion. (let ((completion (try-completion stub candidates))) ;; Insert the longest substring. (insert (substring completion (length stub))) (cond ((and comint-completion-recexact comint-completion-addsuffix (string-equal stub completion) (member completion completions)) ;; It's not unique, but user wants shortest match. (insert suffix) (message "Completed shortest") 'shortest) ((or comint-completion-autolist (string-equal stub completion)) ;; It's not unique, list possible completions. (comint-dynamic-list-completions completions) 'listed) (t (message "Partially completed") 'partial))))))) (defun comint-dynamic-list-filename-completions () "List in help buffer possible completions of the filename at point." (interactive) (let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt))) ;; If we bind this, it breaks remote directory tracking in rlogin.el. ;; I think it was originally bound to solve file completion problems, ;; but subsequent changes may have made this unnecessary. sm. ;;(file-name-handler-alist nil) (filename (or (comint-match-partial-filename) "")) (pathdir (file-name-directory filename)) (pathnondir (file-name-nondirectory filename)) (directory (if pathdir (comint-directory pathdir) default-directory)) (completions (file-name-all-completions pathnondir directory))) (if (not completions) (message "No completions of %s" filename) (comint-dynamic-list-completions (mapcar 'comint-quote-filename completions))))) (defun comint-dynamic-list-completions (completions) "List in help buffer sorted COMPLETIONS. Typing SPC flushes the help buffer." (let ((conf (current-window-configuration))) (with-output-to-temp-buffer "*Completions*" (display-completion-list (sort completions 'string-lessp))) (message "Hit space to flush") (let (key first) (if (save-excursion (set-buffer (get-buffer "*Completions*")) (setq key (read-key-sequence nil) first (aref key 0)) (and (consp first) (consp (event-start first)) (eq (window-buffer (posn-window (event-start first))) (get-buffer "*Completions*")) (eq (key-binding key) 'mouse-choose-completion))) ;; If the user does mouse-choose-completion with the mouse, ;; execute the command, then delete the completion window. (progn (mouse-choose-completion first) (set-window-configuration conf)) (if (eq first ?\ ) (set-window-configuration conf) (setq unread-command-events (listify-key-sequence key))))))) (defun comint-get-next-from-history () "After fetching a line from input history, this fetches the following line. In other words, this recalls the input line after the line you recalled last. You can use this to repeat a sequence of input lines." (interactive) (if comint-save-input-ring-index (progn (setq comint-input-ring-index (1+ comint-save-input-ring-index)) (comint-next-input 1)) (message "No previous history command"))) (defun comint-accumulate () "Accumulate a line to send as input along with more lines. This inserts a newline so that you can enter more text to be sent along with this line. Use \\[comint-send-input] to send all the accumulated input, at once. The entire accumulated text becomes one item in the input history when you send it." (interactive) (insert "\n") (set-marker comint-accum-marker (point)) (if comint-input-ring-index (setq comint-save-input-ring-index (- comint-input-ring-index 1)))) (defun comint-goto-process-mark () "Move point to the process mark. The process mark separates output, and input already sent, from input that has not yet been sent." (interactive) (let ((proc (or (get-buffer-process (current-buffer)) (error "Current buffer has no process")))) (goto-char (process-mark proc)) (message "Point is now at the process mark"))) (defun comint-bol-or-process-mark () "Move point to beginning of line (after prompt) or to the process mark. The first time you use this command, it moves to the beginning of the line \(but after the prompt, if any). If you repeat it again immediately, it moves point to the process mark. The process mark separates the process output, along with input already sent, from input that has not yet been sent. Ordinarily, the process mark is at the beginning of the current input line; but if you have used \\[comint-accumulate] to send multiple lines at once, the process mark is at the beginning of the accumulated input." (interactive) (if (not (eq last-command 'comint-bol-or-process-mark)) (comint-bol nil) (comint-goto-process-mark))) (defun comint-set-process-mark () "Set the process mark at point." (interactive) (let ((proc (or (get-buffer-process (current-buffer)) (error "Current buffer has no process")))) (set-marker (process-mark proc) (point)) (message "Process mark set"))) ;; Converting process modes to use comint mode ;; =========================================================================== ;; The code in the Emacs 19 distribution has all been modified to use comint ;; where needed. However, there are `third-party' packages out there that ;; still use the old shell mode. Here's a guide to conversion. ;; ;; Renaming variables ;; Most of the work is renaming variables and functions. These are the common ;; ones: ;; Local variables: ;; last-input-start comint-last-input-start ;; last-input-end comint-last-input-end ;; shell-prompt-pattern comint-prompt-regexp ;; shell-set-directory-error-hook ;; Miscellaneous: ;; shell-set-directory ;; shell-mode-map comint-mode-map ;; Commands: ;; shell-send-input comint-send-input ;; shell-send-eof comint-delchar-or-maybe-eof ;; kill-shell-input comint-kill-input ;; interrupt-shell-subjob comint-interrupt-subjob ;; stop-shell-subjob comint-stop-subjob ;; quit-shell-subjob comint-quit-subjob ;; kill-shell-subjob comint-kill-subjob ;; kill-output-from-shell comint-kill-output ;; show-output-from-shell comint-show-output ;; copy-last-shell-input Use comint-previous-input/comint-next-input ;; ;; SHELL-SET-DIRECTORY is gone, its functionality taken over by ;; SHELL-DIRECTORY-TRACKER, the shell mode's comint-input-filter-functions. ;; Comint mode does not provide functionality equivalent to ;; shell-set-directory-error-hook; it is gone. ;; ;; comint-last-input-start is provided for modes which want to munge ;; the buffer after input is sent, perhaps because the inferior ;; insists on echoing the input. The LAST-INPUT-START variable in ;; the old shell package was used to implement a history mechanism, ;; but you should think twice before using comint-last-input-start ;; for this; the input history ring often does the job better. ;; ;; If you are implementing some process-in-a-buffer mode, called foo-mode, do ;; *not* create the comint-mode local variables in your foo-mode function. ;; This is not modular. Instead, call comint-mode, and let *it* create the ;; necessary comint-specific local variables. Then create the ;; foo-mode-specific local variables in foo-mode. Set the buffer's keymap to ;; be foo-mode-map, and its mode to be foo-mode. Set the comint-mode hooks ;; (comint-{prompt-regexp, input-filter, input-filter-functions, ;; get-old-input) that need to be different from the defaults. Call ;; foo-mode-hook, and you're done. Don't run the comint-mode hook yourself; ;; comint-mode will take care of it. The following example, from shell.el, ;; is typical: ;; ;; (defvar shell-mode-map '()) ;; (cond ((not shell-mode-map) ;; (setq shell-mode-map (copy-keymap comint-mode-map)) ;; (define-key shell-mode-map "\C-c\C-f" 'shell-forward-command) ;; (define-key shell-mode-map "\C-c\C-b" 'shell-backward-command) ;; (define-key shell-mode-map "\t" 'comint-dynamic-complete) ;; (define-key shell-mode-map "\M-?" ;; 'comint-dynamic-list-filename-completions))) ;; ;; (defun shell-mode () ;; (interactive) ;; (comint-mode) ;; (setq comint-prompt-regexp shell-prompt-pattern) ;; (setq major-mode 'shell-mode) ;; (setq mode-name "Shell") ;; (use-local-map shell-mode-map) ;; (make-local-variable 'shell-directory-stack) ;; (setq shell-directory-stack nil) ;; (add-hook 'comint-input-filter-functions 'shell-directory-tracker) ;; (run-hooks 'shell-mode-hook)) ;; ;; ;; Completion for comint-mode users ;; ;; For modes that use comint-mode, comint-dynamic-complete-functions is the ;; hook to add completion functions to. Functions on this list should return ;; non-nil if completion occurs (i.e., further completion should not occur). ;; You could use comint-dynamic-simple-complete to do the bulk of the ;; completion job. (provide 'comint-logo) ;; comint.el ends here ucblogo-5.5/docs/0040755000161300001330000000000010276171175011672 5ustar bhdoeucblogo-5.5/docs/usermanual.ps0100644000161300001330000243233210276035420014410 0ustar bhdoe%!PS-Adobe-2.0 %%Creator: dvips(k) 5.92b Copyright 2002 Radical Eye Software %%Title: usermanual.dvi %%Pages: 113 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: CMBX12 CMR10 CMSY10 CMSL10 CMTT10 CMB10 CMSY9 CMR8 CMR7 %%+ CMR9 CMTI9 CMTT12 CMTT9 CMR12 CMBXTI10 CMTI10 %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter -o usermanual.ps usermanual.dvi %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2005.08.08:2211 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: f7b6d320.enc % Thomas Esser, Dec 2002. public domain % % Encoding for: % cmb10 cmbx10 cmbx12 cmbx5 cmbx6 cmbx7 cmbx8 cmbx9 cmbxsl10 % cmdunh10 cmr10 cmr12 cmr17cmr6 cmr7 cmr8 cmr9 cmsl10 cmsl12 cmsl8 % cmsl9 cmss10cmss12 cmss17 cmss8 cmss9 cmssbx10 cmssdc10 cmssi10 % cmssi12 cmssi17 cmssi8cmssi9 cmssq8 cmssqi8 cmvtt10 % /TeXf7b6d320Encoding [ /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /Omega /ff /fi /fl /ffi /ffl /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash /suppress /exclam /quotedblright /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /exclamdown /equal /questiondown /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /quotedblleft /bracketright /circumflex /dotaccent /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /endash /emdash /hungarumlaut /tilde /dieresis /suppress /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /.notdef /.notdef /Omega /ff /fi /fl /ffi /ffl /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash /suppress /dieresis /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef ] def %%EndProcSet %%BeginProcSet: bbad153f.enc % Thomas Esser, Dec 2002. public domain % % Encoding for: % cmsy10 cmsy5 cmsy6 cmsy7 cmsy8 cmsy9 % /TeXbbad153fEncoding [ /minus /periodcentered /multiply /asteriskmath /divide /diamondmath /plusminus /minusplus /circleplus /circleminus /circlemultiply /circledivide /circledot /circlecopyrt /openbullet /bullet /equivasymptotic /equivalence /reflexsubset /reflexsuperset /lessequal /greaterequal /precedesequal /followsequal /similar /approxequal /propersubset /propersuperset /lessmuch /greatermuch /precedes /follows /arrowleft /arrowright /arrowup /arrowdown /arrowboth /arrownortheast /arrowsoutheast /similarequal /arrowdblleft /arrowdblright /arrowdblup /arrowdbldown /arrowdblboth /arrownorthwest /arrowsouthwest /proportional /prime /infinity /element /owner /triangle /triangleinv /negationslash /mapsto /universal /existential /logicalnot /emptyset /Rfractur /Ifractur /latticetop /perpendicular /aleph /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /union /intersection /unionmulti /logicaland /logicalor /turnstileleft /turnstileright /floorleft /floorright /ceilingleft /ceilingright /braceleft /braceright /angbracketleft /angbracketright /bar /bardbl /arrowbothv /arrowdblbothv /backslash /wreathproduct /radical /coproduct /nabla /integral /unionsq /intersectionsq /subsetsqequal /supersetsqequal /section /dagger /daggerdbl /paragraph /club /diamond /heart /spade /arrowleft /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /minus /periodcentered /multiply /asteriskmath /divide /diamondmath /plusminus /minusplus /circleplus /circleminus /.notdef /.notdef /circlemultiply /circledivide /circledot /circlecopyrt /openbullet /bullet /equivasymptotic /equivalence /reflexsubset /reflexsuperset /lessequal /greaterequal /precedesequal /followsequal /similar /approxequal /propersubset /propersuperset /lessmuch /greatermuch /precedes /follows /arrowleft /spade /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef ] def %%EndProcSet %%BeginProcSet: 09fbbfac.enc % Thomas Esser, Dec 2002. public domain % % Encoding for: % cmsltt10 cmtt10 cmtt12 cmtt8 cmtt9 /TeX09fbbfacEncoding [ /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /Omega /arrowup /arrowdown /quotesingle /exclamdown /questiondown /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash /visiblespace /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /dieresis /visiblespace /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /.notdef /.notdef /Omega /arrowup /arrowdown /quotesingle /exclamdown /questiondown /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash /visiblespace /dieresis /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef ] def %%EndProcSet %%BeginProcSet: 74afc74c.enc % Thomas Esser, Dec 2002. public domain % % Encoding for: % cmbxti10 cmff10 cmfi10 cmfib8 cmti10 cmti12 cmti7 cmti8cmti9 cmu10 % /TeX74afc74cEncoding [ /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /Omega /ff /fi /fl /ffi /ffl /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash /suppress /exclam /quotedblright /numbersign /sterling /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /exclamdown /equal /questiondown /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /quotedblleft /bracketright /circumflex /dotaccent /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /endash /emdash /hungarumlaut /tilde /dieresis /suppress /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /.notdef /.notdef /Omega /ff /fi /fl /ffi /ffl /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash /suppress /dieresis /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef ] def %%EndProcSet %%BeginProcSet: texps.pro %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type /nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def end %%EndProcSet %%BeginFont: CMTI10 %!PS-AdobeFont-1.1: CMTI10 1.00B %%CreationDate: 1992 Feb 19 19:56:16 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.00B) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMTI10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.04 def /isFixedPitch false def end readonly def /FontName /CMTI10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-163 -250 1146 969}readonly def /UniqueID 5000828 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958 9E3948FFB0B4E70F212EC976D65099D84E0D37A7A771C3101D6AD26A0513378F 21EC3643079EECE0C9AB54B4772E5DCA82D0D4ACC7F42FB493AA04A3BF4A1BD6 06ECE186315DBE9CFDCB1A0303E8D3E83027CD3AFA8F0BD466A8E8CA0E7164CF 55B332FAD43482748DD4A1CB3F40CB1F5E67192B8216A0D8FE30F9F05BF016F5 B5CC130A4B0796EE065495422FBA55BEE9BFD99D04464D987AC4D237C208FA86 0B112E55CE7B3782A34BC22E3DE31755D9AFF19E490C8E43B85E17ECE87FA8B9 1485831624D24F37C39BF9972D74E6EC4784727AC00B9C4A3AD3DA1C22BD6961 7E0ADAF55422F22ACA5E4DCD4DF9FCD187A566B7FB661D0530454D0DD6C6C50A 7A3875C6CBF8EC7769F32A1F3F7FC1C072BADEC97794D4E90E0035282A170402 356E5A9CD9ABD80AC4342A5283E458A7269252F4541CBB6452B39ED54D336D0B 19928E9CD1AB26AD83EB209E2EC75011A2643813053B5DBB0246097C4821B5F2 C92554E9140BE35B2DBFCD98809A8EC9FC910FDE9E0D86457C70ACB056EBF90F 244DC0A5BBD455E15D6E3180311D52CF50B0BF7D0A7F64F3A1821E0AEDBC2E7B AEB549FE1D51088C153799C6E089B5D5D65E1C4E2D2B430CDF1FFA23CCB25D95 592943209E846E55B4CB54F6658CBA3C0B29796D69D0435D5431ABECF3448C15 98CA2F36F3659E29AEB79355EC2ADF835CF0886C21B766B9DEBC3950B5B3B496 2E06D980A8C60305B273232D4604F12632FB4F1B2F9703952C823C098543AED1 CFB4ECF259A11985F0C944A57B5AFD853374FCF12305601200C2A393E2FC77FD F78C2BEB83AB223A89D9E231D1BB561CE1F4D3312049F31CD544C39354493803 D47CF45482054818E8621801A97461EC7BF53C6AF1C38AC90B38342D51C4615C 59D45B92606D0479F43149F2579DEF5A20B4D7D10528E9750ADFC4C7DDD73DA8 432297E60ABBB72A637231049425393426F66BFC0851FE504E589F13351187A9 D784ACC207B1F46537BAA5F2EBF637EB8DFD9D24982E2631F6D3A2DA47B4E9EA 0C899DEF82A7DEB0ACDCE6043F36CE1F74BF1B00A1EE0765F497A67B95BE1871 A8B3263B03D41ED8BD6B03CA5983912E094E2AE47DFDBF 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMBXTI10 %!PS-AdobeFont-1.1: CMBXTI10 1.0 %%CreationDate: 1991 Aug 18 17:46:30 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMBXTI10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Bold) readonly def /ItalicAngle -14.04 def /isFixedPitch false def end readonly def /FontName /CMBXTI10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-29 -250 1274 754}readonly def /UniqueID 5000771 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE D919C2DDD26BDC0D99398B9F4D004B836D34E88C20EEB527CE1124209388A2DF E27A8DF298A2693A9D529916AA0B2176E6ED237F69D84A8FEEB36861D1847207 BE2BD61C6A412FFFEDFF13AFEC32AC7735BCCE5965F5966418A62ECB99112AB3 3BC938EC590FF6922659125EB67E260BF02885E49BA6019E696D33F0B53606A2 F515E0C45F323311613A94B838491BAB9FE230C5CC79D22925E3D882799F2707 C32975A494F0F9513E4D8332E7E54470D9721FBD345CDBB48286F2F19CC6D66E BB631DD6476A509167A49CA525A72CA50E82C1D08C2B372DB54C5949C753B632 2009B761EB90492ACD3CBE6A35CE1B66F3BC4D8DC36827CE4261A703328451D1 879438479917C1647772999171DCCF1491A1C9086E0C6393506768F8757BD81D 141C46EB9BF507EEC29962A0072B6C5D8C8588F3D68886CD2606DD3BD2FECCEF 63245494E93EEA12AAFB06110E54ADC444C7E7619627A48A464394E5DE06EB46 4C76A2FF010318BBE48B3776C826A265C66515717F7F2E943C60EBAB23D96B5B FD514A1C4E79BB3D3D2DEB936F90CD3FABF7B09FF7F564AB5CF4AF6A40E869FD 395885A88F4A138B3CA6943A2D430BBE43D91F7F17621CAF52FB7161DA3B2003 82244FB6EE792DCA1722C03392C296C029A2DCC5BAAB3EA03F8DEB039DC83AE1 763AAB84776A2CCFFAE9EAF0BFDAE417E8BE682D237FFEDAF224AC09C9665019 165CE32F5349E857177D94AD6396570932E1657ADE4D3FF57A3419946CCD210E 57E5A1D91CF708395942527D127606350924D71BC21C6F969288B1C8CA3404ED E6219985F7301A20621368F74747EAD38990A4C9F2B62913B8FDB93657409FF5 178DAA7C97C35EAFA47778CE03E863303582D8A9900EF4F8DA879DED54BACD7A 4A50C18AA2ED906FC4DC073B1E6CA1E3855AD5B7698EF4A96B77DBE19A12382A CFA8717DE230CB6182F2250885B8E90AC42A66484A7B527061B223A6D1CC72D4 890359E7E04690BFFA99FAB5CC9999F0873A9DBE49E33F79E483FAD72313DF9A 7B7D926461988C23CCE9F71AB7BB63BDB2B10B3F78176380AFFC154825C9BDCE 82303FBFC3B59E070438984C28D12E8655BBBF049125BF56DD2B0DE8C0450E55 82832DA59EBEB001AAD86F2317460DD7ED264611B9043614221ECF 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMR12 %!PS-AdobeFont-1.1: CMR12 1.0 %%CreationDate: 1991 Aug 20 16:38:05 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMR12) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMR12 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-34 -251 988 750}readonly def /UniqueID 5000794 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C 68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 3645B82392D5CAE11A7CB49D7E2E82DCD485CBA04C77322EB2E6A79D73DC194E 59C120A2DABB9BF72E2CF256DD6EB54EECBA588101ABD933B57CE8A3A0D16B28 51D7494F73096DF53BDC66BBF896B587DF9643317D5F610CD9088F9849126F23 DDE030F7B277DD99055C8B119CAE9C99158AC4E150CDFC2C66ED92EBB4CC092A AA078CE16247A1335AD332DAA950D20395A7384C33FF72EAA31A5B89766E635F 45C4C068AD7EE867398F0381B07CB94D29FF097D59FF9961D195A948E3D87C31 821E9295A56D21875B41988F7A16A1587050C3C71B4E4355BB37F255D6B237CE 96F25467F70FA19E0F85785FF49068949CCC79F2F8AE57D5F79BB9C5CF5EED5D 9857B9967D9B96CDCF73D5D65FF75AFABB66734018BAE264597220C89FD17379 26764A9302D078B4EB0E29178C878FD61007EEA2DDB119AE88C57ECFEF4B71E4 140A34951DDC3568A84CC92371A789021A103A1A347050FDA6ECF7903F67D213 1D0C7C474A9053866E9C88E65E6932BA87A73686EAB0019389F84D159809C498 1E7A30ED942EB211B00DBFF5BCC720F4E276C3339B31B6EABBB078430E6A09BB 377D3061A20B1EB98796B8607EECBC699445EAA866C38E03ED7D4F3EDBCA1926 2AF6A41F67AFCFBF3630C943FA111E4CCD988A7363F7C2B75EAF5830B049460E 0D2B337988F150B9182E989E7750C51BA83DF37685483F86D1F47478883F3F6A 4B7F768DA5AA89E8F163029ADD4A9209DE8A4F285766C06EA859639B92CCCDCA F59B1C2BB8D588CA754D1257BFF76B53984DF4937093AAEF79009D32A29A4C16 FB610C7D6713482C48D7F9E8410C0F00AD6E67021056B6035534E79F05D14EF2 4E8009CC91F2665BEFC1CE3671C19C85323A837D78E41C0D3B619F32C0A9D46B AF5290C003A2B726CC6B53A18C7C863274458AF6F23BFDB2FF9702BBB3F5FFF4 C641FE85F5350A377DFAE31DC740161C4FADDDE89635FF7CB78C59CD4F6DD2F7 DE7EC8302B5C600A44879BE4CCA44346BC84BDD67662E2DF2A8B4FD7DB7DE145 EE6670D11AEE4C75DD03AF69593BBA6F016AB3805FC323E54018EA51F2896872 09CF6CDE5E5AD1D0B8C62CC44BD1303B16C4BD1237EA5B78A46CD94085B3D68D 2CD7EC569755FF15E895A303F7A9A9EC48941747E9025BABE7A2A100473D02C1 E70531E914D3D1B992ED312A2E3D4748D081FD5414AA5ACF09B10FC946243575 5CF981BA0F1391065694EDEAC83704A6B1946F3AD85302CE328AE1B7E3E4334C BF9AAD909A45549784BF3FE956EA0C08D2856E39F39186F2DB0A8F0460AA3DEA D33F0FB1488C3CAAC800C3B53E14255A2F00282858ADE148689027A38DD8B7F2 A488E9021878CBB78541806EF17C958266FE3F2A6FCA714AC55DDF253492FC9B C08CC4A46BBCA6261485EBD03B995A99BF8A3D538EB563C965C35BC0DE1AD471 69ABA91EA3D7E3FA39397FA9A243674DE65DD160BC50AB7478C69A5836B54A05 15631FDB4BEA993A2722884E68730DC5756796240DBEFB4FB0B42515DD9532B5 D3FF04CE553DA24E7AA892FA387799773FC457FB3FE7CA0FEFF53A667100BCBA 5C701CDFA4DA70FA583E556E5C2FED3496F695709CBAC5819C3983BBB897088C DA3FC2AAB5CCFE88C014F3EDB288420E599C056D06C96D3196B2A3CE6390DD01 8EDB849F20E7FEB43DBCBBB4E2C1890FD48A295798A6DBC647BF16028FE67A68 2FEB7C2C6766886FAD95FC865F108E0018BD1C0D01B40CC475EBBCBF6787AB33 A08DA6D94AE5B2AE7B7DEC60BFEB1605774B18FE15BA27C7422F2F86DB8A598E C6F3C22DF791912A96CC9BA882F6AF5140E9C2ABA745295D25549068EE07B7BC 84F23F2C40AC800D894E871440214165D5096B547540484F79D15C590D62F5A5 A0218E82E4AF73B4E61078D0E347DB454D096002AA9A9AFC7B62D05A36AB3AFE C6F3DCFF784D4632E824254FBC7A982CFE8104D517775901970FDD5F478C29F8 5D00AEBBB4E9675975FC47B190C7FDF177EBC8157B6EBD61F2AD580407C7C526 C6374EDEB9B4686B14B350E3728DB7A1BCD9BB52B7905DF69E1A3D243DAFFBDA 4AD3EA832DF72B9AB498538B594765E4A241740CC62DD1D585C6C15E2763B162 4F764B5503E3B4AC2EB7D0BCD18B3A8C81F67F2748B329B15F4768272C7CAA69 32DE76116549EC2AE0AF0A0B9A78DD4207DA49B84783EDE23AAB4223CE25ABB4 74D9ACCA23AF9D0E34569593E29EAF19710266724E2EEADDC9FD5BB4D672D3BB 3D750973078E7954BEA1710B60D0B7D694BBA3D3E563D6A3E13BADB33B1F703A C65DEE85E757637D0961DEFABB237EF0044CAE4A74629214F08D52E92C9E8387 6C1F77A51B4CEDDD17BF4871AFDCE72CF1C668DAD46B5EF43723DD16F1DE493F ACB595E4A33D49A602F60E924DA08B9AD04B3454FB8E25A4307A2F3C18735F03 3F094D268845C3323707BC89DD073C12D2A3AB1D860E9071077F1095E1A8AA7C 31420748A50167B809886D799F9F52C60AFD82FD60C38CC6FD7F998DFFE37BA1 AC0EFAD3CA10D10C38EBAD988E61EDA361D83E167E2AB742490359DE504044A7 A7E66239679A4A67448F303D78AD5F1379D1915BA364206B8C832853FC49839A E9C2E566E9DFD5D8BA8E8B0E76A6B6BFE74BA7317200FEAC8E73551A735F8DE3 EC9C1F9C94FB5052BFFC622EB735EBAB04B0855E0AC98F47C095A9AE3DD2AC3B E6386F5307CC461897F8DFD4D06AE76A24EDAC45C20B38379D1AFCF16C41CED2 43B37BD954F77883CAD7E3AE3A9644E2DF4A5EAC68C52CEE6C844601D9DBC7FA F092AEB20CF5075644DB17A1D0392DB09A7A7046F5AA985A0558C2D6AAA6B950 71895198BEF2697226314245DBD649671663D91A6E295B73C4108FFFE1D95509 A63B1D104E8BBAFFF31DF55667734237EA5D37D23C777428A74C7D98D8962DC7 74A356AFF19F153DD6276C1473A2832FE9829AE88F54375789E59E6FA407838E BC8E5BAE85A5C8626AB9C001D49508A7860C81B58EC5595955ECC705AD1AE952 FC1E0882A5A5513CEF97554AD3DFEC96B8D78D79818FAD3F09A570A3F5F42203 75716C970F0929DEBEB88712552A44814723DDA782A3FC38774F3F02136B4EDA 1B1888E6FC6940431F48BE4142B767FADC4E3F991F3EEE1525CBC83B42750AB5 7C53B3AB02E763350E49DCD87D56CEF52DA760588B80AEE81266A71561E9C66A 79268EDFBDE1D74C19995295722EE4B1896CFE0DE64825B41A772DC865B8426E F1ECD416DC0B3CE71CDC5FD19770EBEDEB98F1568610536B96E3661DE5FC7E2F 4107DCB79BF8037E4CF6E9B9FE7F50603F5F5D1D1B6F85524F5C6793C234EDBF FBD5B24E4E41222358232FA6DF2663D1F59BC5C06E242B5271CF4EAE4962E5D9 39DD117B4481D89B4C968B15A815E7E6676E475AE001D3842A46A9B3A709257D 5FE3CAEB7562E8C4E6A84A35D28B6463F284C50016611624D701974E89FE912E 8CBDACAD0252AF4FEC7C68274002FBA62B92E4A89ADBB64717ACA684CAAB5CDA 538E89547FCD1BB41B179B6978B4322CDEA13012F09C2825A3FDE708EDF75C44 4BB5DA90C29F55FF416240466857077B309E4534952ADDD3C034718734D05DE5 1564D1B99B76F2FEC05007D9CF4A1F445927AD77FCFC2CC373A3E2BC3B7C81E0 82042540D38EA0FE7E88E468036DD24F610A493A13BC54D281EA46777D02ABDC C3A5295F87D5807E42408842095B56BE66EE907F29D419D4A4A8DFC1EC3A22D3 03E9F1CEBDB3F7E16D60C0B21ED020F66EA4A07B935BFF3C86E95F55C5FC9154 0C222304EE7925AD3E25FFE78906649FFEEB4D1422EF458BB7F50BF51316C52B C11EFAA7C86F6EFFBECC355B7AEE5B7C035AD439059B7B8E4D05118F0006ED18 E0C3D8C9F27A91A654499FB3CE3B3CA739DA7A2CE4F620B9EA7B2F3808186487 876D6A2190117418841D49AE7313BEC4BCC3CED228C31C9C85A1FD7DCC0F21B0 982788BB34D7CAFB3EAFC932D8C83C61B1E4F340EDDC1AC854BD7887B45A3B24 8C94479F5BC81C9D1FBE7E8595F0C7031C9C0B0CA0D6A84ACFC173096CEB0930 D8A42E454E783175D149DE128A56142C1CDA7487D229D01D6A1572189CEA56CE 07AA14BE847FAE4885496BD388411D9BF61C215065796A94E049821A9218A22C F96EB9E3028A6DA86307D1893FDAA8336E211ECBFE32E3B111CC2D7A64B21281 18125A862DE929AB1118FC5A030A994EC79D50079E7E1EC5A78721D255616C21 AEED6E37C30478A745ADCC7F0F588DA0EED29D9138DE76F74D4F105C8C702A32 9620D6B14896A6E259FBD8348B9DF3AE141DEDDCC4904CE9CBFE72EA1E09DE27 CB2196EB3CA2E422A5E9E12701CD96533C135F8081E848046CD9ABFA4E5114B2 6830BDF964ADFFA4CDBA600E82ADA593A22FA4E4A1AAF6209DBB070BFC8EDAE8 8D0142825C52E0D86706F4C1CB6A44D451AD966D51F2F1E0AEF1E1C6601A53F1 5BB9661D8B92DC0DCF0BFB7E554C90658D0B5A09ECE97B46D210C600016468FC 3D989CC31383241DB17CCE0FB8EA4AACE9C27A31053F11D293484E81C9CD1B0A B900F79096589F1618D74C40C76C01CD556AC2E085978F43094DB7417F779E65 0EA8EF3BEB6B2D0B906A17EE705A60B9F2840AA9D8CF21F4BB0ADBB31B617DFA BD91D4C8222DD852C249189A1FA8FC46B3928BA008845B180590DA83A1BC072A 4A931ED8ECCDE3F898FBCFDB9355CD34EF7CAF40BAE8E928F6BEC57FCCDB23FD B88D3A700F3E3D8CC669F30F154465C8E7422DC4B414125D0B24BC6706E2F3DC 9D33735AF811080BD6D0C106BEBF89B47668022465109B08A03EF5DBAC8487F6 52DC4F24DE9CD81EB14CDDBD1366B76B16637587CC614D963E4225775A6C5A11 D022CAF54859A53C8D886E879D0EB774C9FA8DE0E9E4E1E5C013154266D9F5C3 047F2C1F4EE6CC190B7296E74E5D70A812F8395B340956A032606A2015132AF1 0F8D7ADC3430195517793654CBC383019A51AFCE248ADD20E04C5DC1BC58F7C2 DA9F24B6029FE6563FE79609B8735D40FC08C8A27AC2F215C39F72D84F92ABF3 489F4404ABDA75B731632E0476110B51354EE27C741D4B2C4393471036067556 37B6F786DDBCAE9F75B6814FA142C970F0513A326C38408C423B6D2318444C82 180F9B0416DCE1C1B1DA7860E549EEA669D925F46CF5D4F82431C3890BDBECA6 50F352BEAF575B74F27147B0CA387D194177BE1D957EE44E74778668D42E31FC 42F86F20BC2F46A26BCB4EED31420526F9C40B1CAC2BA683FDCF097ECE0066ED 17D9F5B10AE1D4D96624978F10D7D0C1D610D3E634BF695CDA6C7A1015C6F017 88F6E5971EB3D59B810FD1E5B47A27947CDA94679620C2923985BC43EB2A6137 4E297035BCCC1E0259C032EA29E6CB41086FA00764DD1AC9549E7CFC61AEED1D C6008AB467CC432F4FB12D0730D1C7FB24326EB762E4E65F918B594915265BE0 D900BBA016F224E2CCEE47A4DCE6719CF6012CBA645E585D742A14252A52E06A 03E1BC9D1BBD62CA4EF1299A79DF120FA5F1D7FD9D9B126079855756C25DF972 E16B4CB1EB8B37BEA758A5764205D1EE556DAAFF44E774629FEE232CF91C8F02 DC630A3BFA6502B61A6160AB2FE2E6EFF0C8A8F8DB83022DED8CC986CB4E4CBE 3AA44A627F9B9ECB85A8B0D8224A43824BCE9F506B48B29D3DF29B39EB439A5C CEDC0E637DB36BA83406F31978C3EE82A1D070A4A12DFCAF7BA75988F22ADFE8 72B63A96D54E2492605537549F1C80C5BB7AA7823E0B072937249170CE4AB235 095391534F9DE893C80624B2707FF6DC09922C850195D37CA389298FF431F7B7 F695FE9A65B9758BEE968C2B0442A35B57B8CCD3576C98647A6E361990585971 C16A66430AC9CE131D99BD084BAF05723696D1F750C65989026F544AA70CC322 D60DE32584DF0957BCC442EA0070072DBF6F30E092F263B5CD8FC3C885792211 5A80E63D7ECF7D76508E88E825192B266B14C569ACDAD8ACD9B4CBD17274A96C 1B814B658F5CAFC975FA5365CCABF05C9CEE667F4ABC7704A2F9996B9E968D78 6C0FEBEADF838298023A6061158C9D130767E62FA5E4BC46C2CF7CB9C70A324C 0BF5BB35282AA552ABA9D2139CB284330684D6BEAF0465D1B19B6C6495568307 95406683D1549E2C27A75FCD3CD32AAD920CF1B9689677F04265A412D3DA2DD0 19C799E5A8B08221A9A012293D229416A1970DDDE6044B72DA93DB532EA2C300 AB8E07E66DDD1D0632E59B9D8694256451E2E2CD00A39B9D9A4F93A7E93328E2 EB9CE1E67C548D0B7FA13719F5B5B7EB7FE803420061240A48FB32D96A18ABBD 5D9E29EEA80333F3784CBF9278B9B32D957848054872097F44CA53012C6FB946 0C086F2599B2E196C6D9C13B0E0DD3F8B7635CBE138346B254002DA82F571B2F 23A75A84DA0E872CF37D42181C39D434246C6D026EC2B94BB977957A19F31132 6BD821C0D03E2C5EE2FB6AE5CEE2003D20B445BB9DA195F716E60509F4507036 FE4D2BA5297C511443402A1794729BBC2FA3504F070B3F4AACC8E46C2307262E 8569337387A4902B0DD139A880F6A9F4C63E8A804D114D9AF769A7F704E2B2BA EEFD7796525F6F03476CF473C4457B8A0F27043672DBE65EC79D639254827152 537740BCFD1F04CF5EFE3E116491D15C3EB3F9F9C0F423E51F56126D1BF22BE8 2E570F37698F26EC641F7D0B4AC0876D8933566AFDEE859794DC862C7A9C3A5C 9F2845599F42B77BA24B3C8C80125FAA47688B2A8BE82C250A3818CE9377A6D7 1AF4D34EAF17F066AEFE7AC4A96333CD81FF2EF83D21DBC6902D02A2AE179102 1032D81DEAA0E14D345A3B4D211AB459D8F92FE422531DF5A7277235B320BDB4 A06312764C78C5879007FB26D2DBCFA453D586997B20400FCC09F31C68E5AE6C 8D6A7B176EDF42D3CD5D040E5E5A2750340E9453A9756406FBB9B1A9CBCBF55C 44F3D9F897A6A4A800DAC975117D3DA9D54E357CC2D520DEC0E08A84E44710F2 A9B881276E2F335013C61734C26BE4D53B7F50465A0C37183DF9F3EB4279A264 D9AA87DB174A15124B745788B09C4BBC97C08DFC455E33AEE108FAE9C440B47F 6B1B54457BBC8C3D2E8C26FD16D2BD0D0D4671B6D2A59F08844C1992BFF21FC2 1EB4A8ECCD777298424FE3F0A75021D6D0D7B6995FFD6A0792A8AF1801141AD8 F6867CC15FB89AA6BBB6DFF91958B64AC080D3CE779D418A508ECC5733EE6B09 2D5C373643D03C40C94BE6A3248F03817134A8C65C4233B1D74267999D3303AA 63FA7E11E60D8C0F5079577EAB578CF20D0EE4018BDF4B55FC3ADA074F998521 D0A56C1D3A856947677105EA10D4F535994F640E9D9E4CC8AA82A3AE97B74678 458E77C43EAB26E0EF05440F0C179A86DD30A158210078101B7F89E26E8010A8 F926747FB12FB666DFB26EB9ABCA597C386550AA7ADCBC2954869C42426E8557 AD7180AF05F60806CAB9265E18243E3FAC613A9A5EDA869658B7646EE90A2F24 6DA3B24EBCF548E151D217E2D1AD3688419669A1CC753BD6605B82CF52E86E88 85BF132637180BE0374974ED973F333AB503CF8F48E6E2A24F828BD12FD557B9 249903050120063477438E291C77CA26D0905D5CFBF3058517238F01E2E455A8 17D0D191A762F84C237C3327D9347C9A6CD7D54DD7ECE3F053C16092359039CD 101D1D23363A8E27006CCF69B7CC16CC3A24C0524DA6C661F6ED7ADD52402C64 EE7D407DAEABAE4DBB37D7E21490FCE1FF25734C5C30B997F94313301088EF69 C6CEEFDB6DD12983AEE33DC53787C819931A5DDDE0C2AADF939D607214605A94 7F6A72F3803347C168A86FFE6061318D2CA6484F002905D5399562A9DF268A75 F3B3C90D81077CB8CA811780E80987988C121904CDCB905DA1DE644DBC730FDE 322EBC1956FC9057ECA3D9E13FA17886ED55BBE3C099870F6635C3C5519777D1 390F39D89311D02D764279F7B562DB1CAA4B3EFEB1D3BAC846F144CE6513F197 B5A7647D67171596B515FF43DFA2E4D1CFF57E0F92EF52477817C397253E806C D5AD9600BB184AC59B8A19B5087C5B76BEF3FDF1302B66F24FD3C21B9601545C 989D09B72291ADD4F66AC2F0E9BC55EAA04471C9030A04A359BD60D7C157EA3D EF885576DD1E1950F2354BAC4B970FC3C200A4E7B71F01405DD6AE85FDE75852 C3D178463D4F17546E9DC8B7B35E0ED9A698DA82EBA805EE64BEDAD3232DFD97 0A747A040A7EFA17306E53FD3C9ADF7C493EB6743241DA09B71C0AD8CB254B00 F82AF11E7429F4533004254C68E4CB8DCCBABBF51AA29280F2B722F8611ED4EA 3992F9124E6F033F42420C63DE44975B0132889ED4ECBA0E130933234016D79E 4F9754A5271D2613DAFC2053FBD9CF41EF969895CA546849D03968CB56B970BF 3AC9B1E8FC9D8952F5378C61D01D46D71A37F1B815F5DAA9BE8BBB26ABB0D2DC 379B8AF51D723CD691EF5AF066E3BF95794E02B5FCCA27A0C2C6D30C6797B400 6BE5F415BAD025872C713254914B9936778A448AE807CA175064983EAE8947C0 B2FB168336790553861E345AB092619FD5094F36FDE2E6445B89D0F41EEC0427 D5B81A58627DF291C1B7CAD5BB57850C92CC4C04ACF956F859DC02A150B01A75 ABAB2E0F532AECD05E3E3A6F43255E6CDB3E2E03D306A685C64CC6B7711D33AB 0AC0E86D9EC36474FC0FB23D37C4B391F3EA11E4FDDB905B3F3F418117773E48 A2AD4C77848880C416D9F4CEFB341C4C69CCD1234F30451E0E1E5B2E954C9786 BF0970339B8BC04E7FF8EE65732C299C96715144EDB74EC374E1DD27E8DC460D 9C3B2700CA0AB2A45C247C3B3BD554C38A9A61DB35ADAAE332703930F716852F 059340B178429BA9E80E566222252D3E0D26EB537C29B21EE54F0D594DBFE3E6 2F71EF22E32BCBB86E2CC0715B4CFD7BDE9C63230249B773BAEF6BA5D522E3C2 99D0F240EE41FD2E311610D4213A1BB289583B39F4336755201A0C377C085E79 5BBBA396FF13A9558129A6C5E5F4EAC5C4E7482A861ECA0DEDACCA1A445F9127 C76D424807A2683969C80923EDB9F703513541AB0403D225858B4CA41145E1D7 88A745AEACE66DD9344139547EFE6F29E5A2D4694428D9AFC9AD462186CE5034 108329EBCDCBEA3835E6581DF8369C78E2D575FCD9A0E61CA58414855B906150 796BF66F56BA463C2A5312CB1593F1C7684CC64365EA2BB6897F2BCCCA010D25 DA710CD3BDB307A5CC1BBA81D18482A46CF3BA11D0C2A6AB291D05F4093FFF4E 0C243EA907B9EE1FED1B4EEF1DF48A7D7F863AB22342B693FC0996350AD47A52 9745E6D608CE7759A3C8ACA55344C2677845DCA57694E9674040EE8E4EF31B58 90A95AC7A50B945B4A18956706A3545593D2081466DBF4464CE4F795ED6C9D5F 1519AE16F69E6C6F3D3DED511AE9F6745819366F943194DD4CF7B3A596371964 92E730AB9F8A3BFC4B930C3CE256378669F9860DF52102DB5B8ACB751DA50220 EBD34C024192E71A3F19B58B4109C3255E1AECB9244BB20BEFFADBCC695B18C3 094227993EDDC022E9344476A4B14E9C22D539685B78679220C0E26E0C92B2E9 3EEE404E1C0ACD87040594F78BABCA2DBEC54A5C59C7F50BCCDF33462F1EAE7E 4A1F117DAB79B9EC97AB310EB64B8E477453AD784766D50978B0E725F48D2A54 AACF1CE8510C352A37CEF8BA8CA6A36DEBA425D0B1288E913A81B7801A138249 0ED22FEA20EED9AB139094DAEF3F28CDF270766F11DD9EA99376385CFE10B208 B7604C5537FC93F6CDC6DFF8CCBB0662CB2BB0E7D2207336C8E10C7807FC4235 019C90ED454542F6B4332E7340ACED54CF7246080BC08CD244C0B7927548787A 3955DD29708B6C5E6F57E8BF6204D6008A38E7AD048A576D39996AF7E55DC77A 398D94E8F2600B9B1930E352CC86B3A03AF48DD8592871C5E53810B2D30B0815 831E371E1416031ACF47AB6B797BFCAC2D2703E13C6AE752720F50ACAB224A19 096D67590DC9C3FF91FD9A4E5FF6407E25554F75FA5004C9C6D763F4254A4AE0 A608D5A24A850B013DFE7C96FE259E9EF2EC97279F18E3E8D4E0FB7B8E9A315A 79E4B0BDCC4F15D8B63B9E45E70715B5F54576EADF900730EE0C1C6609E903E1 0A787809E43E86912ABD5B18A82EB77D6983BC556E5627DF48238C6CFB5C0046 B7C93CC542549BEDD84518130F5421B4BF72FCD1319D8E06C5152259B12DFB90 AD0B7CA988B7C1FC3243FDAD1DC8D942CC784A41DE65D6802576FBD3419E0CAC 966AE820104A2278D16B143B0FE879EB2B88ECF081618DEE4D077EE83B411338 87FD5B96B69452D1F2AC7B432BF57D8912DFF8CD899CC99E06DF804DDC63FAD4 0210F37623C6B3DFFBD1B35355E7E59DBAB821675E6742E1F5D4DC7C387D0071 C264719DBB17B8FB5299B1C1CD3E347990C75E92E974FDCB5752C4EFE28D9A2C 4F1A7B06A1F83FC958ED7CC7BFB49BDC0C96BAE761454D7A2913A2B5C74CE0CF AB34FBC35B29DDD3CC65FAF60F2054127DA45371C7A7BE4B4044036944EEA272 3EA24DB741CD2B1AA35139E10ED86095F898C73668568F399A8D90539D8F542C 0F6EA42E11C679AB4E1E519E81F0936A95C55FE590FE24BD8998A887A7E3425C B4BCD830207366454F28B7DAE2B47401C66641E36563B70358B50E9A9429CCDE 3257D593DD21F434BBCD4134F755D10C501F30863085B51BB2154B20058C23F0 4D3EFDB80FD1A19F5DDEB5E197F8916FE4AEAC0FC7AEA29C4EBCB96CE61A506F 455D4B06BC992E2A2855F214A5EBEC0CEFEC8EA859C0F2203E9A6F2C95EC0650 665124CCB4200D74AC113B1DF1F7AED6871169FA29041C1004F2D94788BBB9F2 CF725A22857FF02A6F11821FB5C73FC8EE428A9E2E85CE6F0ACBEBD2368F29B4 6BC25E4E35EBDFA349F7C1FE161BCBC5509B5EE059C8603B501B4DB3A6FF8EBC 3AACD47860179F20223AEBE89F9B50E962619F59E589470BC7844EF7B8081CD4 80BE3C81548451C43BF533424F3ADA61E3F464E2136D9B0BB62CB1234AC76246 8CABF2BED6C3645C9330DC09FD0F69CE97ACBB96B2CC88D3414DB5511DFDFCB1 F2C1E38AD05038D4B147C20450C30D147A77F472E9994102097DF2F19CF6CA17 0E614262624FE6D5D48F90C63A2B5600F1B621BD949184F561B751DB38DD7DFE CAC598ED20BF398B60E23E1BE4BCC5B55B92D93BF04554A9937F5C853738E109 F9C98B2FEF1E30413716F09408CC997475474A85128E9CFA913037068DA13F9E 9A48AD596D6EF6CE16E8CA7E3042F670170D5AFAF30FAFBFA2C59CB99F0C34D7 106676006DEBF76A57A558C4FD1A72296CC2D96ECB37CBE3DC02EF9BE8D33453 79BF6D03504F92C8AB8D10EE5B63044840638B0E808CE35155845757270ECF69 0372B77A0F71CAD1897E09F3A5B4DB643F90280391ED754758613065889758E5 1D8FEA545CE2B389D47CBE996942BF4E71339F3AD4EFEE020BF91CC0A14E51A2 96DCF4FCC2B77A03964F4A529B7C559E84F5D66755EE8CBAA5B6F3C1D9E04D4D 7C0CF9C70D478FDF98E622163F8ABEE32A2C6CDFD7117D91D18297253F157FFD 66A2ADACB19D30E0C185DCE8AB57A084751964C5CA7931F917AE32BBE0227A87 9336778DEE190C13496772D11C89B788CA93C4CF1F89DD223C4AFE4FD7704596 250AF47811B9CB0C44F8D650D6CBB24429E43CD5C52A468200A316761E02448F 8EACFBD89AF04B25B91D704F720B44C401D144405ED086ED9616079F38475AA7 6B32CBCB3DC4D5C3EA974F600DE736664A6AEDE7BD5D926B6824D85BA1B8DA25 C27EF4A46E1AEEF8FBFAAE80196EDFA8E4ED0F4A778226D4CD98AF85DB13561A 19EE91FC50242538A04CA7C9E82E5E1D6A21D80468DC5B294584B2B13A85A18E 7DD6C75021143F2F40827F16D110EEC9C57E4AFE56AC734CAC7AF5DE78FD69CE 443C6FB84D6EB37F3174DFB5EA169AA6E9738AD5C217A3872ACD87290497C0E2 F30D59F3DA89EB4F9CD3650F815C6ACD49873C5DC2B485AC169C71F480A08460 D8568771975FB1BA8A3286AB4F9089DBD6950405E9800C914FD624121162716D 34089D3E11F10A1D4A6029B1628EBF3419CDADEFF8F762BBDABC190D2EBA86DE AF7BDA785435EBD50819FB68ABD3C89AF0EB414E5D85CFD9B815F74E3C90CB15 A532975FBA91BAA45745CF4EEAFF76A78133DF4DA5CC7DB2C5391C77737BBEFF C68DC5B63989363CACC62FBEF0608CB01CFDCD51234C8AF87D0DF4EC8ADB2F71 F8DDD30C864647A94532F38BA1380980E73D780D4F5DA4FDE6A5B4765E4AD250 BBECA9301DD00F2BC6172FD82B3DC18A867BA8648691BEE53B7AF662E8E916D5 787E7E493C80D412ED69394A6041B5242C75F9944810ED552E5B533415ED516D 0EBBD2FE4DC3301E48A22194D55AAFEEED32D924CF83B5B6EE5A6BA1B56C8134 6943E4B0E28F3A335897E4E38FA946688B8318477A290A57825C3734596696F2 8064AE8FC52654C07466B57E794F4CAF2692DA961A0DD220F80181F993548BFC B4904D8C1953CDBA779DEB4E7E3EE134AEB36E407F9162743A0DC4 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMTT9 %!PS-AdobeFont-1.1: CMTT9 1.0 %%CreationDate: 1991 Aug 20 16:46:24 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMTT9) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch true def end readonly def /FontName /CMTT9 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-6 -233 542 698}readonly def /UniqueID 5000831 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5F00F963068B8232429ED8B7CF6A3D879A2D1E 2931CE5F5D18C658602059F07BE66E6EFC9239D7AB2FB8A4CBD41675B8ECF279 650C29E53B14AC0E392A664848C1844B1CECBB2D5CFB72D0916B675C9A9A1E35 F12696A6F628473C604A95376468E06E295AD6F76CEB939D94113532050B9D5A D2F41A9EFB9424D986612313B89EFE9C8A71313340B248F6853B1EDBF02B7F9E F447220FE131D7D54CFB8AA1281DBAEA73E665BACB1F164552CC0CEDB63BD4B1 4A9AE8AC6FA02242DBE8DA46B64B6BFC11762F0784F216FC8B9120D688D1705A 438B14F5E5DEAF2A98408B3B64620DE3732A4DAE6D08D5D97E34C75DAE19EABD BA0796165C1151BCBFB1DF8D29A63A8300DBDB9E3323CB82D0337598B83F4F2B A97CF5196D4D1CEC1EDB8966E548C0D9C194C932319610FB43EA1B86322FE641 AB48770FF13BD475A7267E142388563D1A400419C585B22A9886074687BEDF74 D905BE8EE440BA2ABF28EAB673399B7F129B9729DD5564C681954621903B84BB CAF89AC5ADB2932472DF29ADA2BDBDB4D05F65F28F5F4C529613D61858E0074A 082A852710A62A147C966F2B85B51B0BE85F11D2057C66FDD61F6C5755367980 9F4DE680601D4DA41B46F8D2148450000413C27AA39B586B74B977B25F0FD3C0 4BA1EBFAFDBEC531EA13DFBD6700E53818CE04D23886B8AE75DCC36BCD3189B1 0D55FAE27D0D126E82AEF31D7B5DF27E58C30BB0867D6D7AC1DA9EFB8A2DF095 B5B934A68EE122DA0A83B36C952431586B957990206194E89339048AA6EE4C53 703763505ED57C494DD907D0EEA04F6B1D4C8F3BA778F4E7AA832AAB4D75F024 61E91C6D25FD6823CB24FC8638C80FB8764AC39D0E204B16C196C51D3C4C6F13 A756F09CB41947B7EA53DD703F545B682CCC2D877C073A86D80BA22041CA6BB0 474D3CEACD3B25AE80ACD0C977B606ECC64439B44E125AE7D78C1A884C57C77D FA1FAE2A242307DF52AB0D7AD075BD97DF34218721DDA9CA395339A9D7EA982A 9167DBD2E9BE841ED480F6EC6A3F026AD05E979D83F32C5B26DE2D78A450F9FF 3661375D700B54727AC19E9DC14FB037ECA4A063390118042CF6C73C4C78EC8E 67C77058CD52E8C2CA17229B932AF521E98B86C4AB0380469FBC9B8B295DF354 641DDA2FFBC423DB542361864A207FD000D2630F6BADB939C3D18F240BB4072E AFAEE99FF0558F171AF9CEBE9468590E03EE8067266992F2BC543EA1B97772BA B0C0D35A643E25A98D7D4921D3C01CD0C88E41DFEDFD0F4696CBA5BA06DE70E6 294E714426AF1F827D801CB76B5DC365F1E448BB43703CC690D01B0587D524CC 8E334EF213BC4493E1EC0938682A1C124BF1F2126CA517B40A0524C0CCF315EE 1D813C5C44971C8E395C0915DA27D4F977E5F9A45B11CED06E0E480F2332EC93 403E71476E1AA5FC540F7A2B09E6FB9C6CE6EBA9FEBDDA7F9B301C927F774557 72FB0FE5760A77608F1064AC8AECC88F387C5D1688DB9AB620F55AD0CC53A2A8 A7A69E31410B3B0E3DAA5E093D92D149DF0E597ACF908642DEBE1AAB3565D17A BE2238C1B804F772F17C0A692948EC9391F4ADADDFFA5DFE31251BFE1038B795 60251BEE891E2F59CC3EF372217866E2910664B104625417676951F4CE6507DE D6D629DED41D1861C10DFFA4C3AB766F2FC58FC20160077363522D288F6930EC F49515FE9C0101425475504C2A9F127C55E3EDEC613C788416D3A0EF05CA0662 5EE4FB17EA6BC099604103D8366384FCE536B542A7A4C497A68986950E83E0F5 7962F0904128A16828F587CFA3DA7A40894E65B82B254FF21859ABF24F264CD5 3B0080601D9729C02FBD790BD663C59CA964F0C73F0CDA7995D18EFFF25DAD83 7BE45D5B587B9E9EF4E66D02D164C41AB3D804E6056E12277A20B83CA29D14D2 6C4C79CF9B074B872D17715813DA057073EEADE477C72D5F897613D675663FDF E460C9D3934B139A58FD8DA102623E8E69F9B64F9F7E855E978A4A3C17AD1523 46CD32C932E2A2724DCEB6952ABBA70B9862027EB98D53E7A774BA6AF802A6DA D7A8918075713ED573B731C38B2A8DE0E0954838AEFF077D4D7C4A52BDD36901 CD0BFE8A65418AC7D5F878675A5A35283F0AD50A80867AF9A2CFD9619DD9AA73 E8824BDC1F6ED91ABC6B136EB61AECA7182DECA1A81CD110C276558A389600C2 83DA9F1122916978FF8CD48967ED2E3E27044DC398EF63654A0463376AF8DB2C 2190A757EEFF9D74DC5F624D24FF5ECA39A99C25066189DA2D725BD9EB33D0D0 1A85762023721D9A7C3DEB78A2B390EF52EC4467DBDC5B3FA8C9493A2A2B740B B7B6ADCC7BCF5EC76659CDF64AD46086DB752754D81A971F376447EC6EB14EE1 2DE60D92649C81B938A8BD130320EE0C3B8796345CF226E3926A9DCE3C1B1B81 12D67325A527DBFB85FA9783CAB10CD32293C3309D79323382F21C1D1E3C0DEA 7E57C9298387E59E0F55554A84E694497F801BF280FE9D8C2BCEF66E174CDEDF 94BD0E0C0356172AEE8342A392BBAF8AF2A2DE0BC540784BE38DB32DA791FD4A 081310D9F50C82C7CD508C547B992B1AA39132A63616A0CEBD6BF8E0670B991E 85BE27595CA7141F9199502B5AC0CB9F4298142966D832167CC5BD4015D79748 0563F2D702B2C69148D6893C42B1F6893034A36149811393B79078 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMTT12 %!PS-AdobeFont-1.1: CMTT12 1.0 %%CreationDate: 1991 Aug 20 16:45:46 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMTT12) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch true def end readonly def /FontName /CMTT12 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-1 -234 524 695}readonly def /UniqueID 5000833 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5F0364CD5660FE13FF01BC20148F9C480BCD0E C81D5BFC66F04993DD73F0BE0AB13F53B1BA79FE5F618A4F672B16C06BE3251E 3BCB599BFA0E6041FBD558475370D693A959259A2699BA6E97CF40435B8E8A4B 426343E145DF14E59028D4E0941AB537E34024E6CDE0EA9AF8038A3260A0358D D5B1DB53582F0DAB7ADE29CF8DBA0992D5A94672DFF91573F38D9BFD1A57E161 E52DA1B41433C82261E47F79997DF603935D2A187A95F7A25D148FB3C2B6AA32 6B982C32C6B25867871ED7B38E150031A3DE568C8D3731A779EAAF09AC5CE6C5 A129C4147E56882B8068DF37C97C761694F1316AF93E33FF7E0B2F1F252735CE 0D9F7BCE136B06EE967ABE0C8DF24DCBBF99874702ED252B677F407CB39678CC 85DDFC2F45C552BA967E4158165ED16FECC4E32AC4D3B3EB8046DCDD37C92FDF F1F3710BB8EF5CA358ABACA33C7E5ACAD6BF5DC58BDFC3CF09BA2A38291D45A4 C15FF1916FE2EC47FDC80911EB9C61F5D355BEDFC9DB17588547763AC5F0B1CC 12D2FFB32E0803D37E3281DA9CE36C5433655526ACFB3A301C56FAB09DF07B5D 048B47687348DEB96F3F9C53CE56DDD312B93D3918CD92AF53FB9461864D11B8 0138918D0B1270C54873C4012CDE6F886DB11BCEA04B023EBB43E0D0A06BE725 741D08B9DB688731A6C9886C15A83C28DADCC81385EA239E045E8F3670CE03DB 9EE77ED067036595C9F3B1854343BE3A12E486B6E5A2F8AC44FA5378D28DCCEE 306B0E283AA444423F9A4FF38E2B56DCF67A39CEB2C643DAE86865517D5D0371 CB8797208ADEC637330A3A57902C9A88EDB75A7C16FA9850075D9F19578EC666 1353CC1FC512D59DFF847ACCD66E868716B07631ED493CC0B5CD5121D7405B70 46180C3F093DE8582E0264F2561E51B8CF943CD6038A98E9B7FEEBB2C6679953 E695CBEC156141F402DED0D9040E47DF588A7AF7AAA5689693F40FC1F8CD1D95 4F5F1A74954C9794CAB33B448ABCFB799166A17E5F2B607B229C5036AB58C28A CC628E6D3BC4230A54039B13CFE89FFA25BE91D49925195024C51CC0D9271366 F8BAD47F569F5F5EE551D699A8D278A09836FED40313BC0BF1E6655AB09E3CF5 047E149FB01475CEAE9D40097993B5AB7E5FB47C16C2E98382064F78D987791F A8F6F4BEB835408222DCE6C3B5CE7F68CFB973C8E2A70A9FD370068F4E6C2829 0F0F035CF3AB378D45C95F718C68986A11420CFAAEFEB81D57B1AC3E1D5E72D8 880A97C8940637DAF162347236AD0D5BBC81455A5A21C32E8E102657D154EF28 A62FD2C329B75F849924E61F1BECD4EF516DD382DAB0A20BCB099CA0EE9EC643 EA36A203BAA0F65D8B839D0A31D63E944E7DD27570604EA67EEDCE6A59CB05C4 FF672F2E965E01EC2061C348B445DEE397549D9D7FC4787B2A4BF6494323564D B86EA7A26159B9AD87FBB18BE7D388B5CB6B41FB4538B1C28805C6914090B27C DCCB079B38B2884454DC566301D4A9F16F03787CCA15E7464CDCF861A90C012C 6FB5204B72F9F522961DB9C435A39D612DBA6C4FCC51231F651C91BD0B0724B1 3D8DA4 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMTI9 %!PS-AdobeFont-1.1: CMTI9 1.0 %%CreationDate: 1991 Aug 18 21:08:07 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMTI9) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.04 def /isFixedPitch false def end readonly def /FontName /CMTI9 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-35 -250 1148 750}readonly def /UniqueID 5000827 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958 9E3948FFB3DF7BFF10C9BDA4EFE5F68A8CB1526990D1357AE6D2F7C2D2EF8496 4E47B39E6712EB8908A3265E5FAB40567E866C244814449F1E993AAB422C3F1D DFA8C7118584F2E5197FD4BFA3A8AE9E953C6CD4672C0FF51E41C3A919749C1A F06650DF4C5E17492164BDBCDF22609A74BFA7F69960A64B9F949FFC2A807458 8579366C4F41BDE1FDFBCC4845FA19BBB6963D65EE8532549274BAEBDFF24FA6 03235D1BE37C06B1938AF369DA75BF38DDBC87A1FF445EAA16E1895ABE9506B9 211955753E447865D33CEF007391D2666A046277A30A49804FFCED3FEA5EB2C3 E52EE14A9F75241EA10C91974CDA6236EB840FD44D6DDE4D9B3266C3B99BD38B D835BCA8CB819C073480FB972CC028D218F6A1D344CE1B63F4FBF2C826F412E1 6E0B05A26125865A14FD7B7030B478BB8BC6BC395335C3BA940E1C348267F4F9 0AF97BBEE253511940F1048E175D3569F7D05A28851B6F50765FEB6C9654FEDC 1BF52F535DB5BB90C1BD5D2EBF75E0AEBE82B20507F3C28A03746781018D4EB2 298E4F2C27ACF73FA73EBE43F014BB575AAD516C0407B29E1653375135ECB74D C91372F06FA8EF37C31AF3FA48AE65318EAA6C34830A5377ABB2DFA5DA53A574 433484BA1466709A4B186761655C8E482833B697673E847C691079E7F1DCB8D6 1AD91101D757B83E2090337D525AEECB028FB3C9F6A6E6AD2F322CFDC5A833E6 1CE4EDBF41FD34FD61630581D222F854A76C2EA9FD72796A7C9CC1F6C2FCCD16 E95CA05826A4ECFADA6A5FB83C41A7131E52BA6585DD6DD78515D8F7327DFC6F 9404F89293D6ACB433CD0802C43F0E74C6C4766A23A6AE3788FE6CAE82E1A104 BAEC8BEFDEFE4F292F625E60362F3886F602CE4121BF0AAD93526314BCBB5971 40091A7BBF7EFB3BA355B88C897D9C70C841DE41309348751EDFFA8675215988 49CB1599834A01EC6CD4FD813AFF97A614F56975775D5F48E9C1A9CE532FAEB1 4EBE20C3FA87CFE03664C428BFC5C894668E507950005BD8C2BCA8998C1FB92C 4E6B791BA05B79F332EB8AF5B0F851B8B7EE372EC0861B09C007CDF43F82D0B7 35446F682A0DA7F4112CDABE4F922EACFCB7B8C88BF550B60957E7 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMR9 %!PS-AdobeFont-1.1: CMR9 1.0 %%CreationDate: 1991 Aug 20 16:39:59 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMR9) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMR9 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-39 -250 1036 750}readonly def /UniqueID 5000792 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4 87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0 92A36FADB679CF58BAFDD3E51DFDD314B91A605515D729EE20C42505FD4E0835 3C9D365B14C003BC6DD352F0228A8C161F172D2551CD1C67CD0B1B21DED53203 046FAFF9B1129167921DD82C5964F9DDDFE0D2686875BD075FC81831A941F20E C5CD90040A092E559F6D1D3B0E9BB71733595AE0EA6093F986377A96060BF12A A1B525CD9FA741FE051DD54A32BECD55A868DD63119A4370F8322CCBEC889BC2 A723CB4015FC4AA90AE873EA14DE13382CA9CF0D8DFB65F0ABEDFD9A64BB3F4D 731E2E1C9A1789228FF44116230A70C339C9819676022AB31B5C9C589AE9094B 09882051AD4637C1710D93E8DD117B4E7B478493B91EA6306FDB3FA6D738AAB1 49FBB21A00AC2A999C21445DE3177F21D8B6AAB33869C882613EA6B5EC56476B 5634181ECBF03BFEDB57F079EACE3B334F6F384BDF9D70AEBD592C8ECF21378B 54A8B5DBF7CB9282E16AA517E14843909339B5E7C55B038BF3BB493F3B884A1C C25F9E8FB912CBE23199AD9D2C3E573727701BA301526C66C3617B9514D6F11F 11930B1D97C17816C85B1BFD9B973A191B33CC3B391815AD14F1CBE935942AEC D4004E6BEF379066FD72209DC88D2E634E79BCC2B98C766CBD92C561F2703F8A 109E6C6CEC7B866F2FC7ADF646BF492E520319F3B949AB5D84AE990B33344A40 3971F58DFDF8D8D67FA0B8F2A0D884F8C09A5A721319B911DBA0A35903877343 C37BC36C5EB32353272D1E6ED5FCA611BE319A7E1E842CB7576E7B1CC7164603 217D560459B79D0A32D54DEF436941A031B79890EC4E79665EE86288DBB2EF22 402B084AC6F6AA8F15B00E49F460F73F1C5F3ED9C72F50DE291D8EF702DEAA4D D1B88DDFEE8716699739F6AB234CFC0FBD23D9066B5C36061F9CB7E0AD68058A 2D803731F21C1BF4545A60749CD90FF7216D4400E1712E4BC28E35879FBB20B4 03F168C6183FE88CC2F9B0FE9D0FC7FF622F6A5EECCAE72EE359D135517BBAC1 BC5F25F2C698287AECB18169C0066185C489A59AD54C74EBB28E60BE2325F577 00EDAA585DCD988532FE998DA1E9E2331AF57B2A25BB5A19541CFB58711A5CC5 E7E43B32E0A5D282E55A177B590FDD61E2DF1AEC4F0E5DB698E6AD7CE7E34E84 1027A9D6C1D15CEECE83665514BEF06A349D07492984FF3BC84FC39316295DD3 B1725CCEDE6B098BF6C1D188144EA2CF3A96BB6063C536530C580D839C5DB5B6 9000C276F5B9CC11C2AED40CC7BE949F4A34231EF55E0D61F72E7EF4F93D72BF E175F2A763ACCE3FF93A424DB06EA2ADEA41F7DD249F871CE263A44F381FE7F8 A0DF58A17BAEFEC34913426B407A8BC709B49D406C31DFD3AADFE90FA81F4EB4 263407D08D1523CA35E7F759828236783B03D35DE57A14D0761062F5C4125BC2 44DAB1959D51228A25152D709DC4C87D37DC5420215D57EC9E48ECB240F696F8 3F4BA473561A4F5B16416DE33C2A71EC2483DC912F9CF6579DBD209A3F555132 4CAB0D9B7617322C107902558F3A64A69259CCB16C4A35E0ED8249582024BFD5 38539DDD87F37C354B79E20BC72007D6C5AE9FE1B7D9A095F4BA38D34DC00CAE 21661F1697478543A226433B1DAEA46EA1F3E60170A7B77E532BAEA2BEC4C9B7 E00DC87BA1CBA3BA8778905EC052313FF65FEE3B570F9C67EA774ADAD700CB43 BEB4AD6DA9C1ED1122734314DE63DBC1397DCD48E533DF8B4F5ED0E19374D8AC 5429777989C7B4F2F61910C4BE63EACEF4A0305E211F35344E056AB80C8472DB 9C75410FB2AC0BA7F12E70207AF0D86D6698AD445EF73BBD59630A90CDDDA764 82D12C80AA6382AD1344705C8E3609C9072EF5D56636FEC667D788950FF46BB7 3C6195E931E337D5C3D7418BB6E597733EDD316E151E2089B6C056A673A49628 C262D413746AA79355C8DB1B8AACA7A691F7293344E4090206AAA1FD9537F993 87B8AAB1069E86F2106ABA434E7755C1803F4DCB2309E650B1A21AB6F23645A2 11FF449260281DC2C53EC6F36B14247B72DF4F5628D1A17F402622CD181F9799 A19573691ED035B6F9D559E18A9327CC600C18DA6516E3A07C45EA031F9D0DC4 7B60C0E03A55CC48F43DDF1D23B18D6EB2445D3A0F147BD466DC41F69A0D69CD 37DE6A7357D3D28CE8578F1FB68BF440958DB917E84EC22C2DE10009F0E02020 C367199BC78C16CF53F3A97071751ECA66EF6FAB1BD08F883678A2514BC2D98F AD132FA3E046D711E78490F6AE885BA5AE63F7BB7DDF4C2142A545E26BD851EC 587F580F3A4988771EF4183B6C7B8B5ED9722084D1A3DF21D87867D76BBA7854 62731B6820C305705D3CE663B86D359C7944B3FEFAF9CFB54791DE9A9F437434 9D4E75769D40AE83DA44E877EC3AA9B25863A08598F69DA81E2AB5894F0D8BE1 8608D6F05237FEF536AC91BACB89BD0B074D76A32DE81853DB7D85317CAA03F7 7986FCAB3178507D2D762BCD7406ADA992F784BCCEC9A39F29590C276A1E7CC3 E7494B103157183859AEC07D07171C3340BAA5152E54C07B1B020EEECDD01934 17E1D54172A0F767805068760258377DFF1B6D48A2D30C662A9D1DC7251008BD 135E3C0A8E0F9AB01BA3CBB067DA117142572C2CC82CE3530624E4BFF2FB27A4 84651799E79C39A9787AD34DCBB2CF415F2805785E210670659B396FD0732158 876147A0D1DF48AD7555B4D89BAF3B61CF2C4D73B02AC4504B0709C3E38FEB54 B4E9D8CD7328E3E4DAB591F202953C02244D9D1495C3C7F9F7057243C9CF4439 560082D8FDE69EEAF71B78175CF0A69183D730E44B30A5C0EFA23237EC1C371C 4F8174488338F1A41EBD96712AE3A6D2B0F8C70EBA0ECEE82DC0A1668E0E512A CFCE57DE08F31969845D5B38F1E1B06FA997179B994BF59C960ED48E5241C18D 75D940BBD974104D16BBD62A3A2066983307FD3C2819136157A823A90BA04EF3 145872353096FB5ED68681D1C0648E5E577FFE0EB7909F4AD581B7EDA52CA070 24D382BFEE8D8A69EE32D479D33F2DDFD560CC6F4A53C229C21D6CD159ECBF36 13569A3E734EEDC9B968C65E02797681503B13A6CF9A8C37FE8D3065E8D6A380 240BCABEBB6ED6F3CE99A059EE0C015A882F0A5DF23BEECB6E65F7EFB6585938 0B6FE927F8118518025B2109F5C22548ECEC2508770C9CD3F05DD445D32138C6 C26504FB534631F6D1FC260A408714B797E49385845943E80E881A3203DA3E12 5B229B503B9B032F767568A1E36FFB5BFB6F6FA6B45B10DB32D939653964C153 330CE3AF07BAE09489C8E1E029A8E41F109BD907BD4BDB1B0E4427875DC8FC70 C0D92AC97E507981E7DFCE7FEE0F4CA528C5D0D8E891761553B7F304E0AB3267 8E78157F2847FC702CC646B4FBB4BDE9D6A79C277C2172BB5342F778AFCEAF55 93EB04BEAC222830C14E263C761D9B8833FB9DBCD08D724DE0C5AABE6FF98A14 5F573B14CD34272DA90DDB38C277F910D2CB4348C8D85C79F10D8BB0FDBE05C8 6EBF04338D967682A70B8BDE69DF0F3276E0D4B37DF257AFE465966B29D8B92F EB3CA39AECB734A1BD4BEBC13985E48A6A8145C34A6F267359F6939D6E50FE8E 088BE91FA3A6142AE9599029EA9C157129A09198676285884B34449F1C996BA7 EC275C242FB560C8999D6F4635F32A4DA068CB91A82F32C13BF62F97DC5030E1 073C8C118BE2E5092CE2BB887A839579C1F0149DA926DC5DA5C415FF4C8A7705 BBA591F0D899F7F9F1D838A773461747ECA6A58F04FD273055497DE4C2F92FA0 47818C7118D337E07BDE6D384A90792B79A933F4A1379FBF6B4569E19132DD44 2BEE2D41C0873D40E21EA0FB52759DB505B1F43378AB5E6613E478140D1EF408 0A41E95C675B27F434B91C30B018634D65F00D44CFBC29C2C00505D9B37ACD89 0ADC5275CE745FF59208F01EEF4E6087D1DD45E473EFDC117DBC31EB9ED7426A 9766DDE370633E1C88B6697B749455CE4347AC9FAFBF2001270BE9DD4818E180 E789067DDF0638D45185B4124B0341EAF106DF848EEEF0AD43F8CBCEF8312F26 0296C69144FE3BDCFD11899A6042BAC931AE459AB61732D39E09BD77731796AE B465338D6094686CF4126B37325AB26FE1CCBD1C9BDE51717E5B236A1D2F28EB 746C4B6801B507B94DC47B3BB085139876DCE645DF4171AAA54588822AD2F630 AE9E85D174928F26D2997D82A51F3FC336B0FADC846129DAD0F98984FDA289CB 4A56906911F0C3A91DB63DEA95759D962FC845469960E11DCCE0E4A80D13B172 3EE2B12FFAD104A7F8AB081E5937218D184AAB634D9E36E65048B7C85268981B EADFF96044C6DDB138A89B86CE19DF95F8AEE3105258E5FEB711B3862F536FC7 E62AF50B984644701C9F9AD3B59471767BBE2FAC02A4DA519DE50170A7B4CADB 3DB9337CFDE1F2C7798517EAE440941F77A92CF7D3F950C214854293FCA108B5 920D5A854E6D559F020DB91F433EF8504EA56C9C22BA40A19A88DB7DF8C62963 223DF25965BD3755A47EE8FABBE1C4212CFA63B9AE9503AF72F0D76E11DED952 718D7BC837A99D1E3041B13A7F45843E43A7D94D07902C4812FF5C532BEF94C2 AB717BA82FB87DAF6FB14BCEECFDDF882D3988CB1696864A48F10C3F96928AFE 49894ED9B72AED37071BDA4484A3DBF9B997953D3D856882BEDB85B0EA8D5778 A3DA75128679B9AD2FE5A2D87D60B5641912FB633A40B488E67C158947D9340E 32862AC361099117ABFF784BBFC9BE0D2BC7F41D0F93C954D840B574D91D7919 E14C544C3528005337D335B31155C14FF32B6BC59F02D125EF55F88887B7361D A70ECFA0F6D7A0EFAD3D3CD4A6F9997A82F0BBFB3FE8C282980C25064628A64B 25248333BEFDCFA03D28B296E038DE51BE6D4F269E427BE425CC42F042C0D866 979F669D6B1AE65BFBA110D3823B62AF57187BE8903FF9562218C2F707B8962D 50DE147007ACE9EF6DDEA40D54B98C4028E21A4BE98C9C52BB1BBF00DEF5BF38 752076F64F5949577411CCE9106BE8993B2540B1793950D73DF606E44840AE7F 3BE88C01B006C79EED6935B07AEB6264AF10513CAD55F56F601709CB8B0B98B3 EF1DE5B3C99C633CD0FE710A722A4D0A6206427CDCE10AABB30D07E9B020CFB9 357C44750C877A617B6E5BBB4A174058E35BD97755E6BD75661C7C1622DBCB05 B245FC8E5DABCD1797DECB5990BC9F8C7E126B1AA56B7E0DDCF72D421CBBC67A C4D0C800B57E7DF8A93A5817A7F3F9AE5EFE9FF111ED741B61A57AA3BF881B1D A812699EC7C7766C47F35F7F1144398477C8DC95F5079349BCB661BEDC03D2F0 3CC781C0E5A32C5907D6CFA169B435F7AF7E87961FC230F51FF2749221906D56 54B7A6B1BAF6138C21119EA17C6A26B113C0245CC1CFE99F9388B05A6E29937E 2156D2E6AA3EDB68EFB225D9DA448F625C2FC5E606952ABC88A91BE6221DB8EA EBFD7FBF69743597E4692377CDD3570E5661BBA9B474F2EDB759E6D20DFE7AF0 8F0EC0609370450FC334C5D6B45614E9DA5CC1E3EBF9B86B07860CA3EA71E77E DCCB891182B81CF52FCC7CA3BAFA67FED709A5D61FD9675C4BB57CC2B0EB2BCA C5F3B2882884579BD324404A368F21BF0CC2C74F6E9900B6F14B6BAAD579FEB4 A7481C3988D6C474C9A2AB75D951CEF9879B354685ADF63162E4E69372B08EA7 8D19F9BFDADE6872CCDD4F67A6838A01624D93C2BFAF9121E794ADF822157F2C ED4A6ADB99816E63001C36EC8AC055D490178430B1D5E3B4FF38BFE4F14562A5 08497C654A1B33ED858FFFF043C7A825E859013732DA41CAE3BBF8793766E0E6 5FB06C122AE97ED7D8433E4BE95DD1982D364B200F82124DF758EAB471C66C3C 8A042D610DCCA9D7CF9E81D7CC35C5E2A872E237B3A9F97E7CB865C50E3CDA17 4DDF8982B8DA8DA4952B2DDB81E64A7CEB31A3B0B931DF0092EAEC429FBAA426 9556DFFC100B21609F291ED4BA8AF7BE4E16B1F2F6D920DD0FD96103421A62F6 E4BC4E3576D4769F244B52C0D1D19DEE5F5AA5744F41DD5ECF57E1D093A678D2 ABF4D6655958C2AD0ACECCFC641EA51B4818F5DE33BA16D28780677081537757 AE832C0F7501E9DCD9E704F23E4A5E1251A202CBB94749B5A29ADB0DC82EE65A 8071315BD7005646DF03293724916DDAE73CE3FE9A64FBEC5F281A19816A1C97 7BB49ED2A8DC20777B6FB312E9C58ECA2E83D94CCAED51D89A969EB3C4062DD1 3A5A7DE671576D45B44055B244A25FF84282C2D0B2CDF3A0804748F6CD30E507 56D50B86EC19E8832D0FC0A874AE7691362D3D9AAB87EF6C376E067D7BA9540E C1D20A3392F470770079B4766BE7F85931B5E00DA2DCBB22F42752D2AC252CFC 9C9E5D901E9D7EDC83E16551641DEDE4DE41A1EFD6FCF383E1BFF930A57C8EDD D64CE10CD562DB5C49D919C7EA7ACF0056022DDCEF0FFA63867B11296A93752B FB563E34EC373A379F3250737A1EA942C7767D11A1B7AEBC5BD26EBC3116CDEC 624020AD363B6E3A942AFAE984FF73E19CED8F2DC323FF0172547B889AB1166A C751F9DB587CE7B46A3B1AAC589BB8FDFBDAADABFE23B2E97320D615F406A9C9 93DE1FEDFBE139D9988F597B1A55FE2D86DD975790E4AC411CA46F7E2AEDADCF 85C229AA2F2739F627214D2051F2F622584D64C0C02FD3B0797C31539D55A366 26D3FB610C13B23A6112AA31D64F2CCBAB13BFEDD499334C7C2E0ABCA327937D 1918C1E42D5FB19F0FAF2A4591738B42983F47817799B4AB17C7322923BB86CE 45F145CBCEFB2BF655CDA64C3E2039271A16D462C57F14C0FA9B164BA092423C BA4D645D156B94AB3965CBB38D4CCBBE65025D7A804666F4B5C2007299D99CFF 3F9691B4E6FFFCB3942A3A4A4AC822BEEE42FB3DA4B7BF80E3487E6B820B67D8 AB9E085834D749EACF3888F54462CD384888413565439E97482F0CCF312D6252 9A9378896274BB10AD3103BB31597548E75FA79EFE91F864FA2959B4CAC56A0F 5AF8B1E6A64175C5B562F8939E6CA27572BAF38E038F2A602D8AF7198D7B8354 B8068DA7959C1E9C32A97E36A2AE0BF1E52966788A17C139C088D1702A0A8E4E 7F4FE50060CE906DE6799DF5E3BF9F81FF0E076E9077002F74C0833C63F62FF4 53DAA35383196740C79BA5224BC369D2B94BB5C850A5DFC022AD2D428BF88C39 906FCD0663774DE40F14DA7492A7020A92CFF2008CD2C442AD89D4ACCB3A3D52 B4668CFCE7DDC59715951D4AAE2698DD42C83C968BB331C8C1B023867CE904CA FEC3AF2B0ED8336E93FB1151F306DFA3682322BB02242348D25A1A33447778B3 AF19F58C43C95F4B473A04AF8E5DA8C67D0D5E3F9F9774C519F24F715334DC87 207F7B6884E03DC374400BCD11FAC1AA23FB1BABF460F99A22A946AC77740F57 883C7F3A6958FC82BD2DAF0D2A7C4F47457DACF21972C5E5AFB2037F3345DEA9 27A21F6795F4288B5A85B13E39A2A66A52F486DD2D1B4D2026BABD2966DAFF92 B7204CD258C4EB9548234A0876B7E03464F721B8BB5611F56A94449C37C3B1C6 1A4DF0E5E3FD11633058389F30BA4D56E7FB0C7C28C097E70323B155969541A8 830EDC4FCEAC0C7145FFC1DA62FCC154F48568E81C2E8A3A15F264BEC46263DA 574EA4525F80552CF10CFD7D3AA4F8D5963B3EB13CAEC5137B4347440290D9ED 91F390E48CDFB371C71898400FE026E0E1BBFD44112999855C3257B306D54930 4A3D2BCB0B24F8B47AE4250C850D93CA4BDB84F935E1C91B2316F0CE892C158A ADC940130F4D7C11D0AC4C58F935BFD1D837C8CE3838E913AD99E0EFA11F0646 5F64B6E08014BB4827282BE30F6ACC91FF3F262B4D38072CC6BF0DF5482CE51A 54A2E8A1780B5CF4506B25EA89DCCDA263402E53216A5EE1D5368325115F0780 0A42C6746974998D6C2476438995FDC4D72E882A3EB3E1B63ECEC3113C0E7BBE D160631EF790E69894DDBD622E12B206DAB8ACD762728021ECFEC53A82E43333 F18DD39BEEB755A6808B0EF3CD8A9472F05A0814E75F2EB5B5BBCC29572C702E 25E81013DA1D28C88B370599CB44FF747459F6F525491384D414E23FBD149200 EB2493AF03D4C802DA07ABD54F5AC94F2DB03168C4AF36BA0F4C038BF4C7C571 1FC094B8B8AA8CC8433483292F5FAA7DBCA49A39A14BC2259FCCE42316FF2C82 0427B0FCBA196DA06C25769BAE17963D3DCE1BA82F682A74BB27924DF0457838 DFA2BBC9C27C4EC2B6441D3ADE43EB111895F128FB70F0E182DC4454369B3FEF C02E575F543D067DA61256208A9AE0C447FF8A7BCC7DC1839F853732B75A7DFA 48AFF8D660EC59B863559759634ADDAD5F2BEAEBB253101811E183277317FC55 49436FEDECDB4F93D07C6A98E3AD0EEC5C167E9B9BF8976BA32E5077A55AB9BE 18620ADEF7237D4DB13BC76214CA09878CA973FFEA3767F99C2C65A824DB2561 5728DF8ED4D8297075B410EC107517DC8BA01D4CC4B785338DAE5B61BF1F738F 8B89C66E17376938CE44887E4181DD971473DBA52C674ADCA42EACBA7B1692B6 54C5959ECC88DC3F6C25B68B1036EFB3D2A2FA51EEB16E047C8E6B60D7433ED0 36D56531C33C390BF0E6BAABFE960055C084BD7CE9CEB2BC42A4EA9CB986903B E2F3ACF5E732D5B071049A66DE2C4FEB9C3DB7782A673F724D9496B20269C27E 4D7468CCD93657F37374469B853647B1CC65C4C95F8236803CBAFBEDB8F2CE3B 0EBC3F99E38C0777DDAB389F44CFD06F0B6F27DE34FA1C554DBB29DAC590CFF3 B0808B576ECA7B126D2337059A1B3A3DA74EE077DD1565C73A7FAA8567BBD83B 7928BAFEBBD543A41BD9423044342E01FBCF3F10CA7E7E4665A726270EF13BF3 D3530C9338707747C02190391745E0D7E4C33DE884041674652C3209DA415E80 60BE42ED8609F06BB60A2C52BFB34F5CC13C9B90AE7FE727B10463DDAC1C423A DBCE07DB27C28708F3D31080886C4B37F135D02183F65D1C7192949FB9B8EDB8 9EB6DC08920023F64376880CE42CFE31F7CCC47E8AF29E40C00AA0B1E7C3A4CE 02F86FFFAC9A02BD83BAF25277A0724399DC6B54728C726656481E730914B2E2 39A7F11DC91EC0BF39C1D2515FFBEB66F2F74D0D5A15CBBB2506789CDA644008 C6E85FB9BBFA26B22F6B5D34B7C7AD043DBDD69AE0277448665C99DD55AB1682 ABB168FF8DB8376C9660CDADCD805F16975062918A62472C6F47B9DAB217B640 DB58FE98BE3B7761E4ED87C71E2447F4FDCBD9B244E7CEF79B1787A8AB3E3FC6 3CC069324F0ED64A73893CAA6E4A14F0CADB0671008AD0BC1AA22382879FDB9D 18D071F5F605D6734DD94342BD34819D1D7B2E308C6A8D6C7ADCBA296057D79E 91C7C5E45F019BFFFC271174F3EAFC151B592E4419F5A412C64C2EDB0F4EC8E4 9B1371CA62F697DE3F1FB44BAC62788B0ECDEC72C954A07F6584CC502C7C8C22 0FF9317AD4E876F146C5EE7A0F0F8048A3CE2CFA61223FB9ABCD620F2D56A6CC D1394D212583499BF85FE218C74CF7A79E047F99595B49707EC1F85EC02A1CD9 E3888605CD6C8EB88C8A22BBB4ED2D526E05E387152F5B987CDE0853405D515C FEDD33DE45186D506DDF191656A5EB5C6744F6181C08F859429EC7FE4104411C DBB08484494D2733CD9A1FC89736ADB95844612CBEBCD07C3DE424EEBD50B85C 4383BE6AAB2A3DB0C510FDDD2E9D395DE115DA8BCAECFDA1863FCB97B38A8723 27662DDF1EBBBE9899819514AAC7FE6BA812A75C35D2CFDECE26C4C5CDC9F3F1 A18A7729A0B2BF0960C82D4E62355BD1FA7CFBDC5188F1F1E7CFECA5A62126A0 ACA9447EFAA34616C4E593CEAAB36A654C0992DA38788A80AAAF067A89B3DA0B 51BDEEBF7D48EB4DFE9C10A74944E08BDC8793162C961C53DFC50CCFDABFC195 044FD399145B2133EB92CE07C6B00E90C3A0FF2E51AED213F31C878EE1A86654 B60A5C53E69EC98639F01174FDF5EB7F3F1054C18C3D363F663ED6518EE0A509 3CAC82625A1A85909E07F72106037E2BD6C2BC7344705A71617D602F24896DCD 7AD85AB8781E17A6F408667FA37C8522EDCD4475304FB6D9B6F497B5311B900E 793D7E0699F44ACE3E0C359CC2AFABCD414856E3EFE9332FE41A31A551D5E480 83BA15E9138A28E6665AB3D5AAD118CAC0CAC775B7F3D0FAB949E136E2BE6802 C7C6299D5790E825F753A507D4CE80CAF3D0AE1B9D6807D6F23BE2A54FDC1ADA 76215AA2AE23AB64C2552C6133BB8FC1DE53C814635D33D83BE656C19489BA02 62942477C6D79BB2D7035C77834267CA7CA4EEBF57B6109532C4DA1BC33A8093 525F58EBD57403FBBE76D52F59D01D916967F351767324E45D37B457F26B56AB FFE9754451A737A0850029B6772C4FE9AB29CBBC4CC9544BFDE33E6E7B11B553 38FCDE9507FCC07DA0886DE1308BA1E406237A51CB3412BC88C358499F545719 EF57B991F465C24B6DDD33935F2499F542E09021CAA268F87370FDD362E27977 0BAE061E9367628A19F0223EF79E16F370503828545BE2FC5DB25EB701E246B4 EA0D3983E40E59CEF19AA7521CCB90E1E4FAE6C81E241B60BC7F01DEE0638D87 23F4C10F5A8BE92091CDDBF97B1666AF5EE4501F1CD5ADC523B594E87616F161 9B1BE7962707EBC47A5ECB3BE179730CB6AAD8FBBD1C49612AE67DA2FC4CB798 D2AE2BAA8C37767290EC48086261EB9C0B53C9ECDEEEE6F250C6D0FED06A68BB F17BD054858EC1F65B4E06D456EBC2E2425C36393617A494549DE2AAACA494A6 89CD607B4E77C10E046FBC657BA2E4424A329CA6F9806A6B2D92C3DA83A52F9A 4FD3794AE8C306A2EF8B837870CC3016BF0D14E51E12182ECA4AFA124FD7CDE6 C5B1F8A1E37DB88EC3EF233396E51069CC33C548ED760288FD053F83B24FC732 C1116591894CD4E48C1355E9E5C25E22286B4E54681124C3A85CACE28F6EA036 83118350C2877D796D41CC098C65D5F4A4F1A74D831F1C6D593B1AE6E9404622 E373CE492CF666B190B27CE2CCC5F365F17A53AB2CE1607A3D8161F6EAC61546 F75CBCF4E4360E77DB27F70CF89A7D4ABE91251C248A5098BCDBDBB4A4749C61 D73AF1C3D1745DF99F9517A0A71E08445F5DDB2A76A0FB41E55D8EC2BAE0731C F93404A64B0A0BF6ED28C078E0EA2FA67D622426FF440A2B5A0E113320B84252 B3CAB74275D8C2723A4E03F3C3CDBD3EA5D7E6858F79F75B4BEC59803B4CE489 31A7F8D40CC0D98CD0F76DD8EBB6AEC0813CD155E8F60C502261E838EA138490 E7DCB476875229B17B6754BA026660901D8D70DD36243D0399491332BFDAA7D2 A5833426D97975031B46C0917D7674D2F2246CF00135A9CA78E52B937BDECEE8 0E880FCC4A3F57237D849C245A737A9B21BE512341DD6CE75D422BEB4A5D8C23 65A4F36BD1E6139B5CB6619AB86F4D27C09B6520186F73DAE8A1FB2F77864BF7 6CEECEB1B5C55D01AFD69BFD81C9EC3B44A8FA571DEC77CDC3709EE8296C59C4 5F055B8D75FF9878CA8157DB1C9D7573A90B53EC53025A1331AFDE0E1698274C 5436DB24DD914C6CD703A085951B2ECD42E55BCFFB90ACA01D393011A92E800C A9699F2C9BBB459A52124F89B9C7EE509EC772622545798A1853F7BC58E8F044 2CDF849C9E7120A458FB4F76AE6462DEDD669EEA84FD8692FA0B5CACE1C30518 5729D811DC54B3ACDEED1FC95DE4C0E829DAB746EF1A1A369E4DF61406573FD7 ACFA7D768531C30230ED9FB742B2E716CBF6CC254D2C650365FC5312850CAC5B 5B4612DE956E868A5381F71E3BDCE76DF5944DE0ACC668BE9920CED769F7165A 2673148FE27ACACFE8E498B6FC69A9A174BB3D81A5077C62580C5A4546A2F676 CE65C24ECD61207118856254F5F4151640B4486F25EAA24340DB6F86BF8CBD94 44DFF2643F892A853DD0A95FE75EFAA645823626B4762308A936C301891264B4 2148DEA6571796157C26C99E78EA5B2FB9F3F766F6A8D566BB0992E6A961E7E0 3F14BA635FEB3364955C9D3A2358DA72BEF92D5EAE1D76527E55A8AD50B8D12C BB4682FD342EA97ED173A1AA9763F92868F361C02AFB8DE5F8A255E2AC3BE88C 69851826EE2742431A646787CF1ABCEF65EE16 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMR7 %!PS-AdobeFont-1.1: CMR7 1.0 %%CreationDate: 1991 Aug 20 16:39:21 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMR7) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMR7 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-27 -250 1122 750}readonly def /UniqueID 5000790 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5CF5B8CABB9FFC6CC3F1E9AE32F234EB60FE7D E34995B1ACFF52428EA20C8ED4FD73E3935CEBD40E0EAD70C0887A451E1B1AC8 47AEDE4191CCDB8B61345FD070FD30C4F375D8418DDD454729A251B3F61DAE7C 8882384282FDD6102AE8EEFEDE6447576AFA181F27A48216A9CAD730561469E4 78B286F22328F2AE84EF183DE4119C402771A249AAC1FA5435690A28D1B47486 1060C8000D3FE1BF45133CF847A24B4F8464A63CEA01EC84AA22FD005E74847E 01426B6890951A7DD1F50A5F3285E1F958F11FC7F00EE26FEE7C63998EA1328B C9841C57C80946D2C2FC81346249A664ECFB08A2CE075036CEA7359FCA1E90C0 F686C3BB27EEFA45D548F7BD074CE60E626A4F83C69FE93A5324133A78362F30 8E8DCC80DD0C49E137CDC9AC08BAE39282E26A7A4D8C159B95F227BDA2A281AF A9DAEBF31F504380B20812A211CF9FEB112EC29A3FB3BD3E81809FC6293487A7 455EB3B879D2B4BD46942BB1243896264722CB59146C3F65BD59B96A74B12BB2 9A1354AF174932210C6E19FE584B1B14C00E746089CBB17E68845D7B3EA05105 EEE461E3697FCF835CBE6D46C75523478E766832751CF6D96EC338BDAD57D53B 52F5340FAC9FE0456AD13101824234B262AC0CABA43B62EBDA39795BAE6CFE97 563A50AAE1F195888739F2676086A9811E5C9A4A7E0BF34F3E25568930ADF80F 0BDDAC3B634AD4BA6A59720EA4749236CF0F79ABA4716C340F98517F6F06D9AB 7ED8F46FC1868B5F3D3678DF71AA772CF1F7DD222C6BF19D8EF0CFB7A76FC6D1 0AD323C176134907AB375F20CFCD667AB094E2C7CB2179C4283329C9E435E7A4 1E042AD0BAA059B3F862236180B34D3FCED833472577BACD472A4DE3E3F6222F 7A252B780C86447859579C68E52691E144F836C1C62F19A12EFB710343D33262 1F7955FE5C37074CE5F9C7ABF1A241078519A4D7913A0AD861E0E357B50FB730 E757C0D26390E6028FAC61EB0E9414716AC8406A6E35DC70A7C1AA524804FC8E 985CC3604A2BE0A8235CC895B2B33CB7EE85FE4F2CD817BAC3D27ADD295D0A0E BC0E8D849952BCA7325DC261A785CD2305BC377AC61AC5E5B2CD3164CFF033CB 5436B8000673A4D763ED26273130702447C75A774C7799FB8C3E54A2E34D1710 CF7883A9B05285C7DF30F314455A4428A5369D92C0348D45BF4AEC5E16611D16 1E5EF015900F4DF63A58DC233BEE88417B204DBD110AACD1DE3D750F9C 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMR8 %!PS-AdobeFont-1.1: CMR8 1.0 %%CreationDate: 1991 Aug 20 16:39:40 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMR8) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMR8 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-36 -250 1070 750}readonly def /UniqueID 5000791 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C 68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 3645B82392D5CAE11A7CB49D7E2E82DCD485CBA1772CE422BB1D7283AD675B65 48A7EA0069A883EC1DAA3E1F9ECE7586D6CF0A128CD557C7E5D7AA3EA97EBAD3 9619D1BFCF4A6D64768741EDEA0A5B0EFBBF347CDCBE2E03D756967A16B613DB 0FC45FA2A3312E0C46A5FD0466AB097C58FFEEC40601B8395E52775D0AFCD7DB 8AB317333110531E5C44A4CB4B5ACD571A1A60960B15E450948A5EEA14DD330F EA209265DB8E1A1FC80DCD3860323FD26C113B041A88C88A21655878680A4466 FA10403D24BB97152A49B842C180E4D258C9D48F21D057782D90623116830BA3 9902B3C5F2F2DD01433B0D7099C07DBDE268D0FFED5169BCD03D48B2F058AD62 D8678C626DC7A3F352152C99BA963EF95F8AD11DB8B0D351210A17E4C2C55AD8 9EB64172935D3C20A398F3EEEEC31551966A7438EF3FEE422C6D4E05337620D5 ACC7B52BED984BFAAD36EF9D20748B05D07BE4414A63975125D272FAD83F76E6 10FFF8363014BE526D580873C5A42B70FA911EC7B86905F13AFE55EB0273F582 83158793B8CC296B8DE1DCCF1250FD57CB0E035C7EDA3B0092ED940D37A05493 2EC54E09B984FCA4AB7D2EA182BCF1263AA244B07EC0EA901C077A059F709F30 4384CB5FA748F2054FAD9A7A43D4EA427918BD414F766531136B60C3477C6632 BEFE3897B58C19276A301926C2AEF2756B367319772C9B201C49B4D935A8267B 041D6F1783B6AEA4DAC4F5B3507D7032AA640AAB12E343A4E9BDCF419C04A721 3888B25AF4E293AACED9A6BDC78E61DA1C424C6503CC1885F762BADBF392C7F6 73B64A75DB0DEC7E63389ABA9AF23241B3AD5082B5B3B5BF7C939E35F5DEF80A 98117D8933549937B966A691E37AD63BE615B3C33F204C65741097DECFB3775E 79C625E5EDD6523A56E6CF7867185E6E4CB3293A163E9574A517569C976994EB 28C2BC13B57BF83788F602425FAB60374F5E45DFBD9D58E951921E0E6BFFA25D CA5C4F18FF256E50E2F74D9FD0E89B77F57E29C416DD951370080B54C59736D5 A118C65180A62409BB859E63522B6E9DD570792A19203712303F9FEC91230ACF D1AADD6AB0060C512A37367034D08A6C224CB75040326B64C71B1F75E40B1D84 9FAFB72E249AF38110E6D6377D198BD0985AD94AFEA780402B4274F02486F280 A3DB3A975D4D6FCFDF34B41138AC53AACA4CD771E3A9C37A181E74BFDDD7ACC9 AF1C79AE57625ADACBA906EF80879BA7CA2D7D348EA28B253A6C561077AAEE92 AF55C0DDCFBF76F99FB686655921747AC3F5A57B1A31B657776A197D96A91900 25D9D5DB32CAD787D187510910FAD6BD130226D50F306B6ED8E592B414D09F3C 15237E072638FBE2A70349F08367832F1691E58F55F6E0F558D4E4E4578D977C 91AA908693AF5170BB5B33361D29CDC6598A968F03C4537D3C663A79343562DE AF06EFA53C7D435F3009DE4500DD709A12AB89665DB5E84B70A526F0BD8E3463 4C6EFEE2497AB9534A3CEA2EE29BEC420B049922C81A4E66DCF64D1B028D2E85 998366C3C5EB2FA6108C07830382837112BE8BFE439CAABC704CD8957BD0D04F 9BDA4287B06F7FB7F18C4215B97DCD56A3F6335034334CFBEB383974157D03DB 9F2CFA7A31C05BFD94C5AA199CAB8D0E8FB33119836BC1BC325AC43912C1B210 ADDDA7DFC7BDABC12E9BA7CFD0CB0632EBC86030E128B28AE841DD135D871931 9E7D9E52C6925B15B1A5BC52DEA83F1C0CE373B36125FCAF36FE65789FB7F2D4 9F69534DA69958852F761991503936DBE876437C15EB7592B59C087A17E88CB2 C2ECE9B8B00153318F2BE20C3192A5B9B0F17D9B8916F4C6BFB3112692355444 CA9CD5C1680FC005A5B2260305B76D458C2120545D594C23333192EAFB9BEBBD 8BB78234F3A6C2549F0ADB06E7B3E2DF552461D9DDA63BF4637D6181A625159A 4E85A879C8BBEFD8B0F0C79D92CFCEFF90896335F930219ABB4B57AA7F95A061 17E11F6C810AB16BB102AD68991B78D2F39AF4CDA7226B880E9FFA54CF8DB7FB 1C511205444BB40988085A84BC37CF73ED0CC872F2DD4211D165E44179FF6812 1EF7AB22BB811376B05399B904B9D288E6C882031E574375BF45D21EB9286E28 C028B70C32FB0937D35577234FF235D4B868ADFAFCC0218F2B5E82ED649FFC74 483262E9BE2A0C14394EED81212F870EBCF35F6480FA879A710CC33DF0AFCD3E 3C30329C6137ECCEA3168FC3D77E724BFB0707900396A330EF2B619D5DEF8F9B C28FF3FF1051EF1BDCF989C43AE1E3C4A10D8917E7D7E5662DC31987CAF64940 4EABA4AE2FC64D072CE92120DC18011AC3B5523C657915A1D6A890AA1CC0CF32 16188D3FDB6C3A1A70BF0A8CAC5DBCE7AEA41B44FDD7EDA3E97BCA079903173B D48E0A36C5B1BA5E0674F51A6B5C2AD107F3613AEF1463F69B4FFBA5D7F1BE6E D09935B3D0703B71348449AE83AE43AAFB55BAC1DDA36FD6F14FE8F6D1F0687A 916E6C36C331B4F7E9100631AA87CB72BB78D750A9F5D7FCC1A799513A2B4B50 7754E25574D5AD8773335B4C510DA0C9B0B8EDE8DDC3CE9D43820423E81AAB77 738DCE6E6C6E591D82EE871B1675931CB8DB4886CBE7B21E86176ABBD7C61157 AAF2A9A5D9636F735994218DFAEDAE97E33183275A7DA98F3C0D167C40BCB866 74549E2AE7C1A5AC0EFFC73A4CECDD62943C815A44E776B29C1BB7CBC3882086 5B0DC87A9DCF3C7ED924BB5D5A5895E5806471C56E8EC4CEE85E80FB2B680CC5 A65926C4EA2DF05DE0D59FDEFDBE58080EB473E2DF1B8EB58AAAC0C370D6D9F3 3F2677B02FD65A96C155253590416B9BF993247001FFDEB3CC999D7DD9B3D429 A0CD47717DDA1AE0BE26933DDEC4CE15DBE216FC5EE885FEA8B60A55D4C314AB 8E473FA0F24E3654EC41271730A02B521DF881159146E5F53E2A96EFDE0C126B 2CE74C76AC697CDC66FB0DFC404A29E133FE7A46C78D055540DF398D10E9DD36 2C149B22E38320B07F93B4E106013E5ACFDC2377639EE99225397019542511F8 8A69CBBFDE03618BC08DF05D417E49B35083AE8CD42FE3201B4F9758AD88CD2D 624EE1EAF925F9E3166A3646DCBD2A6BA362927A5AE9F39CFE79A93D375186A1 10DFA3D141C26F1647AF6B92B54EB27EBCE37CDBDD69E9C9122DD21CE77B6757 83832C14425063A0119C73703EB20FA447437FFC2FE38F27643964B2C321CBF1 761EAC6ADEC5BF4D3228A592FE076F5382D98514CA0EFE41DD8340F951236790 1F77FE645DFBEC8C59063790F6B8F3B6DD2DA072BAB959B4E78028B5CA3E50D8 D03C4BE2BB5A76ACAB07469AFF3A0270D7EA53C45C92BA9A5529865B1877A320 4D54F51242FB476B1C5D79F99DAD234F851F0D2E48DB142AA44F4E32601785B6 F7EF6ADE404979794E06C1FB339AFB8193D63D06C23BA6A44EB2B699CE72CC36 52B63FE0B7B090FC6D267EB6DC269DB880BCCBE4699DE5193EDF907071051785 802880B267F0D6C4FDEB3D984B5824D28FDF0D03A9514DD7DEB9705A44504165 9226AECE88B60063C4A27CFCA96F9D0E75221A22AB0433ED49ACE8A620BD019E 3B74265B9C82AEC005D83CA6923B3B25A833E07D3EC2B4A603221CE00F1BE93C 950CC03E14F29F477C8B7F36C1B7E564E8BB9933C81CDCED5009FBE9CF7336A1 DEEDDB43697D7C893542DF4DABA6874985B23683C077B2F3D93D67038F5306C9 87DE3C341BF9D13543F4E074A40ECC25D2EEA898B27AD1224C30214FE88B40D1 04C4811A6E624E2B513849C7EA2C65BA3BB8126FC23B79B125FFFFE126368C85 C4C195B6169945AE959649B8341F81C2AA95A0D2CDDB0543C1EA3D0DC5B07681 E0EFC4509F6A478CCA6E5A8F3B2F478180968FCD4C1DECD9F4C21F1C126C17DD 1C3608C6B204A03E398F0546350D700B8791BF9BD7A275F805EE7E8DE18265CD AA4A297EEFAF208257A38131033B2B928FAE7B65A24B75A29749B6967CF4E1ED 3CA359BDD0CCCDA1CAA567D600AABFE454F8C9DB513F64A432F27ADF6413019F 35C05E1D1E328F8D6789637E8DF6361EE8943490A6C727A4A4DB9B1A120584F4 BD311DB67D64356F1FE31284DA2A974CBD141B9CA82DAC5D397D911F5A44C50F 4FF6E454FE413ADE639C464FB67340215225CC704870FA5EB4F73383534FCEDB A1324656929E7355804DC0569BB5531C6C3F7B677238AB714BC99AF8D0ED0C23 218D4CCCC6BF3F9E460BE86ADF57372C66DCCF26D4B035DE069D6A44D72C49D3 51D80D7E05EEBE91AEE940A2D35E1527B54E770B416397E8256981B3C598BA27 2284A11FD36FE2FAA50EC93784B8F9A445F04B72A034DBE4CEFD0864ED5D33B5 BC90A7D158D3D52E0FDD2552D5090345395F8CFE3D1FEB3307EC84E6DC1FCB8A AA631A7142C2694755A1 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMSY9 %!PS-AdobeFont-1.1: CMSY9 1.0 %%CreationDate: 1991 Aug 15 07:22:27 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMSY9) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.035 def /isFixedPitch false def end readonly def /FontName /CMSY9 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-30 -958 1146 777}readonly def /UniqueID 5000819 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A 221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A 27D1663E0B62F461F6E40A5D6676D0037D33F24E2FAC2B0009AD3C8350CDF8CC 65BCA87979C36D14CB552E9A985E48BE4E88ECA16DF418749AF04FDD2B0E1380 D281BB2476BB45FF30946B247DFD7F57305FA87E50CA338121C71CDFDF927A9C 77FF14CB4A1D6D80356FB1171ED38C37702350497B44E42CE31DB2F493807DAA 15B887C671199A54C4C1294BC520F5538C15556BC43C9F62342B121C6DCD6C5F 491DA47FF360201EE21C08A781ED0589A6DF91B99FE118B9B29E4F068672E52F 1A06C514D91C4C937D4E642503392B1CD1BF5AF0BCA28EBD840AD76CC39AD7AA CF2C05711374F7849708E1106F88737C9AA60612D384CA8C173FF1031EBF6EA4 176136DE1B9F29E40E82680A2CFFDC24DA05853307F1D1F6537D061EBCBCC5AE E6316380ECD8E63ACBEA9FD1FC28949366850AAABCBC9552CAB2CA3BB934C8A2 14C9DFADE24D9214858B1D42B2171DB18A475AF78868C2549F19555AAB07F586 58B28541C74E14F28B68DA42A9D46C031CBD74FC09BFEAA3AC1DDC68B7B71B81 6003C9C6AC8EDDDC046D247A2B8AFA63A3B1BA1F12AE0B4DD07327F0138BF470 4630E4B5DA55C194F454EE2E872E0ABE6B879DF2E87CF81F75D79F458F7D3F81 FDB76C15EEC4125D18685E1D8591C54C0B0D069E2ED73434617B9D30E64457E6 1542E4630E848948FF2747D5C31B9C314AE108931003DB9F76644DB43D245499 2D28E8452E50B1945E13A5DE2A8B93523D3671D1C7ED07EAB6FFB559E5A1F828 B22D2FAF349B40C3B31FE806595F67C5E75260514F456FA0013668D948619514 0EFFC35C1AA131AF8578A254AE62CA75A6631489C78CCE633A3B302BFACB 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMBX12 %!PS-AdobeFont-1.1: CMBX12 1.0 %%CreationDate: 1991 Aug 20 16:34:54 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMBX12) readonly def /FamilyName (Computer Modern) readonly def /Weight (Bold) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMBX12 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-53 -251 1139 750}readonly def /UniqueID 5000769 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5F0364CD5660F74BEE96790DE35AFA90CCF712 B1805DA88AE375A04D99598EADFC625BDC1F9C315B6CF28C9BD427F32C745C99 AEBE70DAAED49EA45AF94F081934AA47894A370D698ABABDA4215500B190AF26 7FCFB7DDA2BC68605A4EF61ECCA3D61C684B47FFB5887A3BEDE0B4D30E8EBABF 20980C23312618EB0EAF289B2924FF4A334B85D98FD68545FDADB47F991E7390 B10EE86A46A5AF8866C010225024D5E5862D49DEB5D8ECCB95D94283C50A363D 68A49071445610F03CE3600945118A6BC0B3AA4593104E727261C68C4A47F809 D77E4CF27B3681F6B6F3AC498E45361BF9E01FAF5527F5E3CC790D3084674B3E 26296F3E03321B5C555D2458578A89E72D3166A3C5D740B3ABB127CF420C316D F957873DA04CF0DB25A73574A4DE2E4F2D5D4E8E0B430654CF7F341A1BDB3E26 77C194764EAD58C585F49EF10843FE020F9FDFD9008D660DE50B9BD7A2A87299 BC319E66D781101BB956E30643A19B93C8967E1AE4719F300BFE5866F0D6DA5E C55E171A24D3B707EFA325D47F473764E99BC8B1108D815CF2ACADFA6C4663E8 30855D673CE98AB78F5F829F7FA226AB57F07B3E7D4E7CE30ED3B7EB0D3035C5 148DA8D9FA34483414FDA8E3DC9E6C479E3EEE9A11A0547FC9085FA4631AD19C E936E0598E3197207FA7BB6E55CFD5EF72AEC12D9A9675241C7A71316B2E148D E2A1732B3627109EA446CB320EBBE2E78281CDF0890E2E72B6711335857F1E23 337C75E729701E93D5BEC0630CDC7F4E957233EC09F917E5CA703C7E93841598 0E73843FC6619DE017C8473A6D1B2BE5142DEBA285B98FA1CC5E64D2ADB981E6 472971848451A245DDF6AA3B8225E9AC8E4630B0FF32D679EC27ACAD85C6394E A6F71023B660EE883D8B676837E9EBA4E42BA8F365433A900F1DC3A9F0E88A26 30F9120B5D68BECD2760EFF272B05A79928D299242338556B2D3394AFC49F66D 40AFEA4F628C8DCEB19B30FAC75DC14A5C835AD6341AC8183856C78EC4DA45B2 B7E37FB4E64EA4060A8A7B98E61F268FC8316E0140F69A1D20750E90CBA5BA37 D5EA17255543598A1B16B89941D2ED532DA282A1C10EB0789CCBFEB89BA1E8E0 5B6A60AC34BF00A1AA51B7129C4A6D8D9F69863BA0DBCFD82A0772ED1594625C ABCAE4C4BBF2DA3325E08DFE62361E6A848C408569432F8509FE1C4ED08648AB 75E5EAD9BF35B1F80B15D96998732241DD14A372D1BD0C4F354C0AC33627FB37 9805CD3249423EF27F64F6E4E8EF80E8877B28ECC7DB24633FD3C5739F26081C C17B583E545485DB408D61428AC921DDEEFB73319F45F40D81D71C8A5A2FD4AA 320BBE8D2FA0022C08EEA7F6281EEFE90E5E501FBC47E20E1F64BC9B48426AB4 62BDE0388B27FBF7C272EA4C2C72105AEAE4B2E4FDDBA2F7CD73FC0B939AE294 C1B00278E9DD47D24EF5466A6CCE5E594A38860C807580EA030A2F9B973678F8 E4C1ADFC4B20B528543AB19A8688CE3AD146AFAC35E53AF0738381D568958B2C 112BBB74E0AF3E113EB6456C969B0DC69294041F09D30F8D36AD94C3E48157F6 A6940AC3BED5F5EDEDDEC50657D3AE6151811AB6AA894957161E31B85A54CE82 BAD1D99861AB05DDB9BEB34955662B270091006115C16B26472E3A3BF699DF0A DB3C2E1C7FF04F3EF39989A2AEE03910C3D76DB3657511641C03951EC0681D54 9123F58DDC50EE2A4829EB2BDAF4AE38353CE5E192849C593CA229156D48BD93 7D4EBC6C28F30458D1F9899E2C970E400AFFD4F218BD57D883E234D78A4AB1E3 2BEFF428E73A29899F96AFDDCF5F69036304CDFA4BA8E62792EFCE7719618B4C 88858A4801FEB352455419138388091B94681434D088C05D2752DC3D0361A2BF 68D8A9F4399FF68834C816F3C26A28DDCDB902A1ADAC47F603F86658195BC3B7 A429A8C59B051289323EB0E16E7CF1003CA16FF49242096F85D18A3CA4DBED02 5BEE3E6DDA48A997031A9819035500917AA13987B3B19126DD7C61326F3D6F20 D3275F6F6C90FB42EAF158E7762E96B520570A7E3665CE23B6E00BF6BC6D737E 09454A1A7F4D7932A1C6E552B520ABB46B17A95C5F4F5FE64BB489A304CCDB5D 5B2067D97E71F8593FF5942D4549595D25A59D0EBE6ADF891352C382F24694CF 30FCF6E110E77D3C4C30DCBF64B03816677C75E099A695ED751709763C9D7B8E 8A79CE84A6889C3EF468A6BCB3FFE21C22CA96C218E497D7AF20E943B48CCF02 8CB75C6EC3F0594BF6858C6D50740D19BD256FE190762AA4F953F68DF0C1B443 54B49C30CC860B2129FCCD69A5D5E1339E3191C7C6B50A8752555BDD96F7F22A 25066C55EFD3F48A35B89765B8B5DF5A0166632274A03A7D6343DD5D26873B10 85D8D594606C993F56E7F365F3A8B64F4C28F5070C0C442907C8474E61B4377B ABA0D49FF38BE3B90E6B3AE93CE588F1D7DCA44D9D7D71B915ECC23B6EC9F519 96DDA3992023EFE5145F86A386AF35256C1DF30F1E7B8D6C1256E78C0E91F76A D95A22FFE368445D2C52206192FE3E10A111C3677177231B6C70E85129722ACD D259871BF53E776E3838B24F0CDE9E13AD164943325FBA3167A07CF2FDFADC0E 89D75EE1EDB6D5FE7C8882256DCC4D4F4A3CC9C410E96208D8ACD738DF70535F 527ACCDC103990B21DD7F01F08988B695912F7F2B573950923775F24C4C080E3 68792E4B16916E22FE9A2DB130B3CCCCC877AA02652F0BBB2C1F21482B714D18 3F8E62A69442A8B8DECD4926B19E72D217333B8EA031D3830E9344C203BB5FAE FAC7573BC0846200EB93FEE6039FA9117378A588F70337447A71E911BE531A6E DEF66242060DE5087B6F15EADD26F53893B954B8E31ADA4882B09C52F4EAED81 CAF35DAB9DE695C50A2A450BC5434F0C621E505408AED542F4A4E37119FF2B17 6403BDF9045FFDBF2532AA86FF549611D910730AD7B064C5CA4A3A9B61DA799C EE6EEED03EBD99C7804A36210E9AF6BDBBF09E743F07335C9BBC41C0218D4B07 B24F647D6E097EC45D6036DD893E9A55395EE6BBF10B48BD8B1549D9BD375681 0179FA52CBA100E612F3DAA254E174B4963175CB55C232FB126638BD75431C98 11DF37C4CE348AF530BE8619886073A84F041DEA9179F1A8331DA1F2C19653A4 7E2DD7344E89E27025BEF72A887488418390E4774BBAB341E2DB605D5D360865 19CB3EC96BC16F4A9FB26DBA96A2B42FBCDA579D41A662FBB7E65E7D25601CAA EB0DD6C97EB9B3621C01D43D7E840FA063191B3BB0A3CAD914CFDEA5F713E2E0 C4BF026809AF6F0E4C435C74ADCB96FBE468C034ECFCD58C15EA4F2F82EA4E42 B3BF74B323B45B956606D3B12578A6DA4D87CA37D475489BA44C8B07371EC5A3 F4BD418C9B05FABE7BD88453558F1D5EB99725C8187D93292E1777255DBBD361 BBC17A021AF4A4B76D92A6B6AF0AB7FEA769CE9C31AD82F51644055E48DB70D5 AC99108C14874D845EFD76F7583D9C6EBB5E5B2C2AAB4707BE849424944C9A18 B90E84D303FE9CE0B0E3851FDBC6F8D32A98DD78005835D736B88AB2D130AFD5 EA94D78BEA59B02A3812B7D81A96E9816979489288E4EDC709F5870CBA85C02D F98CF8F4FF9262C2BAC1909E3DB1AAF849CFB08C37FA8573976A436FB8E0F50C 5ADC7235BF4C33A303DC89DA3A3BC4E3A77837EB577584EB959ED8F127B31098 EA4DDCF0EB407DFE42A32292D31302C31EDD735B19B19156837DBC96501822AC CD672977C541096D4A789D4D5769849D351EEC36042B909004D331DFC20B37AA A36F0AD5FED2C1B24FC4E98A68409F921FAB1A9BE0FBB94D00468B43CA2593B5 C5A5A152BCCF0566D95D553799469486FCD584F9A1F1A4F430169EC635CAE70F 3BAB9B6FAB3B3D848C9D0A468C384EC4A68A10D9D67112DAFA8A240392B8564A 3F67204CB2893C08A8209EE62F0E1239903DDCAD818A0EE0FB94CBE1D3713CF0 3F0AAA64D541621B1359278F2A591266A5A03FF46BBF9A56B4EF7AE1157C3C05 0C306EE7137D8809E08B7A0BAF24D13BE1170D5506D44AD6713C21951F10B9A1 29FB9FC0EA7DCD80A4044D8082BB50A65D81F6AD332A99281E6B1CF18CA4CB96 666A093C745C0E1480C5D37BF09FB5A8BF545693F4FED35A815B51FF68BB2227 4EC4AD669533C41A7A81488E7180BB295603192A022A232308B51C26BCF4629C 98FD57314DDFD1856F42AB68BA2E40BCF82269FD016D8C869106115D4E2FD638 8C7AD177CCD99DEC21B3613C4422DCF389C73ECD5302248FB066C4532BB05E3B 2BA714988713E14C5F47A0EDBD28C0E890B810234C57D23DDC52A53C9C31676C 0B55CEE0FAEF992E2E5D879F7579EC036D3C058E1FD7ADAE6FFF822D3C8C6D39 753706017CA62FB8AD83471E5CCCABACDB95EE0851DD9742992F3CE91771BE97 8554755F8F3FC0A8B593BE9E31AFD9EB1B2A1B0253E4AEDD592F0FB20158F5AD D94AE0F8228F6E1FF216BCFF84D7CBE06A516057DB6CA9BC75D8B45F0A1BC21C 7FB81086C0D33513D0C611D6B47C3E4705533CDB6F900085888264411F734790 EAD7C496518CDF95FC2EB9BACF038CB3704245660B39A2614449D10CC103A05B 5046F10738567A67E0A7988F23E903987047FAC360FC8344B8545E6D6355252B 5D87F15FF303531B17D1F578AB370691CDEBF2D1DC957FAFE108F17803DEAE7A C5EDA2EDED41BA765EA5B9B5136BFA3B8A75AAF756C0FFDF43D03B57AA2E40A5 F336B3DF5CEB9D614305CB14B7430853BC19FD3718434A06B49C4B4EEC56E96D 8AAB7DBCFF8698F3539973E4D1C3513A2494656FC00D712185D010EC6C4026A0 CCED61439DAA8BF26BD1E31C6DA901091ABCF7D1D16EF2247984036755CC4916 67615E344FA5A3F9C132B4897BADDAEA99B0EF0B84D66E46723F5E99E8FC1A1A F06FAC55BF5DFA7C10987F0ED29DF9987350AFE5097925EBD2B6FA082CA52DAA 177F1D297010A7F8102DD1283EC275781D683EC72CAF2BFC8689735621794DAA 0FA0E2D1FAE811BC711D0DDB39BC72ADBA3A9955373B8BBBC6F8A03DB835CACB 21D7055DC5F2A2A60AA19661E7DF6079AFAA05317B22443A4496C9D19EB2F5F5 AD1F7ADE8B2701427D3718220E99E972AC9582E56459B4881F638E2C60D45209 93D4E3685CEC64D1B8459F069393FF215D6AA351C97CB90EC4A6C144DBC30591 3A509CBCFCFD227EA750EF49437E542AB2FB6D94FAF558342E36BDF3B3220482 4D5E3F7B675DCB70E50F8E2691CA360450E2BF5DC36042DC1B2386849E718F9D 2E94EA3450F23729870C1414F78B9045C70374823F45ECA591F8442F38F8608B 86480F7F306FDF82FB98B7159EA825065F34E93D8B58544426862EDB42E9875A C6132CE19A604E17A825166997E346BDF2BDFF1B77D46A11C1D41958C67CF03D 3D3B1294AB4061B4BFD1B14362CFE69D5BD020BB734456BC62B1F30513ABA2F3 70ED8F96AC3C0DB8E1CDE7BAA0E5E4C5EC15CCA79A56196A768270C82823B3AC 34FAD1050AAC51DBFB48B617A03206A45BE82C1FB006827AB261FDC1F4B8B6D5 7E5B5201D9CD78EF8A6ABAB81190A4C2CB366210426BC37FDCF73CBB84C567F8 B80436685BA44F36A371AB0332AD28A887301524D2ACB329975EE195FA679BE5 B878CCFBFD266A68B4E1CD9AEA41E1312F9CF2926C2F397490B2455CEB223F56 3B89226024C192BC09873C521E7D86E71D8D472FA5B443A659829BA84B2A1498 2973658683C548864085898EF0CD818AA993946EE0A39115CD6BEC1B34FE9DAD 9F203DED197F8620139789A73E15FA63C967A3D4AFEC101AF28B3FCBC33697BC 9AA8EADAE5081DB31D8CFA9DD406CDD66B7A18DA88E5AE3A525064F7DC07A951 086584D7507471899ADC14FBBFDBD77C4112EFC9D8964BE901FC4901A631C947 312F403988CEC3B30E6B5AD70CBD7332C18A52BE9A819CD4FBB7AD346D0C09B1 0242B0743498DF99EE0DCA7B588178F052E418EB2B2AD113FF87856B746F0A84 21FFD7D977DA8C1078DB331F5207F32DE2F57E9CC2B178AECB718350C6B5099D A4922E0060894AD673A138BE3BAB09C27F335A349A49B43DD3A9C1713A77D7FA F3FB829F89D2F81AD7513696C1755CA374339A53D860E50C6F5EAF61EE986BF9 02C846E620D4A60221311A7B587B7F6497A1F29051DF8D7B5003D7532FE047D3 DC4B7C9FDA53984FC9009D71D51D452207865C20BA85DE83CF627107552C6C0E 09C2A4CAD04469A9CADB4F1ADB3BAE4C286F43CE8A6470C95956574E40BB9EDF B79C407FC2DF575390C206F95B61D042476D13E5E03B9198F27723E6D23A20D9 D8591DEEDBD7222707F9CC67F07283571BD7EB93FD91C3CC4947A1D4E75260A1 2D94D9530B3F2D0AF607C4D6731F4842870D2428D0441C228E928772C0D3DA6E C3ABBE61CB026FA0A7B72AFAC8A547AF58EDFA56FBE51477D5D4D60954FDBC31 03F4E97A6D0D2B62B08048BDC8EE36C3DEC67C2AA850B4F233671FF00C0AD4E4 41A6D5A19EE1E8ECB2C8197FE345F7FCFDBE2584DC151C19159551BFB62E9A64 AD11D741348D9BB0E8C56246B56D13670FA10991804F8B883CD1DD9A34773EFB 3E28EBC5E453492556567F46703732D6BF773BEA9B76165790A4B3792E20DBCF D0A1D3F36357B774EB00BE9F414D5BF47A227789FF3B01D6C82028C0F1E3C961 703939A640EAD579B325768903A3B076E4322EA65C903A1F97C5F919383E9C11 19152EF3BE63D7F9A4A05503FDF9E227CABC132A3CA4F3FB7DC9083F8B195401 7B1A713459A78EC357CAAC28D88B663F4F608E715776378ED5F68EA21CCC4731 2591C7F4BB6D9A378F3030083D6EDF67AD994195AD5F073E7517D5D8BF23C2A4 8D02B674B7F1D229766EF7F1D1405C1FB52AC6ABADEA44C274BD99E8130B5483 B7EB3E1200D1C8B77C64F09B096BF9D19E1FA4DF25E37B9FF3C4FA865D8F331A 8E2BD26B8BDBF7702D64D889AEDB12DEF3322C0301C2E16FCCB14CCD493C5E69 1257C6A9BE766930BD51C0C33B0781D775A33054C9E41722900F4D1503EB54C6 CD33DDC4E5F9C7D95E75021967E16C81D11AC50F75D3368315979BFEC241E986 2FAB66FFF3F79B72F9F3CCA04BBD1C2CA03A8FC6F492EEC2D9A5D504025D237F 8A5D35A217DEB9B7175321D55EEFC5A929FB6ADE165CB596C392840AB45B36C3 CE65B06E9FE1450D663D319D8D733BDE9F2BB0AADD4D850D1FBD5EED1D3BDEC2 C44128C6699396FBE4C3ECA53BD2C26B40C4429D26F5434B5C4110A5CED27AF8 EA57F6E4EB387134DB6147A07F3BB3C0D28F213B000083630515903125ECFBB0 448B9908E4FB3FB59038912751CF441A506E4346F75C9849E0835763C7A4CC53 C3DADECF556CD118A5FF2340CAEC7F591B0F99555F9705B968D7722A8A5E0446 1F4539B2053CD65B67DD2A1949A2EB6962C8195624EA4B4FBCEBA26B74FC514A 50FC7D128065CA3BCF147C376FFFDDBF5080D9EDBB0EEF2C899543264257C105 E29976D9D393D8846346381E67F8AE55B17112DD300595275DEEF49BB36C2722 B6C9261E5B08A7C7D0F17BE8E4616D99007CB051742C232D4946E609B737ECEE 8665F830322BE5B7C69EE8B5F39D031BB89998B389FE9504A4D2120AB4354F35 4AED599DFFBEA28B4A0FD8EF1CEA718231EF6934036B79DCCE8499665590766D D262B4D80ACC8F30D63349713B24418CBB928C5505CA1DD173F4FBE0D3DAA4DA D272A38DB19938370DA5BF5786D880CE38D1A9CDD75F1223B00310681DD9BD2F 65083614877B3937ECD2B811155E35105899FB600B68CA93ED8EFB62927DDC96 5F911CD61F84F79D5978BCC776EA74A3EE75BCE8F2B2204E1E06E8FFC36076B1 8F0AD4ACC0F6C1A809FB2F7400A8DC726535895E5F23BEAB8A50751230B45C27 8D612662355DCBC11607DEEBB95825B6C8236D0FA488A348D877BD1115E083BE 2A67F7FF2594A451C9F5E1A7AD186AE35CEDDD009C415F47E50FD4540FA9CD58 EF9069C02AB05BC802D8A14A4A771CCC7D6CD19B7506CEEA546E812DC2E698ED C3AAAC6688BE22357ADD6617C87C5C61D446B8FBCBCD6619EDBFD09B5BB15E6D 07E3E2838283F6E0D44EE501E6C0B29928CFE84B47544B8F3F74C89AD4B3EAAC 0D945189510F833140931FE144797A9179653325BFC859FF4719C5B92AAE0973 4FF4A5536F5BA4B00CB876578C8836339D565C310151599AB073E7E8C0BE915A 2A17456D05D232F55EC820E0387660457E689F773F0B3FA227B84F8E37457621 29EB8FAD63AFB3EF8D20B3C456967D7FEDC2F4DE15DCE41C9812ABD820D6E131 0061E3D8B4371AC8ED5C545DC3651F70BA92234E93621F8F2FD0AB59F251222F 0766967097B71E41750472EBD051A6443B0AA2453F1AD4F479F0DA4809D626A7 D17D35FA6A96DDC3C80443FF024D59BA99C4FD6DE9304C015EE2727F2F1981C5 1504F1CA959713590DD6ED2B2263EE7682DA8803C58A70B96B1E7046F52C6625 5202A9714A27EB3550B129E078BBA65F584CEC5F8CF710A3D447108EC3344A06 161107561B22074DB0172E9F47A04F3DB365C8624C320E064DA52FB322D8B8A8 63D73A64FAE8D097D171D108DEC6E38A754FF9AA2604F5C0AD8ADD65D4831199 3D98B18BDFC47A63FD90343283A037CA260A47ED6267E54E9462B8BB56398B37 AD272CD8D85C1CC851E86EFA1B7514AA823A7BF0D47C869A596F3A18004C3211 E64051A8D6194FED02A2B9C9187C179C88B28271E56B7D1A063E0FE6F78B46C5 73A7DBDD6E57D9FD8C433BEF155E92AD1E9DEE89E535A526CA38D536EA3643F6 09621939703A8CEDA11695A91CFB997CA9D0CD18E04F96B97F2905A25035A069 AF9B85EAF50175C989492D52E46E03A5A837FEF8B42489316E961D47A79C798B E95733F51E08101793A492DB0B1C3A9E4ED6CEF1EB6542C0FD71F809C120980B 78C7EAA06E6CFCDD567BC4D52F6D3D3095E4AC3E61FC69E6795DA092AA848305 C9F94A132A4EED200CF0A19DC20775F0215C0EB9A7783A78A64F155E0F998F6A 3D7BCF572416452F83E1B2D502389DDAA283DE38EE1D6D7A799A10BA47571873 9126279BD6ADA03B80BA37B74C8B8DA5BE54C817E316D6C9EACAAC270337C415 AC3EAB60D480EC67100ABFE20AFF2F32E97D260DCCEE6DA0DDA5E4C1A824DFE2 2FA67AD546BA193BD8CD0F78933D003EFA71EB25E77678A8976AE90F8F51F522 D2897B04B91FB175BA2A024A5181B997C58FEAF1396495946F2204A252F0E4A5 9CC3D725F0928C3CD4138D4DA638D4621E462687E468490BE8956F67C80CBCAD 426FA575D2120933F5EB700AE51C5372B9A645C69AACA64315309C919A93CD10 436839C3AFC0A2E9A4E81C93582354CCA019F4CAFE3F387CD26C519248AF5EF4 8E77AD97C30C3C1A359C76885FDA9D612A3544347D14970E7A825FF8FF13A220 14DEC43A494016EF1B0B2458CFA7C9A8BF0384A0DBB5305D42182A455AF0748A 42ECC062FAFA97A53B64E6E15448BF53D63193A5B070AD88E8EAE077D3788A0D 296D1EF338CD7C63CD99D81E7F0246939014564D898B9F7693EE36D9C18A4FB4 BEC21618D3A2C28646D6662E15614975E64981B2851527A5E460BADE35BE5352 8A2FEAB9C40FEDE49473C4B2A280206307D79DABAB7577EA7E38722C9AE34AC2 07CB37FB7BA589446BD54E81FDDF90CF489B0A049D12B81DFE8D80F7A5F27CEF BFCE93358F76534E143BABBE6E68C9756889A48FC14A4CC68917AD7D9234C0E1 EC2B32BE0179A70FE54740CB48DCB1A6B7D7021614A5861DFFA5D8D58B330C40 11AF3189CFE312BCB5D34C7284167B1350BE538451C3559B178250FF1F0AED45 09B1487DABBD76998255CBD158A7160A552921E87C766AD509C8850BA9097E93 450D553DCDD25B96A9C082A680177ADEB06D35E102DAEBD89B373AD2E3CADCF0 320485D6D02CC90FC47008D815BE8B7481B375D9B4B4BA48BA236DBB687152E6 9E437A86D41D819DB8F9F66E86F71A9D408DBFF1B41A12BD3C9DD041E78FD32E D258CF3F24C27DA5C4D5F42B820840B4D91E5A1C0F9C372160FB930648BDC242 E2C937491347EC2036B5D84778D569A0E11B31B15BBC000CFCA0DCBD53673D4D 65016411E12927E7628D2B4F4CF8E1F60FB50B2B9278F5549AEFE05ED2D8E878 7CB21A93C6231F2DFDFE9A93015DE8203829660163A10D4CFA27DDE2438CF7E5 19EC587096A24E01DA1113C0F2A7BDC989D252482F8397D4EFFDC1C6E0C62CC6 E2F3C10D1E6E28B3D3A368F16B89CE9D84196FEC97024EA82946738EE828680E CB28CBB2CD6EB286C6B7E3856AC86E5C83679A5759C407F206184C0D571CECAC 7231BACA15D09CA51BFF56A499A651C54E978E5D47FCF4475100AFCDB0175923 82CAAF2A01DA9FEEEDE2AF870A08678B40D6FA1CDD79EEDE2B856485C4ED277F C42B8357B0A27740C50824BF1A0B87721AC3932851C6B810785EDD4420CCCD3E 2983844D35FD99DFF26C8003A8CD7AB9B95ECF01F7C4C051CFD3D4B242B76C9B EBCA23EBE784170B90F4AB4F12B8EE64E1FA9BA4621432107E129C104C69A768 7C9638951382839427465E36CDD083627D8C2634768FCC1ED26746EFA596FB4A 49D1BB92B3CD050F7518B0AA6A0017BE78271A0875767A712E9F87BDF235DE07 B310987EC23F9B8879AE39EEE12DD8E66B9D02C273597D4FD18CC862E56F48B6 BA635BBFCFC423BA23C4977F15B5E2B999CE983EE68EBFEB8E32A0039741B03C E48F1F55086E504342CE1AE7C20C2D2DA7D9AA178B84F8A108FFC946522C0602 422C1EEAA9CA7CE176177EE24F430083752BB98036C1E2D92A3CC4219F8A357A 207D2EF741DF8611F9793A279CD119617536416FCE59B9CAF16E09521559BB81 1C59B23F665BEC43344F1C79AD1D4CE8DF38CBDCC3CFD6DEEF884842E41C9D47 E2EC53C758A4FEFB1F945AA720AB059524516D8DE18AA097287B3461093775D6 4E7F4FF2389FD8A60DDA5751043C48A02E84A3C39FC143F795029ED685C75F1A 960B81E06BC3985A7E9FA74838D9C2AB5B94B4AEF61E1E464F8A834B41838871 54B857595B537C3773F72A31C3FA05E6FD346BB1A25F9945364CF4B852BE6439 0C0D7A17C3AFC016C9FD07D484082375E7DA1FAE4C3DA555BECAED06FD09F60B BA9835A95D6742F2C047C27D22B8504B898F9B72BBF36085B62586F1C905512D 1035536C287E1DFFA0AD5F9342A4266F64FAD8B8C7D1C639D8796D7DE4EDB183 B4BCF3B714A12974177ED54CC456EE82088871323E587E3551504DE2926DE174 992014A78ADB97BDAAB5B8C319E5F98FF95B8389A6FAB291822D91A5A2613169 C03C03C62791002F7521BDECE68311AEB34E0C070DB8C4FF84C12E36121543C9 25E4F5CCFC0DCD5FB9AAE94398981E124C431DE8F5DBEAE52292304469A15D8F 59443BC19C102FD2E84D42294F8D3059AB5AF0A41B61C4DE49B3CFF6894E5F94 98187CDEA6942ED715064B41B3C02766F9F8764572E9CE44BF573D434CCCCBB9 AC4A3DBF8A535F41435919B3A293403EA35776F7D62B079BFA68BFC188058A79 76DAC8CD1F3C8AF5E1A26BE8BA79C067851674F8C12A3B6FB40C5314D24D21CF 7D9A5E4A30FC5825ADD5E5CE8B883507A48B264B7940C0FF81188ACA4AF472F3 22423490D369DDD1D0581688F1686C58D572B1853771F11153C845F80F080D81 AB47A76EC3CF3D7BA425455184D2655988F114C05FEA5915D0D7B2E260AE3C5B E72205EE360E493EE0229C1A6477366CA10F0C2FD0FA4FB70BBEDA4036EE89E4 7465738592A9400F034E4CD4D5E6711ADE40B3A44B7A54D30076F8BC49953D6D 08943730F3FA286F5F98F4101FD34A3C47494EBB9031FFDF2EBC9DD861BF304D 2F18BF4DF0881BBD7F0809CA87239688E8DAEF89E683BADE9CDBEB3AB1AF417C 39BEE509E2EE82474855806841CF127A0B889BBF6721C372F8BFBFDC460315F9 2388584C0BFFEA3F338AEA5EA8F479BAF88DCFA46F268017AC7D2F52C447A6BE 2EF8A61BA1BBC4E3C61CFEF6524600D61A144B64334972D33DAB424E3BAB05F1 38D77F46E4A9B0690104AC979FCDC9285F0360F06E4D570F36CAA95E4B330A2E 7CB7CF153F710769CB96FA7744CC4DEF811D4D6F09F3F1752347AAF57244853B 393870DAC1AAB8B8648B21088BCDC46B34FD86551494001623AD1A3F6A7FC8A6 0A6B91637D84157A05E9D8AE43D41554FBF2E9C962B6EF43C488A3469B8F0B9B AFE21BB53ED0E6BD12F6E02C30E0D1E4CD5CEA66055203B788ED9F77C4D41C78 9053E1056259D56D8C47A7F7FDAD16714AD90BC59A02BD4FA7520AA389F9E21A D3E1BBE248BCD25C201626438309F04EE05D299D168AB4C0EFC86E138E9CA704 72FCBFC52EB71B768ED5217B1A7972021D758FA49FA3435D1D12B412D6A319E5 C6E34E7D9351505246F6F46E627A0A0706AC7169B0302D63A514B0036AA2F0A4 2F7AF9D876F9D4774B40BA16A88A4608E78025386E3F647C937CAF38D3BF0B6D D7D70BE325FB00FE8706CDF2997DC99806A2C5732B9A3605046A0B2C816C878D 30B31D39A559EB91A4BFEDACDD0B5982F30AE7C6F9FA9E68A8CD85773FFF245C B21F3541C27A8A12D80B3D9FB62C8320DE5C6C25BFD3C97B070294B4A77A2B34 4831C3C834A069896D75BD5419AE5D7B3DAEFA423AE83717CB7762A8D49E382E 024B5AD45E541A1B82FD87B960C3BEDDD3E7BBBF423A8A77D9FC0DE79AEBED86 9E24B30E1525DB55C642D2DB5B292518138CFECC5CEF99D24480648A5EC5EDC3 1CC512D5622CCDC9B2B1D44ABABD95F7C97ECBD47B31FE825C44A48948BF4729 FD7D7274AF3108198AB92874F2A6B5C7FCA5EC601BB5668F9552B8B74101E756 01A185F772A00E503E18279269BDBA516F0FFF6BD2F6442ECB5352F4C48FD021 A1530E63E1FDF3CB251232B1960C98ABCBE0115D063FA937A4D9634397215652 D99D0367C22FF302699FE5E9BE991CBA86B06B1511772F29AB55A4902D23AB75 392E21FF98BB309706722D73786AB95FC22DCDF68BAD6F44018DAAC511761861 645A80A7375541EB484259F29D8932214641531E64F26C2C1DADA19C75DEBE09 DC233A18B2D340CEA3BA3767FDA2B72817E2A612B3A16478FD6C57E14CFDB068 283CC65FFD0EFDB08548F918CB045705538D549C7811148A8A70F473F6408545 84292EF2E3D31A345A81476B19AA1987A81FF8AD5DBD4CEB94EB231E7F4217B0 0F1D644CC6FCDB30FE68DC90D34E9575D8C70D1DBC239DFC8C3505692E05C1F7 8947D123D6025522AFF28B488CCEA90F817BFE1F6EE6F5DA3D26461A44C53BB3 F1627D63638F13DA5A23FD4FE5217D17E6151C05BCF27F26F5F24F517A52ADCB 28BDD632B79FBDF5BA55A97622F88E1B78A5E589246E075D986D1742A728E79C A7D4C6DBC299C7A0659AF3681244D50E6587964AB9D096354E724900D9BFB8F6 3143885E2738963BA3D37203E92D21B0F1F1E4DAD2E4F2F83158822366E530AF D4A3925847ABA3CA9EEB79AEA069C01B0E1C2C502742035C4F618C93585EE276 4D8C7162EA96510B7B39ED7A1DB16B76DC832ED3A0A5699C4E6B6EF2F5EB1159 D1E77C9717D7C85566ADBD76C43DE81DCCF4E2C83680D3DA60F1EEB627914EFA 6014C4B30CCA0238FB2CF9AEA8C8089C4B999CEFF1BACE11C314C5865EBE7F96 F6646E6E4B83C6B22B96E3CB55A76AFF4A9BA63C9ECCC70CE9E38CD20DFE936A 0D8F6F804530954AFC85F46907CCE5E805DEEB35A7810E6367670EB783413BF2 6365F7F613BABD374455D00965B10BA4047F71C89ECB6EB41A4BFBEC837416F3 BF69B23BAE64CFF61A5F5B01CA786D2A6B040BB497669907A7ABCFAD02A303D0 52ED027C84CECB0A3399BA5D52D1CB55E10B824E2888D8C49744A8AF726AABA4 C5BC9128A49D12417A72C3A32B9C74FCC530C4E4B612DF03E6F01EF111C1963D 1F83827338125B5BC9A4BDE3B5BED9BE35BC81F44D3BE89A34EFBA0ACCF0C732 1AE5B1062BD2E1FCA3255F2ACB31FE600F1187596721E6674859237B594680ED 5D2822DB9B78D7B6029AAC62B3CCFB8AF9FB58E5D2FC5BC5FB248D4A9D2732C2 D5E75DA98502B90483AC8C0D03ED74846FD6FE45A1A541E15DD5B4576A985018 A21951CD1A871D4D860D4C1870A09FA93F261BD47600D9FFCCAB28AA665B7C82 3FC2722EB5CC2C251EB8C9501502E85DD03BBF38D2B4285ED3B05B005EE350FF 0265ADAEB893A03E31CCFD576647EDD94DABB2794D1963EB039B2D44A204E22B C19B3C1D45D086FBFC260A0145F9F974C5513717D62DB53031294430D6CA0280 717B43FA33EC667203A76F47452B54D0CCB4D37FA782DE8F0181AA5B6D5EC646 BC4608A830598EEA1B3D8D18A476FA735A3C34FBCF439CD6A56A0004455259E0 E0DAAD42DCB7376AE86EB254B065CCC91DAE18FCC53BE209B8476A6548933763 FA17324AA08986E02B3575798EFD8ECBD4B071C91C5BA730209996B4ED834587 3C637BD555BC8B4372BC54EF5BC22DF8FE354689F2514CCA7785B1FC0B1856E6 A0EC6C9A11EAE347963BB60AD6D24AF729D5B9A23C650A08D091FA0C602C4507 47573701B77C3BDDA4FB5543D8D978E4134674E41A00A5A41607C00B69D4CF10 D10CB5B6BBD4EA3951E90E9BEA588AFAB182F92E47C2DD5C8DAE37C01C5DD4B8 3FF5C3572F99D28017FDE9E41EAD6543C5C9F4A521CEF1A52414FC8181884427 B0015400E1A7C8B22A8A6629DA6C418E6E2526CB4403C8F71F3BAE6F1E040450 BACCC8DB63453918AB9FE5B619A50ED5DFD0649FF4F8A5801D5F63A90ECD8727 C8A51A9FCD495968E9E938C1A4B8ACA45E39DDF544108D58488A600B67C48AC3 7AAADECD8F783ADEBD7B98F87FCE81E4BAEA74FD4467F35F1CD74A5301DF7424 66573070CF44CD40766B6ED8D25EDFA79B7AC68E4380355384823CC94F6DCC22 900EA83ECD59A0D6BE248398E5358CB97F5C4654B433B3A998C48B265BEAD812 6201AC4688C23812C3F80AA1B31739DEA4E989BF058FBD36BBC2E5F040CD444C BDC2C6F7CCF3E4C95DFEED490C96694CE76C2F7214D2386918E9AD8CF2C87A56 55950D9022E70BBFDF5532A8BD223D7999AD939C5C6D270B1ECD90CA5E6F2B12 42BE08C289CE0158849FBD38C701CBA7FFE029A234EA26FF891046942DEDF839 451CCF0679C68F0D95BC1F9C89E88102C4CD10BDD175D47854369C236776D8D0 8A6F3751B6DBA177FFD6253CC40FD6BD1A2F736CE18CA738B2F77FBE4C3503A5 D5D536F4562C1570D4DFFB105D95537EF4DAEB5A3DF4AD36AB742C09F57041B8 B7DD821A9C1EA756BD563641256797E7475FEF88420777BB2F5CE0B5F49EF255 C26810B2386B55685734DC3DA8A7729A9A441B1ACAE266EF483DD5ECDD899CDE E352E80527450B093FD30D69BD46A5A8127B2747DD5E22154EA6D2B685514475 40BBB43440FEDBECD5E248066E071D26982CF5EA56F33866ADD7FEC9C5E33C0C 245F0D2820AB2FF3A0ADFCE514F538A78A131B8AF3EC96E1EDB40FEFE0224CA3 C73D51D0C451CD6183 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMB10 %!PS-AdobeFont-1.1: CMB10 1.0 %%CreationDate: 1991 Aug 20 16:34:36 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMB10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Bold) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMB10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-62 -250 1011 750}readonly def /UniqueID 5000761 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5F00F963068B8B731A88D7740B0DDAED1B3F82 7DB9DFB4372D3935C286E39EE7AC9FB6A9B5CE4D2FAE1BC0E55AE02BFC464378 77B9F65C23E3BAB41EFAE344DDC9AB1B3CCBC0618290D83DC756F9D5BEFECB18 2DB0E39996C010F3024A5A3C69C8485664A4E3AA81348AE21A30280D0E3B6542 A770F048F31907891EAB8B57DC70FF775574D6CD26B8AC9C3E64C3631325BF0A 99AB413BDADAA3B51A3E168B03A856EC7D346A38BBB0A2700A23B2CA91120B9D 2AA5BE5A359C60CD78F055253785CC9701F5D670ABE4967D74838C3B267C6563 C9651AC41D8684AD5E913A5C9C547CA225A74782D1AC62020FC38E29C356950A 00E8F2B0752CDBF81EE4ACD59BDEBBB9523AE4764B995855F3A401EB4B04EE56 B10758196CB661448A3617B83CA88C41756EF131CFCE0C968B94B6C69AEC1E9F BF8B21837BC422D766B5089D81CF35A807394A026FE3160580695B1213968D90 8ECD1611E719A871E15C6085A17906F77B5B2DFA6AE670976758E67F8A4FC362 FC7299D85ECC3C0BBAD4649B9DAB4A2FB248D6481CF0CCF274634D37A5AA4DDC 31F3138AAF10998FD66F3817B77060E71C6D8F17205F9C098D81D952E0FE3831 2264C55D73215176470D8D75E7BE6E44514984B9D20208DB3ADD4767CAC09D41 9C8DAB6EDF4FA1AA2CB285CA28E30972B3BFA4F8600DB9216487655F91CD091A DEAA34823397C3D1CAF14A0F016A4EB2A2238881A285C0A4D2850F1D942637B2 A6BD6CF81D1A3A8B0E9ECE37710AE059A3DD5D5236726BF6EFF89C97B4E1C735 DBCA03EAE44BFB56C90EC7472FA83DD86D63E9FF50ABBFE1FC07FAE9ED061B73 6B15923CAB0A8F3DCB7C607594FAA48BC5D060259663B000B14B012FBB1407D2 626F8CAF1E097ED3B0D6C7D927ACF3383909B4E85803546AD4388E63D83DF79C 0A12D51B0F50E18298AB0BD4B54225804AD160569740461E9CD34978CF80DF27 91AB328E5A3A9DC5B3ED72E43204E16006A30BC0BD91E4A31912562A7DDA1AD7 F536A604EC49E630AEB0BC283B7369B0F1257302B9397363C14F4F7BC51064F6 DFE5DF551287E7545C8AE83B2F9A1548E21444CEFE571BEB23F863859552B889 2868297F4440D524301461B9AD27C14D03ED0520298F0A5B505446CE2EBD50BA F0F6B4B50F44CA4DD56242DA816ADA89EDEFDEBA1F86A4E3E7FACDB829A38AEE A1050CEE4FD77E98F8292F95D27CDC38F2D7E0FB9E8A14F5B7DFE8F314940A37 54249155EDDA5444D544ACAE9C60BC571439E5CB179B2D5F6C87C25F72ACBF1D 45B2BED4A68AEEECDB667D6FC7990BC9AA47FF46F658FF693D2B5D7FF0A0C1C0 9E7848241F4C17A3BAA69E76A3D5E0D8032822B26A9D16655D13AAF26EBBB394 6BF6B92D723C65944757C649528CE198AC338C57D48BEBE45267AD4EA83A5165 9DA787FE3F5713606DF5684C6064E536F548E6A88CAE469813245EFA80E85534 4A664144FD1C0D510A387A31FF702EC5B15C09D5C2762A882BC2A6F6112B0FCF 0FE7FEF5888DD5D623EFB82A7A0F9FD4B82AFFB34916E87323343A398274F8A9 D4B53450516853912AA3AC04A2E54A8BC4BBFE46EFD55A77CC0C54507A3FD6D2 180225E05E951287D00552A4996A2EE9366D2CE367BE9110294ADDF879505057 F6B5C2B3E599510940363F01BF08FEBDD0DD4A6754E6C5922E84C70E0DBF7C74 2F6CDEF33FDD675999CC9E6D1F093509997B4805774EDB60663685E43989E227 3CDE1CC58665BE13B8D62BBB40935B450C5EEF490535A98433835DF47855B506 E6654167D1D59EBD21007EFBD4255D75F52451C619B22D1D55E1A6E3C0C9CCD0 1EA0ECE430586B7D4B4A647D8D8C2942259BAF3606DD7116E1100AD551201D37 60D34993E12438AC57571FAC0CC90695415EF48E9A2FCBCBFEFBB5764E5AE060 7D4BCB036D61E04F65A9A79A6B9D2BA4872E258D1463BC3A3D58958B18A9F06F 0B31E1DB2E5718930501F409BCCBA6551E4A83D3EEB48F824522626FB009A1E5 CC96AAE9CFBD751677DADA846B40A681153368C7F153225BC40E5F5AC6ECBC9B 0D426D96D933927F4929471A07679D1A4FD982463AF0A8D78E85526EAFFA6D40 80FEFFA750A23104BA8F27351EC8FF2F685DD675ED9DBCADC61AFD9EDC9C7B34 4D0D4AD848DDCDAA8CFA2D5C381C8400C2768030692E3E552E82C15BC4D37115 9978F230D54B2756CF649D49A42589D3A04F563DFBFBEE8696573E5C54FAEB53 6437B8392780B6E189CD5088BFC26BF54B318DCD1DBD188F163FDCB8E72EB553 06C07CFA962F9EAB5A630A000ECC0D32678C3DDEE05B3C693FD51054DA13F7D5 7834598D68807D22DBB972E817D598E8E7A65FB287F5F5A89335C85B5788A8B5 978A7342CB297AEF067769F89A311B09C9C0939FF75BCE763D92869D958CE2D8 AADC92252259FAE81A3E3A1CB5391F3A7E7A2EAF5678F708DB6F56A62B94A069 AA171BD0B7AD9CD221DE6E216D412353E362629023C87BD96BD3787EE0AEDA83 37F35EEFB07EDE42C96BEF644AE3B5FF3A393BC2D0AFB8FC2F93C391AB84D861 3EB07E0B48B28CD5D318C64A8EF5C958B18C5B564A14E6B7189EED84C36A7D12 A11AD00042D006A273F4B4201EAABC38B6A2DF0873D11DB659285CED7E646EA5 D255DD25B5342F3D6484C414ADD43A69C50FAD76BCD98E7F6ADDF03F9352141D 3687EE3CF1EABC6A649CA746276D9438CCF8B771E2D3E3446560A75A236A2370 CA74531F15C3EE0018452A8F7C497763F7D530228300282309A66E02411B279E D7332E930D1E111B2062908AC8EDA02C3EC044792879ED45798EA6E9366B3263 3F5A4534F26067B39D52214FBDCCF29119EBC2FE5C97E74E9A8B9045131CE84F 183C4130B48140FC0D1A104BF022850BF199F5F07781D2021CF0A47017658CDD 67B245754E496026E5C56E21B3CE7113B399C712577705EF8ACC7D13AAAF2FE8 E99648B57F6541B6680B528F528B6843286E684753031EC5C747836A36FB726E A9D7497F170DD8CD2E30F5A95704577C22FDFD5BEA65A5E3E53B38C400854657 AEED793663F540FC30ACF83D41D72A0108EDC689E8C978734DF8E2E7DC829CB1 FE7CCE081A22D2B9D75567C19E466B3DA271DC69AA31E7ABE46DF50998910E09 10B49722E267C11286CBF39FAE1CFCD78424E1FCA527A3281235E97FC8886821 EA0F6B2EB87ECD163C3CCA018293FE9210B08AAB131A651820CF25A01118EE6B 3EBE72B2544A1879D6C05879A3935C2D399B6627C74290105E7E966482F0A9D1 5028E6F6ED9742BC6FFB7E7252B50DF31705AAA00384A8CB5E817AE4FBC7282C 61FFCECDB4335219DD1FED9CCFB762D96A07CE228FC89E061E92C10882568732 0878F29BBB0AF3366318F4E3EB52E742C3EDA59153C4B85232484C5B71B47D2A BD876A9D69D7973A19E13932442755C1612E7B70B33F654F241EEB52481CB11F 3FD9221D12E4278631D9C00FF35A13AEB06E75C1D8CEC279E9B7CF80AD53C479 E6B9572C0435F8D42A800DC54A40791F865FAB54AB77E0123229139CECB06692 18EFEA3A0EC719089048FA6FA0A98021A81CE5A7A17386FC42746EB613BA9B28 A5AE734CA75A87B43FC980BAB7B128D7EDC66EAD1DDC904A8E2F185C7A252AF4 3413A5415397EED6076F2FE3D8F3F0C5511EEB21C1914DF8565F9D6DCAF48E1E 86C5639B0B60BDF4515F15D27E6FE5ACFCE44444B0E649D55FD2F21D08EE995C 16BBF2AB1CB04387AED8B8FA7D935A3D5A7276075D244973D22AA1CF14ADA1D5 26F3124E85DF035C5CCD94EB2D6DF172AD7CCA1526D998A706EC73F01B748973 ECD5C528F42B4B0B53A7B3295F08ED1B93652A2BD3C3ECCA9C44997AE141151E F6386C3F6B378D6386567BEFC8CEC9FED26B74E7DF2B6441FCC8CF6515DBCE47 84FD6D286D001631B1E6B114C105C4379ED596FB627963776977EBDA37C2A5A5 6F14DD4DF22D946B278B2B963C9697CEB5A44B9B397CCA831459BF0B2B50AD32 B0FEE2BD7917D7165C89DBFA2F36DE738213B945CCCB1334B1731E03AC4EAE88 3C682C7521D5FDEAA2122557817F0A0169B15958D7252B1980332DB5DB1D7C0A E4D571D41D1A43CDF91B6E9FD33095536B15F0435D833FBA9B889353B03ED38F E66829F218C8FFCF927C4DB5CC7FABD595BE33BFBFBB8E0C7C1027C1026F8ABC 059FB0A9E27B7271878A12057E6AD856D2FA452DE0257F02C831479A081C2ECB 85FCAA507B9100F8BD27D88B1C5FC25D26CF24E887CC661E259710A92240DB77 592824BBB07935A6073090D061C2DDDDD2A24DAE5A0BDEA34C7B1C751E46EDA2 8A22FE668FFEB0EE30F3422E6DE1BFFEA682DD0268CF683BEF8F18114B56012F 9F0CFF6BC7FEBD23066FE6995FA9739FE495E02B2120735DA85DC8CCBF8962A7 F66F5B9A0A22509769E94E300B9D49CACD672FC4D91F7BD9F29E48CC5D2AC51E 3119FBBBEC1D9759B7AAE843FB6B3C9385F337F61912CD6EEE90B6C6A8CF4207 6F50905F63538BFE3D96D6821A08209F5915983DA40E8CE2045D2EB22C63F9BC FA44E0BA20E289A998315DF7A857FAECD598DCE24C9B2BB6D6330C978327E015 0D5D57509423D90744917D0D023502172057154F30C3A8CCA214252F33BE9486 5546151DBAF14B069661F2ACDA6112EE37B58D8B1F219A99BA0A9F3F5B44AECA C273BFD7788373C0EAC66D120A5DB6F9347424B0334C3C1D6EC12F5FFE2F1AC9 3039F6C34B0E1C0BEE03F26EEA7F436E21C83F004241621234AE1F87C7F73288 3BC35610102CFE75160250D10035A3061679BAA77AE51A11575A4C7E2B22AAAE 270BF890F33C2D72E9C59209A06A66FAEEACD5FA6635A83CDE2BA66348A0EA35 4460B2E3DC8A850309316D224CD38FBAD1B566F7E6E44A5967776B5ADAE2ACE0 5FA6364CCB3BAAC7C22C0952776CFF3AEB5B99BD0A6C49FA8B03A57AF8629AD2 E2824A23DB62484216A2E3391F8F0E762856297E1111FFBE3DF568EC5A5D4547 FC6B8A2B0567B1CB6CF1F4AE23B609D0AA57F3EEB2734368AC20D84C1470A3F1 E4559F49116226556BF6302DAC26B11E7272FDE02943257017D6BEE785023597 CBCF26DA8B32F3C4CBA332EA15292DF2A33294F7C786415178C6598B44839745 9DA72D53271548E460567635D23E23821E9498469B455249185743420DB5FA5F 2FAAD1D367D83171B333D3717E2F9AAA6E7C0A5F962F10F299294760D0C7433D 7B70AFA0443D00E650C8FAD1191612575477B622B28D191A5405EE9EC4DDB500 667C5E4D13BC48A72FC6196FC64044E8726527115E0745433B789B6188F18E57 435833DEB345F986C4678D3ECAC97418491607CE0773D4C2E69F78352F15DA61 C7880FE5E13AADF366581CB17BE3D683E804CF1A23D7D1644D6A120A3BC3D3FA D795AC2E579A91100C17BB86D7993633419941D0854FB2C017EEECDD9C39CD42 DF55720C8838B91203CD0D194459225F0AD91150EF11103DAFB257384CDF239C 65074984A77BE0061CA1F1AB44B22535285D4C165520D02B2BF7276A1F1F4A26 2AB0F073F9832100A9E594DAC4F56C74DDB8EB020DC16839DAA1A10C4F72409D CA0382747A349B8311AED49B0F020261820E1D528AF5005CA35E8F95BF8327AD F8C63EF59374E54D699B2F39A9A32653D1B12F613D377B74675D749E5E5D7301 F628F2E1924EBFB690864081D4B511F3009F26CD0DF67F0EA1B0F5BCD71EE90A 725FF697C8B3C8DFA5822FC02AC49DD5E5F9CD8FDBDCBD2EF6D4FEA376742894 F2EBDCBC1CCFA0B1B9139B924F5862E89F4026155FD1A9D64AE0C584AF2AABDB F7ED344069E15659035CF46621E612D4F2C416FCA936993B18B8C3176C761363 18A28A9737785A95827C62F58219B4C96D140FF7D51A1A59AE026BCAF9C9102A FBE3D80F0F5E6E64363A19794F4B192CC9743C875D26AA41DE5942D9E88191B2 3CF4AEA168324071D02F000BCA66F661A853E878FCCA4072F4395D8ED182589D 34EF77277DA593E23C2650BB78FA028A9A711B8BDAE0A402855521F2BFC7812B 6FE866288DE077F06AE188FE41A16FFE53507ACD481712A9CBDF37E3D2122D7D 60A2B7B87122C787A48BA25BDCD88BC6506111CE5C0683A146BE83061A0605F6 C773845077E753C7C9355A92F3D6DB397F0BF8B6A61A5BED668439AF0E3CC001 1C59CA62CA43D5128410A432A5B8A87102ED58B7FA9568A01616808003DF4F86 FC797DEC845435A9102EC236AC72918615DB6BD68CF910CF30D52E6EF4683367 04BA36438321C4747CB93A071C1FD20A6E0654781F8962F573D2DD3F1FDB54D2 99B42C63CBC9FF6E22DF9AE7AB65F6158831FFBF5B57F7ACC83484890910716D D4812D42FA2B627015FBA1D34BB88CCAE470ED47DCAA7F4E5FDC94000991FC37 B8EAF242771D81476FE3690623750DEF36B81A46C49427857C5CDE8D51BE1115 1A91109D97892BFAF014F5A7259FE3667CCCA086501C152CA37EA5B8C2AF16C4 E45B4FA1B034E70256128A6A80880CB1097E1B56C051F962400107383B802312 FEDD9B82EF206688868574D89957AE06EF21E815BE4BF2728A80099D3A054D05 800FA19EC2C6C67B259A23A2606CB158E05C3847B803B5718DDB04F28B6603BC 5C075F28D642C398DA65FBDB40D4C39B7B4100118BB41A323FCF2D09962F4F4F 3F9367E3660CC3D3F94EAA58A516C8D98434C6F0EA34509638FDA6D8DC63DB48 E0DA133A618BD9CB8508FF7B31F9EBA219505314CC4D1AA8C84AD100F0F53B9D 6EAC3CA9A30B4A53A3DE4FDFC84D33005375B1B3FE533977A0B0ED792816EAC8 8DB66CAEB0CEACC89E5BFC2D365F4D572E1517E35EBF334D5887301A16554EFA 72B25DAD53F7121D4E6582BA6A552488318B3C773D3E238FCD83204CAD03DC78 64E64B9ED0398FFD9BDFCC04070FA9792F639B57A6AF9B1644EF112D2CB15875 343D26EEBFB9C1649ACB67B16300191A7B44F4FDDEC5D77F435B2AAA32251AE9 1E240968927361EF9C0C37D3B5BE8025F9C6CA5D2FE2A778A0E25D4B21F8C2AA 5F04973BD24E44FEA452A4F484F24BF7ED38D0D65065B8184C14296B95B7784E D215366C114E50809EEB82B6050AD9ADD7D53AB96C00CA1F8E58A3236F0BCEB4 1F300F252484138704E25AC17FF142E749F648356BE483E9A9C712767867E302 EFAA452ECC5D776B54242E0460341AD6FDBD43B02CB0AE854CD179D52731C572 C12B2C4863A0AC35BA23B66124527C1DD89E3AE882630DFEA4C968952B47F1C2 1AFE6487095780FD2543374AE3FF3DEF92A29A566CE877C4A111389135215DFB F0652F5178F047EA25D9E5633F4A4560AC371DB1ACC2224B25BC166AFC6A16CF 3F6B2DC04A09B75758879B1EAB49973E7A0F50395171D3AFFBA7F18256014073 064E1B37C1D27AD03765FE633EDACEA8565C3E52EC512BFC9AE12229CDE987B2 52F4535EDE9268C0A54CBDE5B86DE38A1ADA6461D19B03C840E41C9ED007385A EEA3567B9B72E610A81FFAC08F4C0250C499D25989E61C3402730A79ACCBEC81 957B9F188E820EE15EE52F0D743D03CD3093FBF1A4D2259D85662E0D236430EF 84546D9B9911184324884AB349915AA75731126619F3DD903112D0B770A2F17A 39BFD582E492ED058D923B91DBDDC9021AE616BD918F4D2F05BDAE9057285593 7559AA6573ECE7AFE19FF06A6E34FF667808E832BC4AFCB3C2EFF15BCFC80A36 DF5AD90B7314F575BE503D11DF6AA4C1DD001AD3B636B9329DBB70821AE39A5D 774FC7BC49EA9E88A8F13A36864F823EFEA9D40F46ED735618A24B1841FEABDD 6821CFCBB1990F2AFB3F7742619CE40DB4344EEF7657B9C887EB1AA118F65289 0C092218C14CD13ADCA71960B77BA8E5155A5DE00AEE81A86FE1D86CB14862B3 F3AEE8148570AF00CE6D482AAAAF2D1CA29E88528B3819507D0284CC0560F6B6 116BCFCE2CCFF283F4B8077027300E38FED0BA1FA898AB02A5EF7B0E56A64279 BFC4689BED0602EAB6770F77638F032163288D2F9B30CE78E8B17B1596AFBC1E B6250646D98B9D2F75DA762A9437F1B37E57DC014A436C90A02920738E8462CA 30A0CDD07E6DDAF01A908B796CE958EA1B965FBB75E16CDF58B9FF13A5453D60 12756203A3048BC6931D70186D13A661B9B131569F02E5DEF90000AD69E96A5A F19B5748CC64480ECD747891B7FA20FC317ACAED3184BD208A7183BEA72519D1 AA8B98EA2E7758256C4456BEF3E1CC0234EDDE65E40B60715258523E5616FB73 4809999E0C184FDEFE6416CF9BBDE270789139CCF198CEB4B10DAA3B2B29B138 B22DA39BDB7F176DE688BF57891359B9D923575E1285F7D994A131954320115A 1431A2D3132AEBFE207A2879F13B6C50DC3CB44332CB8092E36B67CE51B11DF0 804BE0F0AC7B066C665441EA9D8F0FDAAD17B3D1C92B9AFDA1EDFE51FC471767 F1CFE885AAB2275C76AA7C48D58AE07901F4E2F203B6A63B2B2583355265857E C1AEA9D70ABF17E9702BAFD05AA37C2CA5302DF09E2ABBFACBECF515C6B7CA87 8727FC56BD01D55B7D574C39B3D3C4D14B80877B773F2709F2C229E0182CE6EF EF9896F45AD97A9E45489B55D8AA879CB5DDF180991E3BE49FC8191D5EF2A70A BA349559ED5A055440C0DDB6080A5295E4046D406BAE50B1FFB16DA31BEF1AE9 E0E9EFA9A2B34F50D56B80790C8D402CCC1B2001EE7C2D194E3CE3B3069243F8 1725008254F21741AA0E3D2C91B5FDE131B62FBFFE6BE85F82B6AA16340011B4 0006AC5DC9C21EB227FE4F866BD757EBDAA85C4C84BAC9216CC5B920BDC3EE0C B679C5F84A3589AB26788A00AA5C433FBF8C3E3074A0379647157E7C604C6EA1 12ED2C62EC9B828A100458335195CE87F59B1868A19FCE6250EC8EA22F65A276 1AE8B04D677750DC6030BD2B4BE2C7EB954657BDCECBE3898A0EEA825AE9AC74 3F102FEED6454577A56202D4ACCC2F7709AB84CDB5C5999B22D297D1F44F1ED4 E759F4AB6D74F744769407DCF30164C8C196829324F542C9C43C53956ED25864 A78A513DA0BC52C526753CE02DF67452E91F4EA09D79DCDA952C318110228935 431369B6C7A0A7CED61FEA98AD1F9B7AF92B75E1A2AA1E482A088834A6004E06 E52272B04A341931F509F0558654E8FAB9A436B4C1C41A5116F9230EF42E33A8 DDEDCBEE64334F0E6BA89CA66FC02C7A0254053CF7B8A5B04706E4FA4D4E719A DD2A972E4FB386FA28277C65FD80C53C20D14A11B7F1D92C2FFE0C56A450C61F A779E0A2DA679439D92C18BEA0AD465DBE318E32A053902F3362B9B149D8D6C7 C3EC51F274EFF37FA199AB2B19D3EE750F664B9E71A5E27C54D4263AF997B10D DB93C6437014545C06C011307F6A15C2603BCC3586093A2616599547D1374453 0092C9F7A0A2883ECF0C554B95E5A90EDF4C781BD52ED6112200F34AC597ABC7 02749833899292E7C96866232A9D35713682933D6F2E7DECBB02DCC0FFA5C7C3 D799C3F590356BF451446A3CB4BB64812C8C844D68A3CAC4E91212342324F78E 1011CEB067156B62C77B825265B0740EE1FEC16B52E0E97C4F606386D0858691 4ECED83ECE0B499C547C2E18C085F0E370376BEFDCBCD6C00DD3B1DDECD405BA BD2BA4C09AE20B9A506BF4C6A82D5524820699AB8C1F658064D9EDE9326B4BD1 703B949E35190DD6DB5E0A62F770A489AF33AC41B5DC3F765FAF95EEAFCA893C 019CD03DEE5AA1B9F07DE7A9CC2A992DA2297F35C8D4CBE3788B69E4E22FA168 A4FDC9F9B76F4A4FB31DC217BD950A59C9D0D7B2539AA53ECBF72A9C7D0A274D 025F5FBFA431AF8281F6BFD7BC6FBE2D34DAF10DC70A54394C00E3E72F07997D D23C1AB5A9B0D8F78262F2F5948971755EDC8AFF9D4BE25C5FBCA4F3C327B9EB BDA60FCE0120BA480AA15A1E2DDA622FC7E648C9E06C61C6AAD4AD3AB77B8EF8 277F785B27963CC0A56C35DDCC832391745D068E1D82B4C33318F425C6B2BBE0 C0E0C76E711E290D9E1D641B2E3113EEFD8899D54623C8A3E5B2510CEAEC2505 A156729C72D66AAF2AA0880CD9B20295324B5F32360F3273FC1C47C65EB32733 35927B9197F2665E09C446BB749EC5F0E93C2A6EB7E56F422A37CA75F5FA3216 B9996E311B29DE26B9C830FD988C9B44575A4A789BEEA003391E4C026D32F059 786F89C99A84DAAC0B06301423C52DCFA61F064E61C8AF802565C05DFE5C2560 D716F63B103D1107738AB1A290CCFD8C4EA605DD4BFA77996652F1819178546E DCE4BED0CCB73D7130853A6F6329A77FC873EA9042C278CE9FDA08EFDC94129B DDB369FD9E01E3E07712BD747D3F44169425D1DDF35CE6130E71EFE00B9827B1 5AEC3A3C71B0444070C429E925FE63B104EEC64241CEFA5BCDDCEB60B44CB569 CEF43517AD45FF5302ED9A76CCA424137AD576D8805E0213A29163CA8430FA6F 292882CD1ECCCCFB48077B21090899361E6CA5DAAB64BB82904F9A990F2F795E 20D5EBF02E251DC5B7CBC98BD8FCBCE135F3B01BFA4117FF9BB629E0D90D735B 90835994737EBF585958795952A4573050BF011565D6415E7F0880494219CA1A DC9CE13AA936F55942EAC057CFD5D80E2794148394A3A4A1566AF291D8A06783 F29E245C8FBD06D5D8DC68B3F2F5501B432C55107FFFFE5C3EC96B6E0DA23324 6DA33C0DD6F28BC42F17D13B152E9CB51A7D5164385EB7E3660EB2624CF9094C 42CD2C461607DA34CDB54946F3CF0E8985BBE8BFEE444065F8B8419A12D143F1 414C0288C0EFE88FDC2AA8B8E15EC2042911A622ABBD6FC65AB2FD0CDF0DFAC4 3A3AEFAE183385AF4692E6B266D0C97A04F8E4D97BA0C21D68D0EB53FF187D8E 3D62300D7E2F55892EB5F7DAF7B568DDEFC0DC301AAAE2B5366B87536686C871 1F922900D49D9A84E1CDA2D9C981CC44F20B610C45BDA575B9DC29AD28B8FDC1 D92C389DCB55226FD641EBA76FE6DADF069B26116E56629526465F8BEE841E5D 930BD889DAF73D39BB95DDC275D9EE85F0375AE5A3128A676AED4CDF92880CFD F9C3528D028F453E8E70E70BB0EC83ADD293FACA5A8846C4E5536D9B7DFB8354 C794A15A5403CE085864B2DA75EE565C851F39614404460631F5AA7D98C541D8 7FC0EE9652453D9EAA180252A1D7926B831CAD0569B60ECB109BEDDF22B8D1D5 976CE32FC73C114F1553C057DBE18DCD4EBD5BC71A84B2EE823390D6CE9443B7 E548A8C917910955B8C6AEF66615A01871E9D08495633E1A957299B550E7C129 058DD9677B415E47D34280F7419E891EB7D572EF9E798934EEEFCA65E9D4D11E 177534D0239960CA420DDFE08BFDD3AE08B5BBB9A1C53555A9BA56198732206A A395E85C2ED8BA7D573CCCDF9A615FF578C0B6D96E0A2267B4AAD84EB2583A97 EE41BC6376EA416E07E9C88858309C5FF47F0D1B99F78CAED87A1B1A0A20C965 B1939F4CE4E718E4A2DD6A06647631341EC96A7D12A101892A383F24F7C1A4CD DE1CC0E9B50E06FDC97C5729F952A2E9C3629EF2CE396BC47EDAF868E0C2E11E 0BC11EE514C96B9989DB79206F5D691144E64B0A9A992A15FC613EBCFFD5CFB1 8AF2CB6FF9EAC78FDD33725674837BCEAA45EC0117132C6D525BCC0BC9E8DC15 09121FC65933DECE 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMTT10 %!PS-AdobeFont-1.1: CMTT10 1.00B %%CreationDate: 1992 Apr 26 10:42:42 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.00B) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMTT10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch true def end readonly def /FontName /CMTT10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-4 -235 731 800}readonly def /UniqueID 5000832 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5F00F963068B8232429ED8B7CF6A3D879A2D19 38DD5C4467F9DD8C5D1A2000B3A6BF2F25629BAEC199AE8BD4BA6ED9BBF7DABF D0E153BAB1C17900D4FCE209622ACD19E7C74C2807D0397357ED07AB460D5204 EB3A45B7AC4D106B7303AD8348853032A745F417943F9B4FED652B835AA49727 A8B4117AFF1D4BCE831EB510B6851796D0BE6982B76620CB3CE0C22CACDD4593 F244C14EEC0E5A7C4AC42392F81C01BC4257FE12AF33F4BFEA9108FF11CF9714 4DD6EC70A2C4C1E4F328A1EB25E43525FB1E16C07E28CC359DF61F426B7D41EA 6A0C84DD63275395A503AAE908E1C82D389FD12A21E86999799E7F24A994472E A10EAE77096709BE0D11AAD24A30D96E15A51D720AFB3B10D2E0AC8DC1A1204B E8725E00D7E3A96F9978BC19377034D93D080C4391E579C34FF9FC2379CB119F 1E5BBEA91AE20F343C6420BE1E2BD0636B04FCCC0BEE0DC2D56D66F06DB22438 452822CBEAF03EE9EAA8398F276EC0D92A7FB978C17805DB2F4A7DFBA56FD6AF 8670EB364F01DE8FCAFBAF657D68C3A03112915736CEABAA8BA5C0AC25288369 5D49BD891FABEFE8699A0AE3ED85B48ACB22229E15623399C93DE7D935734ADA DA7A1462C111D44AD53EA35B57E5D0B5FC0B481820E43222DB8EFCD5D30E15F9 BA304FA879392EE0BCC0E1A61E74B3A1FC3A3D170218D7244580C7AA0DC65D19 741FA5FE6F8CBF60250ACC27454BBF0897CA4B909C83A56672958752ED4B5E79 E18660764F155E86F09EFA9F7685F2F5027EC85A775287B30E2069DE4E4D5712 E7D033481A53A2702BA7542C71062173039030CF28D8B9C63B5596A9B42B33E7 D922944A38713383D3648A4AF160A3B0C8F3379BA4372BE2E7EA49AABA75AEEE C5DDE1D8BF68483C3D21271280ABB91D54CC819680322EAB72E1250A760BC8DC FF798F2ABFC4F3539392985C4CB324B00072295FC160818BB0355FDC4F12E39B 984826450553E3D271F03D8DC2D12A92A4D32034FD16DA13B876D88C8C097384 46D8D7E41CA1A8979F9B07EC3337E70CBBE3A377235B04C79BBBDB66CE1C1A41 89DAB7CE91F2FC0CAF6DDAD09992D56F72299068192610EE3DE5DB7CF6366B4C D74F414484DCCDBA449BFAADA39D0F27574E604E31CB513B18E3821A33076151 C2BCB6E957C77A0AECA48C587ABB5E8C7624D56B32F80BBCFDC874AAD6EA5119 C9B06886F08CC7DE5400E0F52B07483FD4BAF26C1556CA27B259FF3DDF71131F DFC05D8B14C28F2073C460B5011B76D84F7917E919E50FEF563B5DEBC5CE6923 ADB72392C98D03CD978D3FC207A52B91E267E7ED8BB4531E8BBAC113DA68765E E23FA502BC71CFB91E4FDCA39BDAEB7FEEC3588B1108CE4A1652B770375724A6 508376586216289093485CDDBBE68956210B6FFF3953D097D66BA31D19CEF2A4 35A33AE97547B81426E58F9FFECAB633C6433E86C32130665210F44F10F3A2F4 EA31540D0BC08EA4DA2DDE3E8CAEBE52A3E8B037632B235D4ECE3CB797A5A939 12C45C282783F675060040FFE2676A7ED903798EE3B86644EF30D3B461D4EC3A A1D2E95C02FF1531D93180F66A13E868C9E1FF1722FEF6C4F304921961D4A10A 6AE943157B1B0E8871BEA71162E5246080618A96D5B23FFA8F420F2AC74BFB60 BFA3BAC4AC3A320887D4090FA3EF7071D2E1DD5D70DB98A01B6D315271D10F2B 3D9256D96FFE8D8BA0F4781B74490C63686397241640B08A08FBE7CC9B1FD0A8 21CECF0F994CC97AB18411EC8745F5A6AF56010C22E73CFFCB45B82DB68E6552 2E57A4C06B96C55031442EE1F53373C50E14657ED320D9EB3820144C7EADD2B7 564578EE778AB577C5BAA6CB7F9884D91F1EB53F032AE4F0A8F47A7636AD0573 00083304E10F77C0B5C7C390F436CB4C0E68CEEE4B1DECCA113BDF28F21B61C5 432899378C52824F854212F8B53B75ACBAA50F74868CEF45E8807CF574DF2B71 D37AF61581497D87076740A67F6023199F3ABFD651B2944306176F7AB6659154 7AED74DE897275A2033C35108B1F9153B113B15926004A87B2E9415DC4E3FF43 37E1690D9608655858EF65FC29E1909B2FB2EC1D611A14B3227111E903F1534F B37C2EB3064720BB08497C43D8C0D163A9C07E6B8574D344B27920DF3978B879 308CED51A761149CA2ABCBCD1503985786DBFEAFF4EF1AF192AA02E8918EDFC0 6EABA11C62E13EF728B85664ADC45BD5560BB2D59682660ABBC6856D6E1F6A78 870B3C39CFE66D14295878E710E6CFFFFD3C373C0A229464DA563E80B97CE7D2 B218A582BBB9FD8BAE8A3187D2EDEDE4F3659ECE579499B892B750FA51AD0BA3 A99ACC4AD9B10417CECCBC6B6E41FAE6D168744F176E3C76FE8CA8BC0D2BEDDA 347C3AE933AE9C4A211BED2BA3DCDDE0D56FAA5B34127A6FF58CA903EAC47EC6 67676448843FC96A028527C7211836CE590A951162A2807482E1927308CE208C 8292F82CB777F00A2FBF6D7D5CACC7D4E71DC0583709F819B5B5E81F4ADA8AD2 C022A7E8FEA7C90E3CD88A89F24073D29DE4A00FDA0E570CFDC085CEE15B528E 98220AB21270688FCB75154C44A42D7CED24E2113FC516926F7AA5AEDE41F427 32109C2411015BB654DB0876C825988A8462D4DF884E1C542AE54F6BB58C4966 3BE0741DFE5F968F0CA5FCA3B28F72BE9862896EAC68F3D39C3458ABE6FF878E 92CABBD035C6D72588E580EB7F6270638632F0A37C23A158242D9E1A61D29C18 A053BF4A49035A21082EBA3C2F27E138CE0B41E0F4F2E9FE149E210C3045A858 1A7B725DD36A7C71983FF926D21DB079F3F31CC21527AC4389514ED0833A9CE7 FA2126AF17553D1F407B39FD77AD1CE295EB544752D05EAE5B436FCCFACF3795 44BCC8B1F346838E54E4EE284F5A197FC9FD54CF4EA40F36BB1CA2534FEE739C 5EEC641E7CBDC619B1F0365A711555E9E8D7B86785676FCAEF9D9DB995202EEA A4F76619CAE22EF33153DB3A28FFBC1667B1362EAD86B51AD745942C4D530251 96F9BEC4ADB09ECBA16A69397A7CC3971046294EC26C1CEA55E7A7F3AEA76228 05FA758AC47BC452C62CD828F809CEE74B358F8948B72F7B68177682584723FC A79C33DF4075CA19F578DB25AB881C25F3EE452DE3B55AF1AD8EBAC9C46CA881 92AED9F99F70FB7167035FDAB45496AF025BE8CD11F2F8AE21F2B323A79BA9E0 3CE18A42C4120E345FC1D52E968230BE3EE97E3B19FE63EA1EDBE20D7AD6CAAF 2A30D643FF25841B68B844FF42C765154BA8C0F0CE1F04EEBDE294C63AC20893 A59BCD63C29D0844F9A78CB72F77F5510BB13E80734B1495D101CEC06F2475DB 431A749E7150D3CE0DBA39071A316E1C0548FC2CE8D9E6B728C3DF7E6EE239FA C311EF0E1627D40FDA9526697F5CC26939319926609AC6C9FFB127EAF9CB060A 06FBB07A54B2448FDFCC146266F818B69B60F891C885B3FFB46E8E527FDC4DBD 5B31321DBB142A40E2E644F964DBB904B1A4F6A2C259AA4EA9237BC330AF4887 42DAE19710CF04ADB22FD4416DF0F1AA66B3CA92452CF7FE58FEA982821ECF5C B911CF1AECEBA65E66E98952291D56751F011055C5469A0CE5279D2F1B71DA5C 839CB6877C6699DD16EFCBBE6DEBFB9D3A621EF0ABCAC860C00BD92E9E40E675 B0131C200A3FB24AAB78791B22C3DF5CE8979A3D5F278ABD105A8BA4843D2185 3C6009E574A930C020B407697CAD7B0A3D00BE68BACE84560C7B3161440768E7 FD63A1C0799C938334508D70A686D91911BEDB28BBFA86A0DF568B4063D9101F 633EBF679C9878D524F10316A23179F9724413C2EB2F462626F907ADD6B9A740 5E9984ECC46D8186B659549B556D7597A741C681CF5DFC75E784814C7F46220A 551CD86F69CDCDCF92CA9FDBC88C3CA5E2869D4685AEC04BA1EBD9805F97F819 4A0D2ED49E5D43024C6CA212B98F0B73EDD1EED9A650C936FEF995EFADE7EC26 E230799F4D75AB15E0335D9466977D41E9363F6577C1E77907D727C132D8AA11 236360D32553DF3463ECE94A67DB87C6AB2ABDFC3493BFCCACD1ED4D0FCF5B1B 18271F80CC09DD6E7F9D4406319DD0947763E2A3BA282F6F1EB92C049E39FCC2 906A1555D70B068AB0AD5AE1C8ECDDDD6B39F33709DD2D3AA3B186A5A3FBC6AE F5B026AFD05D18AEF68FC654E6CB58A1C6CD4A62566E8F5A82344167A9108660 2CE3615CA696F75430E5E1AD6D3ACE312FF4C5715B12F67E2487B3A34FB5D4CA 147644F48647E93D06E49F6C930EF4D2B1E32336A0452EF87B9742DC60EF85E9 241E9E7EF819A8461705A69FA8EFE0CBF50F3CCE3D2B58494C61A9EF8220E34E B84E09B002C3B69BF954DAA4003F6C44E8B8F4488A78CB5F9C5B36EC0919ACA8 0F2BB723B636DEAC6EF9ABCB9D26519A4743F09A88B24F505C678DE09BE27430 1A271B6BF62EA28D982767F80A9CBD1791DB3F57699D1A53F548B318C54FEFCB 25524352FE0F2C6D1D3319A629B6EFAA8318632120E874576AAD7B89E1896B02 DE2442FA9E49B71885B8233B7700C669AB1DAF8E197EB3977D8E8DCBBB3392A7 02F6026253C4C377D6915591A9F51A2FB6A420928931FA406A0C15664BC0ACC2 207B1BB9A2F2DA0A9DCD21000A77B642C0BBC4578BF17E8E486E9CE7C96C3AA0 6CB85D01DF648F9657AB0BA41C63E9CAC59F4187E315E428C991EC6543C91BA4 F275C2AC6CA815FD0EEBC07C4E1AD9C088F972FEB3D827256096563BCF134B5A 355CB05F6BED21AF31577C889BB1FB5D66D09F5FFCE84252B3C4A57689814C8D 9BE1B0E14B386CF5734306D1B9C3D1A77F90514C4A5F1CFAF1E683D838A5EE5F 7F10FFF7CC69CB544AED370AF4DFD64F32D316B05024B6CACE166E1425F7133A CE74970FF8805D140154D9563396693D713C5B11398BC556341FD1036DAC870B E967B7CBE705CEF0049A4A31CACC9281AA8D5F724E17A9BAAC56243895057319 C3756464717171DDB26689EC31479B007889E1E55E9B920CA6359948F6D81BBD D5E21F83035BBE51308B2C05B6566A4F6A15742D772D2AA659C7038750209575 4880727AD84E7AE6DE0EBFF90A51FEA2461794FF7C4096C6A0AC8490BE055A22 55E9E8794A768FC91A83E1E1A5ED84882C846AAD1659F42FC2F2F3FE315715C3 F741323C61BE828CDAF4575336549F0EE02BB9F2BA02E197DFECB96EADACFD3D 6BAE0380DFF2FF1C20450CED2EE3711E9A6492089F60203E1F83B5F6B750B869 73F94C9A6ADB8086C79EF9486D58299251BF6D1C1266EB5DA02EFFB8A7D71C59 36FB29C0689F9E00ED22D443A8D11CDC57422DA79FAB2F9A59B889FB1A147783 CC23DFBB25EC289D559CC4DF488BD0EFAF8DB8FDD72C3C2B5F99EEBDA81CFC86 FF1768FEA60A33ADA0CD9644AF8F3795C8603091EA5D311DA0A958FDB4D921CE A83354621CFCB4D0178AA63A692D8BC687AFA1938EEFB5CDAFE3F217D26713A4 8CCE9680E40BFDEE641CFB2AEA05231173E05BF7DC8C9948F9FF2BE99B580755 47BD22153E2B4B29C0CEEBD90CC181C2EFDC1087E0313C20570CA1A3706CB95A 6718893B15949FC5A0FD2FA92A5673AD9E7C76563A061B6C088B998D55A3FB9E 31DA688FB2C44611E334093F5D134B6E992F76ED9910480B35B6B7EDEA7F35E6 8FF33E04E91384463F3C4C26F11860D233B04A8610E3A0E83E14012C2BA7389A 2D69EEF7C53E1026068477E70DE64A3C32C4B6DAF35528ECA1BBE8C7474136D9 527A09F4FB39ADAA4509C8933859B30E91D7290CC6CDF5AD0E9D9878161FA3AC 7101D9E18D36D5A7BE70572F681FEA1D2F34D4147ACED97C6E7DE66BEB0D50A4 BDA90B2DC69A696D0578B09D25BD139E2267915A939951ECF41C755BA70B52AC D5A2FF5B2BE44766B563553FD4C729BD6BC34BCEFEB0798FA06AFC40E269101F 5AAA850798BC64605B1FA191305F0EFF9C78441FFECBCE508EBD1834992C920F 9C8C6EF088BA49B1E7426A4A72B60956B177BA8AC1DEDECFB2E366004EE0D899 6F73BF92C73B6C15FAD02D4B05EE589BD015166B0848D4558905ABF6073E8F57 3BFBD85CB8A869C77BFE9AB5EFCF274697ABF4343A673325766420A6797C18EC B8A283A3A0F8B18FBD793669CB57EB307CD79A5418EDB17A280912EFAC0DFD21 27EA46073DEDA4A4A35F116813B688F817C2A2C8BE1ACEFEFBDD9F9186714953 35B652E8AD2B20B0171559D3828131B4A00EA6E87C63F9240ACF1D8C61DADD05 C748035ED1AFB2704D3259F4546EA746DA376DBA008F1F257DD63DC652415816 FDD3BDA193CD3D206FA8027C875F1E71E9A90E1B31A5C7E42E25BCC6C22DAA35 A9C99BF5A1F50A0ADDB18F630F3F852DCC83EDEB8363A11F5F28D791F77E9C56 52EFAEBDC956EE0025994B988DB4239FAD04D3345819630EA6336581EEE0CF02 BEE975186CC5AA33D7E484F0697D1044B34CFE745A93EA511CED68800AFDB088 C7FEDB3ADF554D6CCE2A2696E18CF22BFA1F21034CC7A80AAC734766CEADC743 2438ABB803BB24785558E464DFBB0E9436EAF4AAA412BA15898FE5AF21ED5592 F1DF14FA29E5D9A168F686ACA70F1021F503CB484A0A3DB5A5B98A6BE40F5E9F 2608330F34A77980594B354BC57063DCAC5E94155B254CED4C56DAA9A07FAB4C CAA611DFAE786FD9625EEE24D555519448828108D5EEEAF491251A19D680D167 FE3DA57758E882A551D3DDA974F7470FE3595C2D28842ED744223424EBC29A03 4B8DC6866C6EAB9FC3D54DC9FB587D00C9D805D2336A8B826C120CB7C477DE40 E64DD1983D8F1F32D1E5BD134DA2F9BC7BDA3986166B5E4F118A80606E72C6FA 0B0FAE65596EF42BE07AD0C1225BC0DCEAC982FC13A2039978A7A88BDA1879B8 8982FDECC64F1079DF99B175909ECE8A0A484B50BE407A8642441C6F842F6D12 3BE8637CAE870B9BE58508EB591B8155A422BD3427340CC3615B4C4B91C768D6 B6FDD497FF04CB72469F58C413C11B4DF643FB849E645DFB42BBC1B8CE13AB94 D556718AF463C898367E800CA0F54994EF9D87F4F5C993F88398C17AC8903997 F49D2E269AF3192557862FC104F84EC315C04276A1DD512E4E620C08447ED97D 5C58A39F5F99422C9D63DC9CC4F8E000B5057E8230F360EDE31E06D53730FD07 12FDF9924057554ADF073100B92588B8E3790068FF94EBD8EEB74E4D4CAF2014 A5908EAB6495F0C2C6BB8B399B5EEAC6D5F31386A59B44959DF4614F223B853F F662261DF60C8117C8D87F428207C1559E26A82085DD5E61469E456221028EF2 C6D085E2FEEF987472CB7AEE0CFA47099E0B8233578A1503D6FBC6CF4B93C19B B7E98754EBF42AC4090CA96C635A87782EE78C6164684A6FB36CA3543A5E8405 99BE928C80DC21C3FA9C4EA1679AE3EB2F5F2C42BB109208D1D31ABDDDF83B8D A992706368B0B6BED871CDD7CC432B1A3CFA2DAA303CAD1617CD08A4D728A337 C9A9B9A08F283BDF5E5F4AA87BDB3E87225154E95D968ED2EA8166C5F43F1CF4 5253F1468909DDC05C3986B68A0A68B470E944978915B64A3DAA3BD0886A457B CBCDF25B2262D2F85EDBEF9697583E8150D7D2E560FB083254487303A1F05A3B E923871DAE0CF7C5160D0C0ED794E1D3F9402ECE04CE947A2AB6D9023DDBB52A 352AF12502D3A3DD451716964253EE54AB42FC91AAC9716D60A6363C72FFB1AC 5E172BCA8E5AFC33379AED2963FCF53DDE7738735A613993D2FF4D364CEDCEE7 AB29AC612A4FD7888EC571D065F6FA475D808B939BF3094FBC0D2958F2108B85 A56AA23DF572ED65FB475A3D9AC9D3D6E49169C803B3BC9247259F35FB1E0CE7 39E19DBD28A30B52D68E78E5810EF2D6B4AEBF266779D3AE42B89A397F709BB7 F202EBE73B4CC8D0CEB58FDBCA0822E653F31BCE8117F626946E69E104F3236E 5B0ECF3B377AB59879EAA5427CAD707691159F249DB8BF0DCE9E3D32C14B68A8 3EF05EC306F6AD9EE7A6881DB1AF4CB8B3083A84499B641EAFE5D518A3C7807D 10510AA98776AEF1A205B6ECC1B5913EB7A05C9E327F55E55323671029B8CF35 4F41874F21BE1A17BDD180139295DE2F0A36E15BBC00C8B7533AFDB9456606B3 8FCD3C26CE41AFF0DF7AC252F3884712F7984AA1BAFF170CD6EED5711A073F07 C7ABD4115F4DE6D1FD3E818D30E507FEF19C2B71B2AC3A8A11FED16D359DF52C 50EE0B6FAAAB01A72AAB5FF9AE76DD02A9AB1198FF7310A1D6162625AB099844 2845D0B031C6C800624E94C49DF2381CF95A7DA957F073D938522DFF5499C70D F9016357D57F2174653B26C37E521A5223BD48F20AC0C5BE9BE4D63E34EAA19F 2D1FEC03F851631B8A501F0CFBF48AF21FC2C8DAC1D7CE6E68EC0C5015344CBA B0C9347BC19C1B1B73E51D944C7E8ED887DF2B62505EBDCD0E3AF1EFF98C68A8 F8736672DE0ACB27589DC52D3F6EB8ACEA58FEFB28D3EBB0C386572BD549102D C586A87F20087CEC8CACE2BB48B073D4EFA9966AF2A8AECF67A2D658C3F9E236 871AD879AA984F8DBEDAF01A6F362073D86F929E80A1029D1D5328DFB1E58792 365CB130CF923E67EE72A42EA8D50E1C3A5B3938D9D1F38A63C3867692F738ED EA4D61A00FD4E3146B5C10C796EA65B89CE73D7E0A65CE45B4C394AC0845DCDC 712013DA2791C135B98B58910915B77ED5FAFB80543EEBBCB900C2F59F96E042 0B0CB3D3880A33AB46D3FD93C7C2BE81748E7FDB3EAF6B53944B08BA4023204B 94E803FD330FEDA060428E6B503E9B6E9715468609CE9041E56B8FA5B9A5FC8A 892B71CDA4A6AC5E727302D19165345222F69FAE99351545AF6723D99565DC8B F3605D27E3B56B3B0CE936AB1896042E5764902C29CEBE725F4AF16F766F0A5E EAAF159A94C6035C276048B3B5E6E664E5B5E872B13013706BF41DB0D9927F00 DA064774CA9034950C72459DA4AD380A88C45AE598741D3379E12B616367BF64 C1C3127587080E65FE56D6142DECEC509781DD2CF8892016E9A687D5CEEFE26E BC82DDE6E68FB65372997828EE0E6791B864165AD18850BB2AEE3142AA2C590F 4F94EBEE20615B6FCC93C2FA95A54E59101B701C0DAC4D60535B6DA79F3E0A54 4C9E8B27D9E7ECCFB41F61774564BB8BFA7F5230FA53CF21E6F6593022A0A15C 17D49E856BB3F480FDCCCB429CF7C17B6DD283D98598D60BBC01F59CEAC873EA 7B6DD5DB728AEDA1C54ABF44026197BDD29B649060B97A6A43C1C9310E9A4EAA 63DB2E2776552F9D50A4817415CC651EE52E4B394A33F6AA5A3A2A8C50FA879A D895E03E59232A31826EE0054072141CBCC29134CD7B702494DB42FB28FA7473 1BE5A15329FE895E4099988CBE903983CAEA0F881CDC36B3497A379141F1BA37 F71912C19C622433109517712CB0DEA48458923BDC80EE8FA1882CCC8AB1762B 7081D20DACC7E98E674A863CF6C054019C20C60EBD9AD19AF08ECB624C8812C4 6D1643BCB2C8DE49E707C0A1FEF2B082EF23BB43365F2E86699FDE55B6C84410 D9F9B98975AF88037C2604126BF167113050DDD6746E4D9BCCB907F649BA878A 76D9E3E640F1866AF7FE8A68AB4DD106F288C6E241A06B06AE03EC6DA8AB79AE 059024B570192CD00920081FBAA866C07CA80FCDF73B346FE8F8521206B9F76B 0BF5BA96B5A7ED4FA0BC4EE8E7C73874B5826903889814FF9356BB8DCD9FC470 5D578F49C072E9CCB566EF0990C5C8D386685AFD502C6ED4D241B323C3A4AD9E 6587C17797125B03F4D94EDD5CBD3AD69EE142C8AAA431855AA593AFD411CD7E 1F6E5F3F3139263AD9340524CFB816F458FED5DCDE7481E4DF7D99CCFAAEDE66 56E760127F875E40A3243D2C4E174C9912A3D0211FDAB736D21B4457D6C3E85E 22B933880C4B56C161BC03E96EE1F3066C38AAEAA90AE9852B3183FB053D40F0 4F10ED9CF83578D1EB9987F88E84FF0254DA3DFDF40449D223E88711394BBC02 A5300A3D317BEF946BC6CE84EB4BEC87452EA787BF1196574A704111281E7B13 06F8FD36B9451C9BD2B79255282B24BA84F73FCAF5AE73019B09122F03DB13B3 6162225945DA68594B7B90C02AAD601FEF54A0BE3BFEE7E2EBE8417890182C2D B3FF0574A10F899CC19C936E7DB0C44BCD66FBBFDF2ADF20A90B6CE2B88F7B82 F57062EFFCE03BE19A2BA5D8C1AD4C2C64FC5BC61FD30BE68DB4D80BE0240FCB 8DC96BDB4D5FC3410DDC7BA82B1525EB283AF559246FB71CE62167FD145D5676 511BA7BD60B5D5AB9BAC41F1738CA9FFFBE2DCC9579251823E80EE0453FD949F 74EA6358B2B60D8C2E75E6F954BCA4C79FADCEF2B31685708369AAB83E3EF797 5B1ACDA4CF3048BA2425648BB064B615D9AB7729013388583CC95A01B407E20F C4C2DAD6AE89A507BEDB7F439903DB8CAB14075D0DCDCFA63C680A08D1E747CF 20EFA3D74F8D92340298A28C512B1667B1AA5E030A3FF04BB5F48D62AB577ECC 99F2C258CB056736CCB9F88D929EBC36CEC11A67E35956E1D6326108CE28D7D6 44609EDF3F3D8CC7C19FAA45F327E67E03C088B58E4562188C3360A2449BB592 3AEA499C66276024C112162ACC3A0FC76790D011334A4410B6C6A381FC38A7E6 2590000D3DE93CD70F6B5CCBAEA20F02F6FFA5709FB2D4CF25A9DDE6A4C41748 B145C7C56817D38CE478D26F66227D06C7696A349DB86E79C7618D3143C5866F 20600CB8108174045902C7CBD174ACF3AD2576B9DE9735F4DB64E51EC9811478 BFE25B3CCD2E44DCC5D2ADFB08E9C60F015A0FDBD76F4BF47A42B3DE8A87588A D45C75A1E35FE129D06AB484467E707AF9B224F30FE62B8ABA23DAFF808095C6 2BA886FDE27FE2229A401F23261A9B5967DA807CEE25B2A50A2494AD0913B336 F624AC43D6C4A65A7E7B901EF40ED3D8141FB6BCD41871AB298B79D334852ECC 1AD114AE3D06F30AF31A0EB830D5144912041E8D8AC3790DC3357A3D85E9B898 2054FB4C117EB8BE87B69856090A1EDFAEE793691FE8BF01D5064E100EFB51C7 7532C177570EA7526734EBA2CA083E985669735D71A70BF6736DF45E9DD117AC 9347FCBB7E95014FE75FD4077A6A429F99E8D724BDF6BA028019505B5B204A88 4C00C4705D569DE554AA61C7CA05363A9FBDD3C5714027ED62BB67785C93DA08 E1452AC8C671A9545F01E8472A1776B079B61EA607CC12A914829E3E3BCD12F7 89E2A1699A0C544C625413D5F2F19691E9B801F01437921695FBD9B44FA78805 3131BBD556F040395CE4E84FE36E91C37BB3238B2D8C53CED2338D474B6A428A C9DC2C3F770E2C5E807667EB101227D43EFFECDA901A2CC9FDFDA7BA4A6D1706 9FA5DDE095674DFAFC325691F37C4186417839FD729EAEA74AB537B1BEF64373 01E082E738346AECA0D5624CE3F80218E8E5088486D5495379EA916D486E7C90 4E1C15369586B38103C9544C7F5B5D7F2937C22C6AEBAEE59776FED1087261A0 CAF0156036E6A1460125BD62427364149126D30CA5911C6EAD878B785C6D7685 D05A805D49DB5C43C68BF6F47376B88B8A2AAB6D722E3853125ABC7E4A5E1F4F 6ED836C009FD6519A7C15CC563DB7C7A39D9D09949CD80D4635735F4741A5B70 6F0D27BC30CA9D5D0D41711400B2BDBF386CDDE412C7C863B4DF671EFC3D6D22 7269CD62D9022269D080FC2D69B34257286B1B1ACA071B500B4B05B108E8206E 8237D0C0D08BD28F8097B625C2F5B856DDBCD5EE99544CF75C45B9352A2BAD86 2ADABA5E33B6C85DAC63AFC19BB0155B40938F015DDE70B2A664B26C11729ACF 0C45450AF8633BEDFA17176B02EFBDA15E67B51E30E4C212A978A426A4049DA8 CB6096FC227DAB985E8895556517AF1EFAC97D4FE6F34A55844AD51E01A6A3E5 B1A42B004AD4535FC28B2BC8FB87FF4FB2EF2FA92FACFF514FB23ADABC1A3274 D0337EB6E6144D3EECF2335063C9E30CA2A94EE032AC9C58CE0DC878D1B3112C 398D6920E1665739EB3E7A3AE040F043F89A0A3681A90545F90E92B0F2367CF7 E8943D5EA4E1229963EB26FD672CD015BE6D1D6DF930EFE1C2D99DDC138E47A2 EAE55E51580F463728B87BBAE061714ED43029E5678D7598BD16152D91743224 B6D01F38C91800982B3F2DE70EF1B0397B5E3CF8D2826227C4A246AE14336A98 1B9C892F209A16485D0614D4C69271A1BF99227BE0E3EC262FE0A5AD982BD2D0 F0D0AFCC27A682EC283C91594766FACFC079994351C20AB4C5D16E20484699D6 44026CD787680AF4FF970E1062578218E4BD1D69D9AEBA4B3FA958F121AA3C92 779DB49E6890145E9E202A3B0CD365680DA71BC9C859588927292E0A62850F07 E4BBDF0AFB32A9D2AA740214FB284106DD02EA25A34604C3B8C35891C4FBFEE8 5C61D4522955B96A80EC4D9504093CA68FA5F717596FE8F2B2B996F62322E733 738458FC42D19538E23C4CDB17A0650277DC3798013C623124F70C34D09DCF3E 1FFFA3FCC3BA56C4131D511F2A78CF75AC845C6625634B70DF4E22E420F247B5 87055B74FB7AE69B82689336568D04EC5F4822F49F249B9BF9A21CDD9606EC0F 8C65F4E4EA5B77DDE62B200769E125026F6CFDBC7DEA4EFE65891BE7468F5F01 4EB693F1DF9F615F975690F0DB34734432700B04D9A10CA69C3233930AD710F2 5694E068B65D17B70D1C6FA7CFBFEE92FA1BF186405E8833F3A008E23B240516 0E8503D1593453D9BFE7C133608086218BFDE7AA21827009B627DDFC55403D56 35A62E8C026BC4080051E1EA2EB0D1B76337BAD652D1D4DF30B5DA40E83BE73B B503708407370EB38CD0241742F59C325BDF0DA7DB32F21D9AAFFACA2F08F01A BCBD8C19CA5F07A0940B19E2B9BA64D72702F0EFD565CCF1B0B0147D4953268D 7110ACFBF7E7D286D6022362DDC74C9849C685B6A0165249AB0F68A1A4E4A869 DD7A55CA81923C8360193431F513F6C6C4DDFEC637E5E3A4F28D73B649BAACD8 C466C682D16DD4F60C7EA63FF9EEE8EAA65613774D7F3CF5B472A93BF925020E 505F2B45BBC8C5AA252837D82A8505337553C067E85367140263C31C4FFE3B3A 9C05DFB3140DEF948B042EC8F8D3B5B2A9802BAD328DA36FDE29C8468BDC1CB4 FEDFB81DFFE061AA10E6F709D0809CBA9EFAE57A5256E8CDD5F180D434947DA2 669F1193952A91C43EB791D6838C289DB4D764E5059CA4FEA46ED2F7E1BFF186 C8025948F25697306F7DDC2D4745E5F4875CEB817453621BD593A5C1391CBDBC AAA741D094ED0BEE25D1B0A52BE4F94B29FF8710CB0C6DCCD11386A7332AC131 40131BEBCA90C1CBA6FBE89608A4353523CED93E728A9DF389181E93DEBFF441 48CE558E41CDCB90B9964AE98175C7E7C46DEEDC3805A946C4E73904EDE621F0 28EBB014C84666D425F70ACBB2959BDF8C766777D03EE238A97D0EC98253718E 633DBA9ED9303A2E7536CF9C51879DF1B27D1F200F2859FBA908576399191377 BC0FA4313638665668950DE056A4C1683736A4D8207E839BD6062EFF051A3B50 0AAC5BDB4EE63C1606074B438F082209EF5E308FE5EB80BFD7CD0FF72FB42B46 74CD3E9CA362E6F1372745162AA843B91682389C9C746D945924C4E477B5C2C4 463B183E14644D24B24B803D34526CC1A196FDA0B3BE75C9DF40EFBDF7ED7C1F 90269781AB354434915D0BF499B57E4F3DD7439063E63D9389415AB01E75F5D3 7FE929C77B978823FF62CAB8D7CC1EBD83990B6183CC3D8FC2D23427B0F1B41E 24AE3625209FECB54C9A5267662EDF6EC1B358E0E4E9E2B33C0DAC3FC098F4A1 E5050BE00D3EE99AE17A1ABF76646259DEACBC9623987C97D4C48712218470E4 AD431FA185A22C3A284E26D2F52E0FBE8A363B0722029A0E5CE26617D5BE683F 9B691D21E26265315AC09E4FA4E756D76347625EF8C4B40E1BA85FB8349C081F 9419482CB93278CD101B31011385D467F8196BE6D8DACEB0E72C34E15937F465 0086834EC644042D591360A08912CE28694CF6E4AB6215248960145268741F1A DEA40C92110934C4FA2C7D5061DE2BCE38D7F0DEE1C7BABC062DD968FE9260A8 9685B0EAA2AD489EC6A0B6B9F5C37F03EFFC0F5BD17A182E86B07E4F3969A4E8 6BB3B8AA2C5F2509F5D8180AF158919F6855848DE7F9792168774CB645FD8C12 9FD026C6361E7760CDFF02A02EAFBA1A054E1989AA9F3B574B36258B39B4B6A7 1E8677DC1EC266C784BE894867CE9BCEA47D9F8730817164D437FEEF09D1F9B6 5338558AD5A6583A30F7D1C90097C49A8AF7FD320B07B6CE66B47E147B345063 32D68382395ADC420148559F614457AA26BC0A74621B53A031E42A3F5444A3A9 30912CDC92D587166D2BC4E8C72BE891CA6D74B9FD8A7791C6B173870E99EEBE AAED3C54075997CE3C60FAD03759D35B44F536245336FFECEA143FB8E7A507FC 2DC83A261D04981B61D90B08121D7DED692B02644930F1B1700ACEC7537ADCD6 CDE3E5CCFAAC41C36C7E492B2A528769375F224F75C4CC41D3C323450F1C3C01 E1878BE5BCB76BFCFC189AFCA98A1E79FABCFCA9331289C5659893EEC3FCF7D1 A8A4B5C73CC2A8BD546889CCEF6C526E752C50A991C81ACC71DDD5D2C0092FCA 1DCD98B45B2050BC0C34E7FC222D2A071FD7EBBB3D49425F0333EC2DC44EBB19 91D50AF039B2274C0AF5061F0BA191D4D88EF8421F81B685F3120E6C2B782580 A1B88539F3B3A4368EA16FFD34FBE2D8889AD43A09FF3743B6DC01CD79369061 A596375F93D05E17C03BFC4D26B63FBFE4B945F8228B2D954A0EA70029930314 5F6CCBD00E37AFD4EABF145469BD3AC31205DBF89AD04881BC8522078A7645C3 25D1F802BA02F3D13C5FA9E37CFEE4ABAAEB9C59D1013C1A1EA7CD000BB99263 5D36118709478AE7AC7EC8B3381D64845CBC5CE3626F8A0A017F50DED408D83B C99409F0341346DE6A4476116C901CC51547B5E8CED9E628243CF8E6DB9A3D79 9A7B41925DA62A244F84A06E3D7249286D6213BACFA203F8A7023C7F4CE88FAD 2622B6BCDC9C27A844D845C1B92D8B4192C5112A3B07CDC7BE4D717DEFFE226B 3E2C77F4FE3F3D2607A4E0B0CBA13F655802FAA8525ACE352D9FAC118BC8C36D 5FCF52E8FAF153D95D994D7925409F0A1BEFE021CB357BC2A5C71310CD3510DA 9ED29F40B3F513DA3B3F0BB39F4602687260AD9C65C94A5A1CD3C7CEAF232AAC 8D9D898B20B1219EBC17014B901D7C54B249DA5AE21BE58E4F11491296B3FE87 58FB1EDA81DE400928F3A52FB173BBBD26AE5D9ECC5132498812C5A21E42ECF6 69FFDA423C6D0E409386D26E991B220B81067E363BBFE85EBF08E242A033E690 0997DC237F761045B906979F8C26964BBBBC9C79093E5236ADE06A6F161FD6D0 0B203D673A752429737E605D59BE4836E1D2D27003CD32B549D8AE78F1E99B87 A51F83DAC5677A51531A988AAEEEA9C6E39D196B25B339595954735FB09B790B 62964C802B405149F0DD0C7C17CBBBC56BFFB50124059CFB04E1D21F039B4897 DAB9B5F750A8E917CD52EA481F5A22C5C339E7A7169F94EC8BA9009B941FD687 B3A15444FECEF7146359EF4157C4737EEC93194217C6B4F2E619E1FC3AA3913C 427267D748F532A512103AA3D5060F1329675D7C063F5F9DE91920FCD0D5BC5C 0E88BD6BB79AF38F889CD783EDD16F8750EA307D657769D9EA6521DF37FB754A 5751764938B64309373CD0560BEF02D53E24DE1A5CCB47591442488B1105E6EE 25B2D4BB852B66999B47E54340BB2837A063F215AB52D1C54AE8C50DE28830C4 48115F59AEBC365FDE88D54B08FAFECDB2B2B152A929BCD90410A3F2A023835E 8F261E3F11AF45483179ADE3DC95EA6F3182E31998591086991AC570FD21139F A8583550A644D84A4F4FDF3B88F7D5CEDA1235EF47633702B358469B5A65024A E4E5EDFB28F13A9289D4B2C15D6D99633863A2444B378AD4E8D1304792522C6B B74F0EF439618B891F2D55BF78252540E4E53C29D5B730398CCF75A9E70D42A4 26DA4A950439BD574AC3A5DC25574C48AFE12EC65DFFAD5AA281DA1F11352AF6 57148088586B730C24D58A3B5A40030D2FAF7E1DB721DDF56686E67F0FD8B1A4 6193D6CBEFAC06887E63FEAE882F76DC36581BC14CA55EE75C996FA8890D85EC 7899E60FC27341E5FAAAD3C097351394EF7BB16754D4357F977D2C4D59F074E2 B19765DC3828D0C721EC22FA9DB3CA9F5AD46AFC5B9229DD0CB0C0D407ABBFF5 8A2976D1E74C831691D84D6E52E2BB127DE94E3C421434A7EA30DC42D800413C CD228DDA77750C26899214DDB2E162D8F774D54E0D86491C5EF3B7F0493E042A F57606CE1B593CC72A5725DF50F1DC5E53F1AD6A342DE44B631F40085AA922E1 3AF4FD57FC8C39C3C84FDA336449390BA51EDD18BAD5BF34D860EEA4FD0B5819 ED95F0AF2B507044AF73001EAAC04E466BD549BCD0F1F947C9635F8677496FB9 85EED2971819C48A082964A6EC411BEA1E6954A8B87D7CB712B9FFBE337B1D16 2CC6B0A1001D52B4F53901EDF4CA6AFFF1B4959DA380A7A2BCA2F40A5489EBEA 88BFCA8689513700DC1DBCA09C4D2F2A15D792F576B11956266F94B10CE6D613 2D69FBAB65C9E2FC206B99F689ABBE2F38231EBB52FC8D2F18212E5CE838DC2B 938B6545E0725614D0E01764BD0D64327A07BAB65501461DFBCA9A0A67A8ED46 48150FD04C23087A85487004D1B38DE3FFDECEBC47ADFC1C4A2B4303891F43A4 BFE8C751B6EEEE0FED3012784F9B4D8349BB1CB230F2B5965752829B53D8B7A5 28BA75E8C404DC5C72D1FC337E3C0546D0F7F62EAEC63744524F7EB9532AE2E2 74DD257976CCF231CBEF6685B59F11915D6BB401F64E69E85873FE799914D06A AF4CF7036D04002EB122C3124AF7653FD315BE239FDD3F1D3DCE8A6E956784D3 65CADF67F425FD44728714C2BCE8E6A1DEFD2C5C9E11283DBE8C9334CC9FB64A 88AC90D0D98CBDE08BFB6CA1B9A6594D8A081C7102AA32FB20B3FF3801DAC20B EFE3BE7962D4DBE8226F49C9A692EC4EB10FA246B2DA19E9B750A98131DB1595 2AEE67DD23A2D3602692CABEA6BED38CDC7BA19EA9F031FDBA191A23612D20E0 8341716E28415020B2EA481A9C81C154896CA87FD13E266F1028B64366D8E2E7 DFF07111E709ABAEA14210C6337240D410A1FBFF4EA8D54FD05A1CA73C165DFE 02E30E71E34E3988D37DFC7F4E45EDC905FA7EF2B3454DAFCBB6A7C940186C63 98670E71861BA524EBD71177000E6C28EB22BC541F3165206E23FA8358735923 0C4DCDA2A32B0F8A955FC35ED21C4CC12903FA93966745358540C1FD58463832 49BB4FE3B24F0DA3D7169908E0C4213A7E66F6DF3F525133752DC42C85A2E7B7 231C4E3DE919636CA0C77FB32278E939639D976811F55C239674721CA1C38970 8F27D8B2A374C7035D9FE92DEA1A168BC529C2717208E6DE469413041814E90C 923E078F3122723AB6D7F175D325D5EA695C766585D8041A602148D57F3D2446 489DE8154649A3E2B5886528B286E58252727E7E5226AB869AEB1C87FABDAB71 DF258B605883DA1D83741C01DDB7103C4302D93F595070DFF6EBBE9E9D2E7973 2EFC4BA17AEA3C9CEFBA35AB11242497AD2B7983D5BB41564B14C3E764873BE9 E2117894441C95419227E313EB29AC3C876AD977C170FCACF41CF559FCF510FB 855F305F745006E24492449AF88BC0EF0F4C4D252BF982FEA0B5573C808A2BC3 63F4BFF0AD9FB11577AF67BE12FD6EAD33ECDE921C15CA83A128FAA561E22165 0AB4DBEDD6C2EB183825633A6B37069FDC5707542E77AC6B62348CA3197E1321 6983351CF25E09046194163577C788F98D0814871F0BF95C9A26CD43740BA336 50E2C5251FFDA1942C957C4D3AE3A9A1189FFA47424F1F308EDAACCF110027DA 2A378F2212A30F0FF002F5170C23BC5FA4FED32954278F4DFD4FA402F049FDA3 EDF8B567E300A7E07CE64B19EE98C98969ACA978EB47D6A36A0ABF99AE13FDD9 A47D3552C0BC0E03F57A7CB93B47482086BEF86DA9769D11CF8FB43731D7F4EA 7AD113D65DF699CA7B27DA43057CB617CF8687383107B41EF2C7BCB74114989A FDF1B2BF9EFEE204C5508FEB803C063212F19F52558477E252400DAA32279301 082BF5BBD10B9D0C2FBDD8860FB6EB9DF6069AAFB171EE8F5AEFE05EBF13A657 EA165EF27FBC2CF1F34582EAC35902EA861F1ED520137899BCA53172716879DB ECB26F6B8073ED50B6AA45CDDAAD21E4F065E189D80582FFD8B465590660E83C B5C98221E47B28514BCCFC48FE3305B2F21F06EA23DDC42A00B72E55DF0B4775 835C046B2E5DB8173AB805D089346B7D2DA91B83DDD8DC59B31ACD2D480D9D93 6AAC4699807A2E776F7A1363DB5F8FE4AFE2AC3E46774DBD8AECCDCD63616687 5D85CDF76CD5E72795E5CB8541ACE926DDCA570A8AAC5EA727E60E213A3747F0 B390FA55EDBD02EBD4D7DABD5BF80656CFD9D22CEF6E8E4DF328198FD85FF24D 61EA38E462E623D3CB1D52136F73423868B29E56CAF2756AE7B9CAFFD35EC48E 3BF3AD0EFF045ADFC313A28313A71965A9282D917BBD30C569EFCF2061723A24 B5EE00C32F8FD7CE8103D1C9B50165B18B17AEE9F13F3A7B490AB7240A50157B D3401AEC3F3BE0932A05D35DFA73203732C9E281533EEB73D5C7857A1377FE38 4BBC2624E7EFD5E22F6CA6A756A0B02D426DDA76E939C2993BA7CE3D56607F7E AAF57C69B01E25431CB55661A71D555DF81C8886BC47E67DA2A8F10817065A31 2630C5262C91B7F9339BFE9C0DF36337AFC9B76648BBBF949E8A37DB570062BD D1D50E80929D47859E3DC565940270545E1B7219E845B92186EBA22D256DD810 C1864494475F55B2FB90A5DAE018612F0DD1771B02B9D53E2D203F9BD6E3E472 31A1A14F984A3CBB5225E94914549AC9EFF3C71D609AB09768581807769A7F5F 6842CAD1CB5310C3BB5173367C89C01C3E213A2E28CB8DA8C0C79BDBEBA69364 2F3BB1189E4DAC91232338DA6CB20AD9230D7A827F5A31D65C5D3683DF01A5F6 031FED924A0DCC612629020EB35D40924E86EFAB98F6AB410AE027A65DB80781 CC2872C1C3529AD65FA42B1F8B51E53D7DFA6F144C8505A5145EE0814D5B0037 E434067D47BF987E71FB6532182DD255406FCC963D24C600AD4289B377A7DABD 73857C966F3F275941BBF75895F4EDA822FC59D15FE3481C008CA5B17EF99174 5939DD3D6C743AC6859666BB2B7AA79F5F5C8EA2A5E4BA5C223DB456B00D091F C8D9BCC8D061E3DD9C18FE3B78F10B5CE16409E8D901F760F1DC5E7521CD9E60 B60F68C3571D1B86AFD67452D93A7D075DE631211E27FA4C466603CE1F06CD45 67266D1B3F05CE9761DD4884225CB42B332890419FE5707539346341B50D0129 CA81D7927AF895ADBC277D1FC615CFBC6BFADA99D5F9042628CEBA8B332B0919 4BFAA26A6EE18F7821E771A232772A87640588B05AC78297E1E4B69B6D721FB5 6D6B0B1C1B689D455AD822AF023319646158C9A1DE4A64699AD7FCB99D75F859 5B2647FF23B264D075655BC5B7BE0996A89C91578AA6FF6BDEFFBF855C8CE867 D972097EB1D3510FFDCF098827BE56AD018BC07AE2B9129B7B063D453CABEC11 7627DC1AFCF264862B000163AE138DD072990F7673EADEE920EB01363B1C7B3E 0C96FE1E5FE28B371E58467A42EED1D00BF16600F98F95C5CCEC373397D77FB4 132577BE21E89D37E10B73C9CA0D314E55D4A9E8040E22780620799C939ED49F 161EC14F9C0E39BFB2DF4F61897E75D2682DD5DB68692566AA693E21DDAD5A51 A5E2EFAD7BECAAEB34590D1FEC6AECCFF4F1445A22798313C233224AE2E15ACE 2C5626354F067AC23C115B14D350147DB851262E47E9C4EFB4C99BE5B69F4AB1 1450ACD7FE622161D1105B6EC97617226B0592AB408F55F461A2D0A9CE1A9CF6 AF1535DD3E623E8F01F2C5D4EC0BB9F1E9B1D02BF88FC57C3ADE12 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMSL10 %!PS-AdobeFont-1.1: CMSL10 1.0 %%CreationDate: 1991 Aug 20 16:40:20 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMSL10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -9.46 def /isFixedPitch false def end readonly def /FontName /CMSL10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-62 -250 1123 750}readonly def /UniqueID 5000798 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A319B6B1FD958 9429B9D40924DC059325D9D4CC0344F3F997A99E6CC0676735EBCD685AAC9142 08DAFEC78BB41AFC2F1C219910BDF41D6279284EF600B69776CA15BC8A34347C 30783C52AFA60FBE3E353E2AE354CF87B558776A22C776C7A0B5AB5CE1F941EF C2D9CAC37294BF407A671F10E4743BF842143F4F7DFEE643BA3BBD8BB9E3F24A BCCF7F0ADF8BA500620C81033EAE8C4EF2C1DEF13AC575F1B3BBB66F093D3B78 5412B82B67FFA087AF57182B2230F9F2137180CA58A7D9B2C822FF04BE6CD01D 43B2CA7058C7B953F6D9B5D6E91ECBAA5CDE1159B0E59C83DBAD96D6C8C8BAB1 374EF652D10C0F3EE7104472C98DD3572AAF2D45A70BF7061447E21EE3C3BF23 DF39C2D1B35B42CD5297BEBE6BC94F7C9DC6E61EC67E4F677256FED9064BD3E4 B51A71B1D27CA4E5AA9E1D8080E6DAB5310711EEF87C40859FA935B19524AE83 63B163FA8397BDFF443227FEDF7DB27DC35D89FB1C5E435DA0619A5C88AFC73B 89A2DF5E767C5B536BC7167A840A0C32BD57A14DE69A7D0D819AC36FF32F908A 5070F32983BB007437E3500799DF5E0AD3710A4C0000F0098D5BE99F2EB9C1C2 C444FD9552D0DCA098A94B3BF176F511CEE13DB7EFFAED7C47B5ADCF8D4700F5 7A5FD1B49560969BF5C44F3749370663A04776F749DDD7B50674D93254426C4B EFE264BEE7810EC93784B7C01A7F29EFD92547E13A2C7851A2E709FBD5B87850 4A44F08F56A542DBE072D2FBC58D9E6468E1AB858DC35240E30D31C7AC13D6C5 7D2BB634BEE96FA0E10F842B11A789F72A333DD6DDCB1BC23227EBC406E50B40 30AF0C48E6359AB0C46898CDAF1118E46BFF8B00F54EACBC2AC262AB898C42B9 2E080C10DE923C1F7032C4ABA4D27D9D32519C0E8A664C75F8FC5B39BC902E72 A7806D800446E405E737E20364DCFF67FE0B270FC279596CAF78AEC9A14DA62E 2FFDEC70ABD0E1B105E0140822708FA77D1AE7BFCB4A39B809496CF8EEE4CD04 1588A386986569C6925BA522EB9750A93EFA8B0E6D81DCA88B554182DF2488E7 A87DE038CCB18DC24A3685E6A7476B32CD05634BADB9427EBCC98CDE0974DD41 6A245099277234E372CA19EF03E4657E8AF44934205DD7EF4D17E7F63193E5CF D7FD8F24DEA385B3BE33C8CC9BB7FE40A6929B5B5A1B2CD1B72918F90090B684 16DD41D0B2BEB90ACC30C95E0E1789C6B53775A33C5D572482688762038C9BD9 DA609F7B4DCB34CC8E46BBB9A02A20C22D3543EAFDD601842F674F7BF64BB737 6ECDB42D655348C157CA46249197E41E5EFC7125ADFB60CBC60663FA96F5E069 FDC50D37AF86B6083A3CD0A64599B20C9FDC76143CD4CFEF3963E34E8CD5D55F 7D7C21CCEFD338B2BF1B715C7A768A8284490055B286C89905F6D30E5CD2E038 1E601C013D97A0D4C5218299945A29C7F7F3CC4AACCC678EF33DE7660D85BDE8 00F83076C86B6B5F3D9E6D69C46CF647A917AE2EAE2C76DA57656D412C2F991C 01D406FD7C180A36FAD29BF58BD5A3BBA19EA834034D0D3356B79C9BB890726E 150A621A2D9F747123CB994D7015DE66603C09E66AD3B17EEAB12C2D55ACC53A 9B6995E3864EF5CB125D752239EBC9E84976003CD05F8BB66BBA3267DEE8B403 992C90157489DF1BBC95FD1D96F6E4F4C67CFDEA669223F989C37B38553C88AC 1AFF2049570686523F0D1D2348161972A672DCBCBBCAE991D274349EB5666F28 6E3F71556501A19BD707EE2AB4CF6F816B8EE9667D593E675A3E1A7CFC87A62D 08664A989C2C0E51EF651D4F880984B82B5A76B010FFB3CCFE624C9050D15220 A62E11DDEC0DBFCD2F9521735CD318C04DDF59AC164ED99B7E8EC4610A1F4D86 942CA5EB6F7CCE3559E31E246837A9EB7E228BAE1542C7B461DFAE99B677DC71 9C749EE051112E07F8436DFEC339CEAD4C0252E1101903EFC09482E7940C4F55 146FB8311AD0AB8D7FC9635B5B14CCBEE8B70F10C49218C5E8ECBD1CBCBFEF61 39FC3C1B66F378FA1C2471A1879F129A10420722F1ED3C437E3B7F3815E9C17F C099A85D6DC855210C8B350E79C8A3F08039A265B59431FA5A2B62E8D5FF2949 BDFB97C6E8960700FCD7B7D05B5C5FD295E9A14E4AB5B8294F00D7C5D837AFAE A4390B313B4316080D2CF5024C3A4D4F01D794633B520DC65B0380C6CDD306C8 C2BBA4E05F147B5775B4F41B493CA8B53A9D1EF90BBF9F9639F0E8A5B2554418 B88CFA147B8FBC77EB9E17775AD6E354CFF95F80BE6902599530C2CFBF5CDC86 39E095D25B53721F2D926266AE65BD57ACD6C15578C863CCF3DF65EB075C3693 A1467C4835AA6FDC646743A79E6BF6038002B1CE8E5201BECB5276E0C904A692 7ADB6B2C9905C77B6E95B9A743C1DC6CC646BC61446C23D4C14003D9CD492746 475392545554436F3A92A48F1E607FBF09AA43DF8ED3162D96E816FE2BE4916B 30F1FE0727BB9E5DF87440A9159CF187B8EFAF95D1DB0BD38A7E2EFB056E9EFC 3F01259E6ACD83A3FD1F39633152397AA2492043996ABC9075CC76850D95F749 21F18EA077077FCA741FD8B554C255B358A786C9ECA45D00D53407AD51D759A2 77E47C33C4AC1A7AEE37FD80742E23D002EDCD7E52C89B109F5D0CC5CCD7B6F3 09ED3548B87163A66A18B08110CA452661105C08089448920C1D2B9970080A80 20972B1876C7F1F3F1A219DFA1BB58C031E6FDDD89A61528477B08AEC1271928 15CB6FB4B4072AAC01ACE40825E3B747465E36818D5E4586033E63C9927C2C58 7659C2F45A302097CD37E4FAFAD295D48990376A9625A3E0E8DA45CCD5B53461 A9C3C9F6A16FD72A879849E063C2F95AC45388AA2CBD1D2DFFC5A01273B76768 F105C78E7DBAD448F78346CB521BCB726B80470648C51759B40B4521D37F25A6 FC172F6D8B37EB72DF01A999686A949344EFE001D76903197AC4FA46F99F768C 458943172A77C8DB120C08944A862B98137096525D80AF5FD68E3F68C7DDF6EE 094DF29ACE4684A91AFAB76D21D5E411870860ED79C6B646FF6802740AF6BF46 00C0F33AF27BDD7B9589ACD0C21F47E923854581750EFF2C58FDC81D0593DF8A 47BCBD757657CF640CE2F2FF7D3A74877C478512879F0796767C914EEA914E36 C2A7D4C886C58C0D3C292230C67F32C4C759E62017C21C4FC69E43961E985AFC 982E70182B5221E3794C6E6FE2971827433A599ACD47334A855518FBD04933FC 8AEE418BDE0148C8D72B0E5301B48CEF56A4C699CB02AA01CE1B1E8DF7366500 DE8BCE018BDDDAA6E4F6BFA4C598F844C3D829468E45E89716A3F29FAD6491BC 2CCA98A59C81C84A266B35E7031FDBD9093BDAE13A77BFBD3C12245935496A87 20D030422454171FA155415DE6EF3A0239E13989A44BE020F84F7FFA5341A750 F079DDCE1FDD28B1ABDB14DEB80B3E13D04C7BDF9CE5958794386841D57C0235 9192712EB7A807378C5096E8E49A4BF1D27739D520EA1FF26BC01C47252EF011 E7EAAC7AE10369AC01F67BB674748ED3B8ADE27CAE9B4E9C726375F6932EFF7E 92138CC2BEBEADF20067B18DFEB5C99D70FB68E4CC973C99262434078A81002E 4C4FF1F768516A0A465DF76DB1880EE4ED7DC0B9C5F98FE588EA9444416C30FE A9A1F87FA6771FBE48E369ED710A41C42A3E49A8A225722BCD2D76E4AF3F2A5B C822CE3E6777EBE630ED0C1B12D2B374F5C55FFFC0AACBB8E51BBA3CBAD0D3AF CBDE0A1DE6945F3D569CE9EB952C3C29FB6A18E49DB958E5FA3ACA23ECD45CB9 9170D258EC98EF55FFE9814112466E7A36906C8C30064C9C8B6607D28DDD8011 7F644680AD70C5955D8F35648CDACFF27E0E07C2BEB45A069A14D48327F94D18 C7E370285E71F616BD200E62C968D99588E2F3EAFC86AFF5554F148014F99785 73E658DB1C2D6AF29DB3EB2F35C2F257B3EC07A660659CF8A1A7858406859AB4 D262673F86E5F7A06BDAF0D570C0D80E770A0EFBB399BABEACC17101B367728E E0FC9C74C69946A53996307082717C42382AF2D129ACCAB6A4C98BD22F21F0DF 7F04F5C6E27A0506915CCDC09D556D73235DF585D96F114086E807374E0DEB9B 7DC5571EB23FCEBF59FFA4F3787AF7DAC1FAD813B873ED2AB2C000C33AE87393 B08878A8F38F72FCFE873C2AF3BECCAF5664BB65E8C9DA788FFDCB100CA747D3 4FD91073F5E174E7DF94435FC4DC2885047AE52BC735FFD74D9FC7965DAA809E D8F9EC7F5AF0CBF60EBA24444565F0F68053F23F31E21A97AE91E43233BB44E2 0D22034DCE10089FBD34583A10FF51F1F4184F986F83DF966FAD44FC5E7FB44C B5D9C456ED60E4FC0C26AEA09D7F15E898B8834F6542138021326569DC00730A CCA59F301413DB3A7A44C957DF73E585525C2153FB504F713F9A3F9C4C9A8B42 28EB818A426BF1EE21DB3DC6BCCF4D43B17C869B2F41F9E1B06780A4F28DCFDC 7C2BC312F8BE354E36300E08B8D58678DFEF7A8F45F5282509D95ED3D15DBB92 C0F35CEFFC4B6B4D7DE3BD2C293EE750606E32CD47FB56EF6AF0A1B10D895FA3 CA6E41DDC2784145E3756CF69AC7D30674EF2F62F15E6559CC827D83D46EF6D3 0CA2674C8807974BF5E7D230648F5960D3B1A0BFF4A611EB52EEA8A8332DEED9 4BBA0E35D29DB46B1E5CFD820738AFDE217EC6B58B343F7E65A652429B57F3AE 40E0BD31F2EED3605FD44ED777683D8C3B24A133314701DEC1F6428EFE67E4C9 3A6B6237C25EBDADC6DF3EF3D8C85608693E733987271652EDBE3D02762556EF AB3251DA4EB82452FB1054090E5DF4C5FC0CB6EBED4A6365C820145B9AE45BC3 47707008B2CC5C2781B5CFE2D634CF6F2D880E13984AD0482FB6FBE6D2BC0D31 2834C0A4E39FE7E1A44B3C7C6B88770C16DFAED29F0647CC27C040BD4703ED70 57A1509F7B53231F633E871B714CE57C12C481CA6F1B6FBBE05F256D88BA23E1 73E378298DC84D0D724353354361D6351638ECCDFF1B198B8926CD88D0E90D40 6169FCD0066645D35D8682731BB1A1C633D8941CCCFE31A1C0A05BB308A70E1A 5B31CFF15D179F3024EB070F519AFF2D33305169126FF7D2674ED078474366B0 70DBD9FFE685DBE4BF902693B4EEBF25ABA0EBD15B634AAC7AA7810E2A7DA4EF 7CB61F430212E88030EB9094E16B9A28F6E5F99B4C8F4A3A23C9F827F3861C3C 227BCB0B31313F4FC4E1528342D75D4E50D9EE9AFC94B9BC984DC26D6756E12B 84F659A5973238CBE1D34C8F4921D3C81BF3C87A01226AA9113837900DEB0B77 2923BE34E057438DEB77BC1E2D02BF434ACA9B6A0C2CE1F279FAAD015450BF0E F129DE4F555161DF49AC818C7BF0969F9CF4B223DA7D732969F7DE8C3E2F5543 E45ABEBA3746BD29FC0428E56B8009A947D2ED31E6EC89F81F0012942EAC8988 6C4D94AD9A9D64CCD2F63C42CC682EC28BAB44D158C2906A8BE04D5615A05593 78269E1CC9B2FC3B49E71998DB102D219780A1F49F3E034554A4C85189B7CD5C 35A516451CD817E9561264C3E72D17D7FA77F1A223F9D192C02DCF7321D1A5E1 1B2202C5209EA5BFB9756035C0255C92762157DDFF4425D743D50F7E1B125AC8 D4AB8BF35B6DE114D19E325C57710C074C521CD3105990632BA865AF7A5028D0 74450E130548D58A07FD4119160A081E987F4CF71B68DFE39A6DB5562E6368ED 7D2A67165EB605E4F7B50073B822C7BB5568F8434880D1835090D0F0737B0726 E661623A2971F6AFB2BA86C82051F7941035D35D34FE0071AA2BFC13ADEF981B 63BF6F647422A2DDDFEB9900FFA8DB9106A08010A9428D1C52CB2636BEF03605 BA3F148851CA6262B4963BABBD015FEE2A6F888BC9D19917C5DE5F730725D03E 95B951B2DB240A74883123D40CD2788E3F22D9F517664D4E20AECA03AD05F648 1176E37B5E68383D070A9EE5CD5578F6713F5720EE1BDBC20242BAE097C55605 A9BE333FC2A67DEF096A6EF03723D702562A8031828B4A22B06C4B31626BAA2E 90DB509E1FEBD522F2F288FA4075873E2C2769DF4942DF150032010767DA0984 A2EA10FFC05D5AFFC654C16B4EDC812DEB8DA97B59B28583D7C7C5981A704B25 886EA32D2094006AD52CE372D3DF7CA452064B3E175B461182EDF1C3509C2866 7A20F48C7B497BDA8239C0C53701E2E537E41C1040F8973C882630FE94C61FD9 DE4B27E0C4AE615BB38CA3DF6B55DA9508CAE5908DB909DCF166B0F75CFAC402 F2687A14093800A5760AD0CE0A1445D06A18F00BD13DE80E24B89F06F70F2D5D 431AED68286C52B5E556E99F67473158DF8D9BAF85CAC1304AB7B5A604FD7137 752B8AE1DA6C021B45445DB9783C449171ED49C30078A2A5869698E8538AED10 42D4B9E793E01D930EC089D937BEC6FBACA5A167BCCAAE026086074641F95E7D A4560F20D0DA5C27745A8BAF446843D06E757665B334B815C739540635192C9B 1D4F75DF2EA4818A0A784AF711C1FDF1FF0A1F33CC94DFBA7716486BD362CB76 EA910405E9464887D6C5427596DE81FE4BA9524F7EE79C9DD50ED87C1E9F248E ECB50694775B4CCAA8F7AE0E75FBF9322449CCEECE4857E3B340EEA32EE5FCA5 9397868ACCFBEC81A5DEBCC977D4E4B842B8093436335EDCC07E5B6271030F90 23E7603DD74488FE31DFBA2C8673737E7636AC0295B9D5CB002517AD664ACE0E BDF8F7AB462BE335CA9BA59F88C9F9963134C3246BF5B805730FA8E1A2912635 B852BD73791F8B25397CCF81965B50712A2526773677B95BF42E81EDB7D062B9 C7BC2FB44919A709138149FCBA9BD9C819DE31C3E0431CAAD144C1FAAA1ADE55 D2E102D9D2399C5726ECFBA4F3E4479DAE95AACC10C58091666CF6C9601494C5 09DFC9C329A165038950F9D617A1571101DF306611362A5DD875D4864E268DB1 8CD334299B857B749E3922FE5F0D30787DC87C7D94AF4583515AB9F6252E989A 314DDD8077093F1E64FF01852C329363B585AF75A09957567F04551EF1390DB9 65E5DDEE527CAF9322C3280BB31697E9E500F6F9B841EB21DD636E1375E0D0D1 68AA2650A0A598EFE13DE2C7C5B4AAACE17BB17FA2376377F798C5C99783325C B17E3F0955347F6614E8FEB91AEBEA0FB6091582A1E1A843CB2589364610D015 E3582E3B7C208D8B8A23080AECA0FA09885BE932E516763D9D8F02BA27FB50E2 3596D470C7CDCBB5EDF818764C9A3E1006974C8B04DBBEC035A018C98CF4E041 4D4C074ADD3C55C059197B932237D3548C7C58FC95B1745ABD37F6DF0A5751A3 ADF61319F59F6E821B3E335252D04CA0536FC1EB902AF8B7A4DE01C74252551D 2805F8EF2EA30F1108EB18F1702E70252DFBFDB537B63982711FFEE7CBDC0176 2586D06DA4658CECD6D0A507AD0851C696CED780CC0AB76E17BE881ECB325DE6 EAC87C9E896659CB9D96D0C778CC4A34F3DD7B3B84E6B4BF52E3360537570AC2 6B78DEBB5A4CF405A5148F8F347B06CE56CBBE122C31118030C84A98A1BD4836 1AF6821A66D47105CCC7D3AA8AE37840533E5C7CB649BCBB3528170655E3AAC5 26C029DE1F847DBDD8BD4AB512388D7955AEB37F6D3FE4E2D018089AEF0ADB6C A1CBB1652E8054295C5F05A20464C6F4227219D102C146ADB7873A80BD8FC7CC 76462122F9DCB2B8235ADF25D2F30CA78DB8A35DF9692A22B0853E1BF775428D 1EF7A0D676C74963624D307F0B2C5A7DBF6CDF8BAF8F429A6979DC7D85036D2F 38A509E9352768B42318C5B0CBF933574651C4669EBCB1381CC8FE4DECDF34AE 5D59166856824BE6F32BD44F54F3B65FE94CB6274F05E763B81C14C326B9C031 08FAA462F1345C836114CDBF055907042A4D962BC49E69D1496F2CB72B108D29 CA8E4F767A6569F3CAB91936CDCCF48915D86B816D4EABC411A380B09A2B21B0 F1F1E4DAD2E4FB78839586E6131691FBF01D8744D4E9805DE60F54B89973F437 FB143D3B4569213E4B329B6BBB5AC3EDC48A76972A20214BD32FBDDCE064EF41 264E1F0AD96737451BD20132F37A95F47A647F08F0EB8596E1BE2200ECEA2B90 1CFCDFA6F502D5AA198206EF8C48DF474980130D85423992230F312F81BB71BB 5E6C1DB582619493C7E9FBB84D3EECAA879F4C65EB247CC297B65B7B7AC6A214 9D42B1E48F2A46D478FE17EDE921D19B6C88C7A066D8099E6AB1B635E54F92AD A553EF0BCDE18FBA6D937D5891F43C17ADF78CE27E753EBF107CAE906C278D1D 4876A59C1936A1C2B6075C9F017576600492D458140740A727A6F578501457E9 7DEA4EC012FABB2616928CA74E09A521222C591F5DC6D98A1BC16AF23028D475 FC908367C03A997DE60D1479F5A7B6806921CC05DA695BC6300E74F321E1E6EE 5F89D59F3DAD44439388B78293192CB860E859A3416F35245558012FA6CBAA2E FDAAE0B0625C4FF94AFC81AD662E9E5FC4F45D3890D0837CFA256C1FF7F91E29 4A6887858930D4015A84E5B5E00A5068D1138FBAA9F9DB02BB128C4F7C5BE133 D51775291856A5C990E1463160E1F1468D46D0D1A4C4ADAEC5200791134C45C7 3DBC1B8B365ED24029AE955A3DBDE0B86F7D592555498EB35643C659DAA7A2B0 9CE87F683537451661E52D452659743183F63103A17562FE40AE3D3A0B395E17 2F0E4B8A45AFB72893A1DB5966727A0F3540E5B46D516B77CD8704E30B80C860 C00BD96162FA11E944CC101E862757A1EFF39DFA09CB81B71D8AD9A5D212D953 88505B992655C402C61C196FDA96AB48AEC1CA5AEF52BC72C91980A332D45382 569C6C65A4C357E0FDA40885A0DD4971FB62FB487B101A90A5ACCE95E970F779 14CC9A2DC6BAA9A1DBC36905998046DF63328BFF0DAA547532F3CC31717B2F6A D7C806 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMSY10 %!PS-AdobeFont-1.1: CMSY10 1.0 %%CreationDate: 1991 Aug 15 07:20:57 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMSY10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.035 def /isFixedPitch false def end readonly def /FontName /CMSY10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-29 -960 1116 775}readonly def /UniqueID 5000820 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A 221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A 27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF 5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09 0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730 DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A 71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09 4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C 515DB70A8D4F6146FE068DC1E5DE8BC5703711DA090312BA3FC00A08C453C609 C627A8BFEF75B4DEFAF34B44B356A516B765AFCDD3F5475B1F928731D09D2170 B97E40F12CCEDF4F6BB3756C4734F6E98D74B7E942A954B1BAAB83D4AD727FF6 DF6DC50B2223BCB5568A73A112E4860AD490554E64E780073FF3399CB4688D33 9E8829667CD6EAEF25E0C7D2D44F2BBFA40E999325F9561514844221B50BC8FC 4C7AD68CA7220D69125C2AF06849A3E068D18733276F0C0A6A2936D3C2C87CDE 59CD1AF148C44F85784A5DAD569F5FF53C061056C067CE29AEF1E3BD1FD8B0B8 71A0A638CDAC6AEEDBD5337D4683C084BB60B1859E600F59CB4E19C5FC5C6327 EC544A68134496A9BD0B87D83AF6FDA3CB62FBF0B54FACE1F0E6A2D84B467AFF 0F62DB 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMR10 %!PS-AdobeFont-1.1: CMR10 1.00B %%CreationDate: 1992 Feb 19 19:54:52 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.00B) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMR10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMR10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /.notdef put readonly def /FontBBox{-251 -250 1009 969}readonly def /UniqueID 5000793 def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4 87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F D1F017CE45884D76EF2CB9BC5821FD25365DDEA6E45F332B5F68A44AD8A530F0 92A36FAC8D27F9087AFEEA2096F839A2BC4B937F24E080EF7C0F9374A18D565C 295A05210DB96A23175AC59A9BD0147A310EF49C551A417E0A22703F94FF7B75 409A5D417DA6730A69E310FA6A4229FC7E4F620B0FC4C63C50E99E179EB51E4C 4BC45217722F1E8E40F1E1428E792EAFE05C5A50D38C52114DFCD24D54027CBF 2512DD116F0463DE4052A7AD53B641A27E81E481947884CE35661B49153FA19E 0A2A860C7B61558671303DE6AE06A80E4E450E17067676E6BBB42A9A24ACBC3E B0CA7B7A3BFEA84FED39CCFB6D545BB2BCC49E5E16976407AB9D94556CD4F008 24EF579B6800B6DC3AAF840B3FC6822872368E3B4274DD06CA36AF8F6346C11B 43C772CC242F3B212C4BD7018D71A1A74C9A94ED0093A5FB6557F4E0751047AF D72098ECA301B8AE68110F983796E581F106144951DF5B750432A230FDA3B575 5A38B5E7972AABC12306A01A99FCF8189D71B8DBF49550BAEA9CF1B97CBFC7CC 96498ECC938B1A1710B670657DE923A659DB8757147B140A48067328E7E3F9C3 7D1888B284904301450CE0BC15EEEA00E48CCD6388F3FC3BEFD8D9C400015B65 0F2F536D035626B1FF0A69D732C7A1836D635C30C06BED4327737029E5BA5830 B9E88A4024C3326AD2F34F47B54739B48825AD6699F7D117EA4C4AEC4440BF6D AA0099DEFD326235965C63647921828BF269ECC87A2B1C8CAD6C78B6E561B007 97BE2BC7CA32B4534075F6491BE959D1F635463E71679E527F4F456F774B2AF8 FEF3D8C63B2F8B99FE0F73BA44B3CF15A613471EA3C7A1CD783D3EB41F4ACEE5 20759B6A4C4466E2D80EF7C7866BAD06E5DF0434D2C607FC82C9EBD4D8902EE4 0A7617C3AEACCB7CCE00319D0677AA6DB7E0250B51908F966977BD8C8D07FDBD F4D058444E7D7D91788DEA997CBE0545902E67194B7BA3CD0BF454FCA60B9A20 3E6BB526D2D5B5321EE18DD2A0B15E53BCB8E3E01067B30ED2DD2CB9B06D3122 A737435305D42DE9C6B614926BFD44DF10D14402EBEDFF0B144B1C9BD22D7379 5262FEEAFE31C8A721C2D46AA00C10681BA9970D09F1EA4FA1566B96E221864A 45A24ADAEC63F61C9FD18376D39E0FDDE3FB4FBCDD6A7B66068A99D31CF54CD7 DF2262DA91CCC72889CAA62B1D6F2155CC8E940A2C35D8CD3EC75326188E2D30 1090F31AB50F30AC77D2C445BAF7323389406C44641B3A72C26BCDA442504D03 6C22A3BA1A69E5F87EA400501A3B3231E46F96AC3A6C0E4A4F6F21E0B2BEEF53 E016F34D7003351FD12436520926C632218410359AF9FF167750D3CE0DAC3B91 B310C457402E05C316F400246C8C38B98CC8030F71104BC4FA0505B5EFA4F5C5 9E4FA27C3E790D698690336254D7E34451E692AE23BF5FFBACBDF33E25359BD2 B0E7A0686602568BC87422F32486CB50776C7EAAE7F1BF78B228CA3254510653 3D6368A4985C5FF5A48AEF16E1AB71D7CE2C6649F2CF4B2879D4FA042239B504 F988D2FBE87C3BC784E55B8EE36F1BB5EF14FD5836CA448E139EF8FE221E827D 0608A6B90E08CBF44A30669AF4E20CD5C0C8051E5F86062204AF362DA690B74C B952C9F4799FB2535E47AC019175950A1F3A0D0937016148222B545B1E00A91B 39D2121462F51F736802C523BCFBA894EC11C3353F9BCDF0892C00EB583A4D62 247118996064991B816F9F490FA73861FA614FEC7FC23A5D45310527B6559781 F1C805F0EC931D0C60E70FD5AC55F22E6379D369303F63A0E7069237118DA0A6 5BB55FC6EA1797BC51C1D053401ACD4E9B5E724F4AEB149C38DB0E2BFEE811A9 A94A7405422CDC911CDD97EC4976E27F766A9E3F84387C04C6367509157E4D91 09A1F6DDB59AB9096FC43A6F9773ED9CE3DA6B56D10AEF99FD277F8666E72028 807AEC6C26E5A142496CD41A80EC051E875DF9F547BEF060B969B197AF97608B F7A3740B3153621A680DAEAB0454706C65581255CA9B40078FA6D352737F0165 D834359ABCFDF5C212F8AE9FD50BEE9683E7D5969D183C058E8BDA78F61B61AC 98746B3A1750093A40C17EBD4AEF36BB2DFA1C9AC2A12834DE4623CCC76BF5A7 92B2B2E368D1DF3471D83495B19154836569D2A30F9CB05C0EC499EA5D3184CD BAE8D2A2CF80C6359275B3894B4DAD7F92501BA9A6BD215256CF9F35C2BDD40A D1D949000633FF0B5FC7674BBED71294AD28FF25710E968E85C3FE71046BF0C1 71EF48F8024C28959FBE6E896BD1AFE579764616672C724959FD66C8398ABB5D 6C02C5619866453708E3FDCAC2754E9C333C1123A5F746DC5B2CA9D430263645 A88C743EBEF8C82DA0236FB73D3DCDFF874A1A5928406838A81E40F34816EBEA 0D7A89406A6F492E5E5E6C8C4D85A2B9A83B6A4304B05AB541041AE014C845B4 283CE3F75DA22CB7CD78C67A1F067C79B209BDBA6705D80FBF08CD0FEB9D3293 D9955BF6730BD59495A1F81B708292B509537089D8AC34A06DAE5E8BBB9B0A0D F09BA6723DEA964F06C0E1A6541656470E251F5AFC6677043DE7C6D85B60D3EB B8A4415DBFDE3F29D5FAA0B5CE4BE9559595265FA8BC24A172FBAF9B1AD0A4E1 1CADABC2B71A43098146DBFDF7E126069259EB490CAAB07D5C9CE5B2078DE52C F601B08B5CFA7D9D11F27DDC99CE5DDFCEFF0E0CF46A6280971425B758AA4106 806122ECA28861AE8E3BCEDB2F923A7FA92BE2DE2F5B1FC696DE488624F81C91 E5D9D9B90A7B0847874DAD266EC2A04462ADAB73ECE8E61543BFAFD9A1791ACB 90485DAD563AFFEE31E08C5D12164386F831F977699577B89FD7926E88F167D4 01C4D048865AF2B3E576E53F4723AE10E124F5B113C736B34DD4ECA9A93167D4 323EF5B366529E06B4B47F942F15A7EFAF2D078F9DB50F69CC4DB2EBD5D53006 2953AC8496CCB2B9BAD6C29610408BF93271000AF13977C1CF28E57500524DA8 08A09D3834F7835C236378283ADB9B52FEA032D1166D8AACFBC73036DB28E7E4 CAF0C91FC641CDB56CB925824475C93D094AD625C99547AA29AEADFAED4E093D 6C98357D84049D9EFD7BF4C4CC225F9DBFADA318FAD0EAC89258D3748DB25440 7DDDFF14E524884C16775375CD2198B878F19A122CA2DC8AD4A7D46CB77C16E6 C3B619C52E43D282170B2DEC99AB45E8E86B9E57A983A5D7CBF005CFFF6F3F11 22FC046BB1BDED08BF0D7A3A15276EDC52471DADFF7343083D304DDEF1F0C786 415E8441695291B168361EBF8BD1F58ED22BA8D7B7BDC3BB9952B336D5685841 03F71AD25A04A918EA5DE48D694348C93A289BDAB9362189C837EE25469A2A0A 0F3EC2328EDBED69EDE51F861D06C6BF210B9D5F1B2E1DA2C1371498F86D507F 4B226727023C327B2686FD3DD5FAA8BAB240A09BF9731F4DD2D22254E0FCF50E C6CB7666851EF2F068E350930AD461348C98295E5F4CBEB54CA3AA332385BA78 CC2A5430916D5C71A720F691E169790187E2A17F04997C257EB763F5D3B572CC 17086E0D72CAF12C756FB443506E4C7603ACB020754CF0F648878AF70A665DDA 66986D0B2488626CCF9F83D61E4248C7313E5D4EE6553E673093E2CD6D40EBB1 8EADCEEC6C88E0FE19FE9AC882B2B6724881DC6FE472F8BC67994DD41E5D853D 1124004EDFC1A3E007B8F91B1A621940EE092A4E6FE0150F77482F752796B68E B3ECB695F918E2F2F4CD9B8F72327DED8E99DE94C9D32E65B8FBBF9BEB8B6958 D6A6A50C81B24BE3A8D3E820B11D8AC6EEDC61776A5B5F59B71157A28EEB123F 40FC423E48A82223A418AED337F7D05DFA256B3954A2318645E79C14C20F755C 8416AAFCBD8CDC8B5BE029A6D414DB5F04098FF864CABC578FD7E8016B149AC8 B22678CDF68EA6C95D056431889346FBC7CCC72BB00E064BA7EB2A6CBDAF9B84 AD391D5F49CD9FA9C2E451FB64186D677773F0F9C2B64EFEFCBF18169C98B1C7 DDB7871F09AB8CCAD5F6CA7398C14FC3C230AE6444806466CB241B50CF1D2E50 36E1C1EDB2A582C7AA0DC67A17C1A40858C4C50C05EFCF97C5B77EA3B4142FDA 6BCD59E52A0FAB81B65881BFC1FB13DF47F6A55B0CC5329883947CA461E51B2E 720B6E350B4574DEA9D7402A25BCF07D52CDA8B769621F14B046757FF2723244 BA6AC3ECCF41C16733DDD7AF6280965A4B9C2E1B0D4D62D6FD01E241DF214B10 E7C2546F824D168DD08BBD724429CEE14B98691A8EF613B35F082861C07F4623 BB141DBC314795D15599C263B138BBA1254F2903B8CC0832AABD542164461021 DD420E347251D44B862EDF833E6DC4CADCF9C61434B9107BCC236FE9E9F9BAB9 1C1A4F2AA25886CFFA46B7FE176D5157B5E7DCA4BC5832131F81F16324027417 7A073C57C9C7C53FFB0540C134AB094076A83B56880B041C915D0892F338609F C4052F6500071BF046EC0D3F2B68A910F14AEE19A8D3D6BD3F1583018CED7E74 F5B05E187978252B843FF0ECB66ADC4FAEC18B5A3B59A4500EFA8EBFA7CFF5E0 A10B2B33C1E7889534599F6085D56A01906A63B044FE4AB89D46F3FFECEBE52C 3DE1B2C4225AA750508FBEF09AB7BF27263742D72128C55F5C894E3E8843989A 4BDC4DB9E435C7AFCA01BEC5261102C4AD54B9B41B7363B0904FEF367AC3433D 3E71DF14C35690042A1B9DD5F660B5A133E8C496858F633927693773F1262C37 24D306447E51F6F944CCBA6AB35FDC596D3CA6B3A0EFC9184ADCD1EEEA05E9AA 60FE7318B333082E7A97BBBCE84319431F6D98D5B5C4FDCD5E91F3D077C687E9 C8597F3F78D9ACE1419F0E7D57BD82376BFD442FA03A57A30B7FCB67F5C80AA4 A5657F6B91BB5A0CD6F3C3A6A13531928B6B6EB6111B2CE51A4269334C5DD025 6BD41BC89AFDDD1937BA70B7A32E1D672379A524BFAD31267355F6FD61E7A287 7D312907BC57D18DA8593BB5C4A10C1B22B8D5883D48CA00BF79FCB2C17BCEAA 16652EC9F219E8E54CFDC540DF31654E62BBCE24B8A181213146C03052BDD01C 0A489538D190C9AEC3B83EF70B7D6BBBD65B2731A37511D5EC781236FA0E4A3B 078E79B6E70186ACD058FCE1FEAC9AB723D0D7F64DFDE39E8816E1DFE5E6E255 F9683EE52CAC33CBB3D69DD820EB9888CA73E80E632BFFD1D41EC00AD483D22D B2BFEAE98691A71911AD90C2CE0A6E1A0D684470ED53629B1BE9173C7CA0AC64 B57B6EDD301CE2B778BF3F667778A9281E4FB5ED8FA8AF58DCD8EEBD3677E20D C4AD9B5BE898FA29606A3CFD9E9F3281FF81187FBC102F8C01EB7E57BD6922E9 7567F82ECC031805F5E3A17CEA28A64B1FBAC1A14E2A4447B3F4C78878D14650 F6BCACB56CDA8A71A500E739504AA4CE3F2A38EF27AC19BDB5E617822099730C AA9329A7B60C779E951275BA39A919605902A0E80F991429057C0C2D37502368 B16E1922EE8BEFE9A87FD9F613564EF8748966C0581AF8DD94A5B1C8F2F2CF86 B6BBD7D004F8D06AC28A6ECFFE68D444C012198F16E0B068304EB9851FC90BD2 F176886FF95554517E256CF8DC8EEC585AE77B38625D29A19B54D6C1456B9CBD A03476A57D5EC351F33B1DA2A67C47BB699267B9A48AC1922F47910CEDB3E453 B949AB9B1D6FF3C656E1E0A14D872D70F405493D05335A3F8697C7628052DD9E E14612903561A3B3B949315AC90F2DEDDA2D0D91772483BA11D8177A3165AC02 A1B92D1D355AC976E788EC1F178B2C36BC9B180AD2A150AF8E673083099594AB 93DF01C1F0F090C94473CE2232AC10F09B6BC7EC4F3E47D88268CE278DC8B716 E1E472CCD2E32EDC9AD4694A78A097252317A9299F4C61B4097BF71FC75FFE76 B94DEB83C5E350CF5B929BAB0CBE6547896D3C0D28FEEDA3272FF56082D556A1 5E3BEA03E5A491A48793CEBEA73008D2A3B93D8B78BFFC98D52E51FD41DCEE70 D580332266DA0AE9FEBA1D02997D17F6775E9EC9C887592A6CE6095AEF3A87AE 91448A5D13D44F0B93D9DC99811CAD9A3A4A89F0FCCBC2EE82ADF3132A21746C 6FC523A06BBFFFA42193C0337CCC7B14F893121AEF8F369480B40C5D0829622B 1D21BCCB22193AB616004EA9028548CE9FECD416BF2335AE894B134CCDA92CAE B838E1B6BF0FD40502E4D5F116A90F0D5B92D8CF17C7439BE7C6886430DF8DF7 9A31895A62E538DC391D93C6AC808E59B7197BA11BF65DDD1881F1E9CF881207 11654931A72C5C2D57F638F889A63C7D3908C20CC8E9A8DD1284142E959BAAEF 9BE78512DE32097B771A167A2B899537CB35B9F3CDB734485298203CC67EF1E4 BF7E8087FA8C0ED2B9497B42110DA8CF56D96C21B8F88EE1F585B92FDEBA22D3 288696ADA0BFF8F10C40A5DA9F470FDAA6464F7D681ED774839C34DD3F99F6F6 1910657E13F49055499A66EE4A9DD469594E0376132C782F804301B144A0B897 E2C4C22AA1BAECFFDC98B97806C41E6CF2DBFE912A82C1745D64B536E253D9CD CC8416A186D86D0B7881D415D89D085D802CB8C950399289B046EC95B9AE031B 9BCBF619BFC6F248C7C285A46A62B78B77D738F38C6A20247B39AEAD87F43EFC D73C47E5932B01ED13B1B0F2AD194D991D470807E0520BE270CDB21C8E5E27F7 BBF0F6B592FE208E1A3EDCFF68789AD1785914081D0025968897B0E1A4F2640C FD45163C3A7632B87EC066026F5FF0CF6A87FAA3BA38A07110C0BC24F5B5EB54 8C40111500DEAD7A5B345FF04FAD24DC44DDB790047D327AC412694A3DC08713 7635693CFDFF586E6E77D9830F201E3B0C10D29126EA713D49CC2FC2DC2365B3 B769DE1BCA70A149AFD9CF0292A5EA7575FB9C7491EDC1084F0AF3827D88218A E9E6F5B0FA28E995A5CFC86BD2771AB0FBE64DD0AD94D342166D019531054187 45078D1839A0808B11C75F714A150C660E810619D3111AF96C0DCC37BB24AF44 71B8059963AF04D02142ACBEEBC3005B7CC331C7BA99C877CF8F354D483EE90B 1EA0F98F1E036CD32141FDCEDF445AD91CD7604FB03BBEEC5D22AD8BD0C6D656 7E2D8C0C00D6A3927D608C104250ADEC12235A47F277A505B7CF3BF6287A6C66 4F0ED0FF204B8A62BCAF01C04A2A70BF3B17E3AA0C7BAB1883F6EFB0D122E8F9 9352EED2B61868C26B7803BF8CBE098252837E45FFF0DFC71BFFBE5B64B742E3 5003F46B8E87D5BB08212CAACEC607FF32349BC169FF332E7B0BF23D95C85142 6B6E31D9BB1B6AD516A759EF317497D5011EF86CEDF7768945CDCFE8A3A0DE28 D2961A7FBE20A7AFFA0FD6955377EAE1F7B965D68E39BF2E5C5C231B9EF76070 EAA30D37E02A2D68CA419E98246D668C8E69AC2041B0B09C2D9A048444E8730C AE3BBD8906B6B6DC39618D0AEA1B3B9F5CE9EAF27E96A38581E55FDB473087AB 8F05181BF7E57EB9DEDDB5DD52CAA370E619F8A38F4C74289D25FA2AA45F63A9 879088560A2D29C12CBF54289D3BF44D3602467E3D8D6CDA06C96F66C60DAB32 7B607581417E8D09D8C039FEAB9CA076D7FECB8C6CDA81195DA95CEE1B8C7938 16059BA9397B57BE6F6A0163B47E1EA95497D8AE22AFE189CB850A8A3E39BF6B F391425DCB0D8BE904C4CEEE2002B2CB7151CC6EFDA5747F523BABF40E055365 48A46D191C90FBFC6C62D62F9127012333F7183FC9344794B05A9F4DEE421446 21A7995B002927451B139FEDFC5982B71773C459A5B096016236F3F34E9E102B BC3FF03B3DBC511B6248F9479B00C7385E1742EC6B1CE878D4A30D74687183CF B5ED8FB83FE595F3B8B922AEB61E7457F4355F16375D988C840C1F6510D89473 8486A28031D92AF14B2308C49447B2663295663124BA924EE6F23801FB4A6F45 386CEAE8D57FF1660AD8A587DBE42B3D34864451BC6F9CFAD68D41CBF4EDF04F D070677B7773CC342DDE16AE2EAC2560CBDED43E04E30FAE552223EC14A84BEB BBAB59B96C7D09BBF01C0C28E2784242B88F5EA515B9A09033489CE399C9DD83 CA1A2FE4238C607852AB5C8632FBAC96575379A563DEC4A2066611A9F85CAE4A 6CFC20C8C1800AED3F322A8DF02CBAB61CE43D2FB2FCD1105540F887D92B6E6D 221B0CBBD4EC66EB828B76C087E30210E1E1F39AF2D4587D0416B48ED10646CD 51986BAB3296B9928DEB9F312FE4CB34D61E4EF196D0E9D8978ED0F1DDA71749 FE2A256411A256806767D1D7DD8C0934A51CFC79D15A46D32668BDB0BCCE9B07 D13FF9AD77E9265F3AB4D4602B842216124F6D48625D5DD43B63D27EA9B41187 A77CC0C469B27F3E45DACCAFD093E2A83F4DB1A73B575F1DA48612073CFEE093 7A27445ACD90F971BFCAEF9ADE5997A65DC496EB88062A6BB48B3383415BF79E 5AEF54749B91BE17BBE3601D8ED2444BE1DB1B1C2C49D6D518FB6CFCDFB3A630 517DBD508D273FD8DAEA55ED2BC8E2B6850EAB4E95E99D645F392A486F167785 1F88CB42DFE33A7940193508AB1E0B0A7E6B566E1E6E6D2D3B9C65935856D9C4 DFC06DF118236C9C5F8ACB33A8719E4B60DEC75D19A30F94143C4B22F763F69A B7CFC172A15E8B48BE1AFA2ED41C6AE00C454F503E0D6843C94205EA4EA9AE2B 169256D72F95E57356D67CF369FCC69F0BE73F1785054A9FA055DCCCC4192354 5D29EC5946E65823798508472B69B15D404B241B1A5238F57942ECD7C8C64DE3 4B34CC35D842E3DDFBDA645A15957DFC1A2776234648E1DE8AE2A3F51813D704 4B83C2719EE1173C4AE6F56E69345A41091F8DFE6EEED9E2E13D6CF80C11F180 E1C1862B5773FB941346B5E6B2E05D3318063821B99A164E387DA14FC19659C2 8CA28AF6989B6F70CC17A9C3E60150E63BE147A979C25EAA2E73AC307345E690 673BF49D4B7102ECAC2229E3CC6992B05AC50F3F6ECC0D58D54933643821A045 0A35394360F81BB90AC8CEB9385889DDAA687FDC8188289FBA3EC9FAA68E4598 D4793932D8F36940C86519BA90B4247189A0AB69361F251B9EB5A825E7970A0B 4F1E995A794590EA2EBD7D87A07140C199C772B8F67F8C6AF5D889B896849323 CBABF21D7732DC064E66086EAC959C3B61B60A125BBE00E9F56923964E2D0B0E 04A62C67D0964CB78CB723E49E91859A3E9BCE2FC8436D5489A9BCF3A7C47412 AC804F78A8C36205BBCAFECE2E31FED76E91FA0EEBA917B39953FF7DFC4F191D 50AB3F777515753D968B3CE2DD7C6E771F6849CF9234AD855FCB0A68B82AC0A3 BBD801CA66D6A37D0C8D18611EE4BC7F2874FEBD5CDF10DFB40A2493EB8E2C6C 4BDB069698E5A318A8A809D8F35636A664B7FB831B9F4B7E6B1FD3A9E8D487EB E01416095C52870C029FBCFAE81E82621545A5A25C25EF4F690F73C06C899CDB 1534476871CFE868D0F2A0AF9E100FEA7B464ED5311E94CB04C68DBE39FEDF57 7D427D491AC9798276BE3A75D34BC099424DFEBBA024CA183F599CD68FDD2A7F D78A0DE57F11916EB5908D765ACBEF6990BC1199F4B3CA9C43E486728D882EBD 5D6BB8898AA8CEA95C7E7C9279ABD3D4485057C21071541B0EB5530791D28531 05C0F37EDC064B35C579DA5DE7F82F9B081F31172EB9A04C31A17D030C4D7E2D 547D687FBC8CF58C31E543B4B56F6145D4A24AF0E1EA6532D9CD0DF732269451 C1213436DE6F6D67157005C66CC1E96D536195B6A2184FD0EC3FB2F9F328EACC 7BF4390EE9C00F7285B6445A999C6BFCCE31AF57DFB59AB37C86FCFDC6EC5935 749995423B560C839F5009950AB78F5B5849AEC8AEC64ABD637C57C017855949 F7AD99B8EB8D3AAE2C7E75E9D832B1EB74D11512D1785A55A24B746370D3D1E8 5E881A9544A018669F2D2BB53C66E923BB88A493C4C262CDEFED9EEE82D129AE FFBB1ADCF7B1E847568C1E10CAA26551188B73E0A49B9271846BEC1EC3BB45CC 6C324D3D0624D9F28459661EECE52E1C13FC82A32E029E8CFB51C867971189B6 7723C5090C67DF3F38A63D5BEBC0CCE14FDD8C602AB4802BB56F95255A01AE8D 7C0C4AC5760053AD99584E7C7F67A301790E20CF95461C6D01B34C39D734D811 44AC497FC0A80E5EA0A33F8C6DB4B5C76C1B69DA7D8068F26F86A829A6B2BFAD 40960223E8CFF67C464012ECD1A36A5737289409B1B7C9DC51824F5FE7A2B32B 9234595C2B6F4EF5FE502B10FD8477A39086DF8540D7193605EC08233530F595 32BCB2484BA4A82F87B23BF27683B71BA834EAC1F3BA14B99B5D1DBC765612B2 924EEC6E7D14C2C76E99B5A1870CB0546347D1C9A31A1F9DDF0A639EB112D7DA 4100C199AEAA5C2E391DBFFC01F5A196A765E9833ECDDE3D56FE2644F1F275EF F6D26A77A4011C74357B2AFBCA15EB7A2982BD4E06EB3A4284446732687B24AB ED10778294A35BF94F2EDF92035495E818C054B37839459230E50FCDE1EAF6AC 2C5A583AAD4704E6193334E5CB7BE1D2E766922EE6502CAB3EBA54D34745D0DC 3E3DCF6F717C8FA8FA9211D332E793866BC12D017E657DF06958B6547612F24E A8B8FB6418B14DF363D96A83C29D8EB277E1B59BAB33B7E50F712DF83B91283B BD6EE23BF5F9B71C9A168D1EC28C6BA5F2A737B28E7EF26F26CCA76E0B416659 468DCAB864DB04CC2CF17EB2D4CFF2CD4C04EF46E0B506EDBCD4996A9BFD2EAE A12EB1E0BFBF1141258664F54BECBAB6E56C00123C1A1D50E10545E8176B0CAA 53C70D0132DAEA2DE85EDFAD592ABECF8A1AF29A61FADCA2F70EBF5FD726D46E 7F0F6E037A43A2CBC19A297729F7C6B0216720E855B6F2C7243E74E674540742 2381D7A76A281732983941F2D384EF949FA45685E541F69BFD4A4247E40678B6 53669D5DD182578191203D24311BAC4F839674AFE1A560508C8A15DFD1A875E3 6BCC257C7C02EC9DE0B54271D4E3FFA9DAA25A14C9D17C2E5D4B077F1D225EBA 322653B847021D16162072F8D6CC2E000F5041C391E7D5EDFF7120D28B353E4A B2F708079F2D4B084E7784FFE071BB16E1C65196D879CC3A395DCD1E72C56756 78DC6505E0DA76DC28259940C60E326115D53A018FD35D6CFEC65B6963CEC6CF 3B1E25860A66196502DC325F0973757CAB6E59076A208746573331ED530145D8 65B803D33DD57FB1FB6D7B4A9AC638DC15387D0F5E56209DD316F391CA20BD56 F235AFC31556B92FD52B48CE181BD42BCD1A098E86CFCC91912C6DE17B5C3270 6051AE1489080F4798474EA2651843B5FF7D2E356316E889A8080515B0A6D20B EC448BA9F3F4B0090D3107BDD39F02BBA503E0632BA8743C52CD064901571FEE 45C3EC407A61667C6F287FB7DB8C5620EEA8D413879125FA6F828AC2E71BC1EB 4FCA65246747BDC9E3AB7E4BA65478306D2C529E949344C687352C8041319790 6FA3EC6EA97C91416DF7AEC8B6271860F901D91FF7F62E183AA867EF0FA1F55C C53A843DE88CB49030291AF673D20F966EA5F3B4EA857217FDB3CD8E48CA93CF FEC3B6E3108E70035694A68E324A7D4A3D86AEEDCB5DBB7E02CB473E6E1D0278 9159F891DF3CF82644548A534DD281261D3C04731A548DA8FF3097D3C10651A3 C61244CC317216D0D10BD262322B3F8438C26C0235F714F1CD5FB1E5F9A6D5C3 CEF09A9276916BC1CDC6E24CB862441DFF9510A649F17B085B1003537FC23D66 F1A7BB07314E4BBFEFB572758F4EF4EB1EE8BB805B4010AFFEEA07B0DC392755 5086169FE1504FFA0CBF4DAAD020584E1B3DF1A73FCD23E7337075FC1DC8DFD6 E6DF8E3B6A29006BE2AE0A1B0A980A679110EC541BBE2B351F682476B0DAACF2 31709DA21D0E72F95AF93DE39E837B1993742E25B1A54BE93FEE8744E8744924 E0E12B592379A23FB9AC9E75E8B9E8E1668AEFB160009ED148AAD7BB5B45BB28 3C0927632D00EA3EB125850EF6026783F42786188603FC53021F3A20B98744AC 66270DCDBF7D9C1B81849E2AE1C51BC604BA578F39CA477657428C02C7EFA1CC AEAB27872791E0D73838E4A5A1261C32A54AD46C3916F9F3739F689D17CABC60 D07666D091927F7B6C2D923F962992DBE93EADCA96FDD57AD70C62D054A101D3 FC525BA903219F59DFC53A387B5DDC661D0E34E150FDFFE6754CBD8BBDB2C6A8 46C370A10F119E4D3C00EBFA9CF068E558423B702AE79E2E43586B41902912C3 38701FAF98461E7A8EA7306252C0BA5401E1909F26CB8A734CF180641DCBA9DA 515462C12E707C13DB83158A0036D74E3F3D9B3841F425C14A6F8F240AAC46D7 27EF4D5FFA5401971B5B76233D4B6B5AE6E6498B989AFCBDB75864A0A555B49E 7632EAF434DE0596169018926E19A85D0533D0536D0F2A2D01F19BF5A2FB6678 7A928C2C47123716B0C8E06F3132065EDC84C80C64DBAA2280E1ADC7ADD4D6D4 1C7ED5D02F9A246FC7A4CF04A742B49507CD86D2FEBF6A02802F3B6E0F917D93 5D6118EFA2629D9E40A8133D8F9EF0C8FF71D5E43D62AD50D474DE21BB008CA4 08B02E680E381EE2687FFBB30D4CFB81471B714DFCD30161A4EE5415BC7FFC27 81822F053A04A9D4AA40093D992C3EF62449415DE8BA1591D0063EB5D893819D A09FA433C4F11957C5B2CEE44C86A742D91560AE62DB4EA49E2EC48D28E06C6B 60F7565B23FEF535F5FD104620D4BADB9597395671AB338E794C2008510C33BB 1341CFF7615919DF9FAA6D8FEB5CC210D9475947049924851F0FFF68B75050F3 6DDA4B0028F03A833407F58F224C29A9D960A0B2ECCCC397B06FB970755D04FA 983F0261EE9D0905A78158E5F3FFAD6550683A207AA3B21A66D2B56563A90A16 258FC176709C430ABCBB6A9F2F84DC117275832F4546021C47751008ACF71A58 819459EBD49A571B75502EE240D9ACEDD52817EF46C65656F92EDA14708194E1 75643A90C6D41C7990D0658CA43F51240035376D53DC6AA9B614C21585749474 2E6F45307884609B5354C11B22B36D9F52962A52B91CBB71D42321A8F62BB62A 64690B08E6FB9903231909E87114E0D7FD3C5C201189DB0615535823B3E4EC7E 085FED5DF5A1C22BFAFE5A00D93F3EDB9FC52961438E67A1C90B2371793531EC D69FD4F2A7D407FE82B39D692B15E3F894796A55891CF7F944A8BAC1C4D2B5A9 950247043FC7199F109DA4C75CB9E29DECA355A25D09C649ADA07C518A1F41B9 CA1509E42D530A9A20B27ED5E095DB4E1BE8D7FC418CC4B05E11C722DEC5FEBF 1022AF3AED5BEC7618967434B632403A751CDC19DD9E30D7F4C0F0E4BD8EE832 3B0627931EFFB560C6E1D30422F8B358DEDA0DC087DF19A99751ED86DD39188F BEAB4029C2A5D5DDEBBD058BBEDE9970FC727F627EBE536816BE96C9D442F1E3 AB971B5A3D0FFE8A0BF6A859D9388733C0872A8DEEF6DCBC79DFF61C639CDB5C 4C5BB2EC67094B5D744BC92E1E41B09BF15A34662AB3A5A5DF44E78B1F140FA2 EDF715BD6338660AA9DE6CBB68B34B4261BD964DC30163AA97474807AA7E6822 16BF04B5F77B906A713E152F1F124C6FD9A9A79234143920304712DA4EFFF502 FCB82DAE3F19328C2AE65BBDAD1848377FAC137556E5052B42538A218C95AB00 3454C2374279ECB41EA5B71AC78DC5C4C311BE8D1223DE52D6B5A105D43A9E82 512AA823B64B495DF107CE9A04A891F0FD51F76CD2B636DAA553C1EA090E7575 4AABA7092EF91A2B7CB78AE0989B0873B4192C17376666DBD385C54A52024FA7 6B1CE6EB7BF148FCD7AF7791D42C47E761B5F5B5491747039E133C38D20ED59F F00EE9CE6B9D046FBEB29237C19908DE1B12ACC976ED199A788C2B2F1FB1F9B4 533263E2C9DC7C1BAA919A751B5484551AD6C32F19C15861A32EB5E1B614FB40 852BB9F13D1EBFC394AAD24F14533AD55B695F70F9EF4BACD1C5B2C62EF6AD9B FDF8F22E43F3975F6AF3518C3A6E8EC063507ADAA45AC9FFB83A5ED2076FE507 01B87B8155B8B38016B89A57999240BA74E3A9E48A089602E877210ED17322E9 CA594BE86FC7845A9EFEC81E9810A4F23ED2D60BC9D71FDA0AA0BF714EA76DAE 7A00E3CEB0645336B657B39615B3526259F288F165A0AD61E872E08E0F40DB0C FE62290556A53DD9E73EEABE867CB92AC212001E60242AA94B6122FCB49340DE FB97E69CC6B2436D9A72C98EAB9E7D56D5678F18E7A95F2EB373AC7BBBD3BCF6 D8E2F536540960EE618974041BB18BEE35F2F781267682A526D6A1BE39A15F09 226828A95C1203D27E1A4142B1BEE3E4E22AB8D436F6E23646C28299E088CE40 C2E79FAFB8B95FB304D3C17C5A6DD61DB73E3F836623585B45186C746B9CD2F6 21D669C394B988E4357444453A81CD77661008C36AD5504E37231921A4302BB9 1C4EEA665071F2349D012F162EF8BBF82FB95ED09A8BDA8A0586AF059DE425B3 6D4012701CE7A65DE9C348D17E7687D66896B792EB5D2B2813CD20D9B20C5B15 8041B8BAD2D143A515AAED58856D34FD55D2202056B09124E684FFD25935656B A5A04EFA85DD32AEA65E41B2E58EF2B903C6BA1DBE287218D22F436EB9F250E5 A0B18A9C1E574F70787D18DFFC799DEF1DC350B8F47A54C14F24F17B687349D3 CF5728B0CA1735773FDDA983E8C8B0690BFC493A0CB1A8AEA728E3DDEFCAFA61 E3329A1A888AD0016510F0E24C2CC61829BCCB129FFD5D8BA0F0E52F3A3E29F7 23BF1EFDD8436015E7068211846F8B36C1586C008A01C0A046919FB0231BFC98 B7671658D779CB5D11241FA10111B09194E4EED06E53CD74AB606626C68A15AA 1F1BAE33924668534C7E773DD4ED2AB02DCB9B2C4EF51ED38ADF31ED74E5D133 B5651DB15437482A3A3908AC45B67AA45D4BD937EEC37C25DCD6842F2E0197AA 34D234B86EE8E64C285E05B8C8E23DC9E3DEC17B97FC3C533E5F59D58BE9E1EF 0DB613008FAF76E6C44C29435EC2062B4F854F67F58E50F34ED8E68A43D80740 567E09626BEBBA67FD35AF418D559F3F35E39D78EB04FD5DCDC676D747B4362E BB2F226B170FDC6F1938AD91F11565E36A753F91183F90AFE038E4CA84EEAA34 3F4AE19C29228B911E2783D80C06F259B252F1A28B990E9017A2D7595DF7FB70 3EC365F0770B85327B79ED907C7DF2C55C6F561FE6F3D042F61A5316DCF21B27 13F59A9E3F3B70BDAD7318596AF530A0EA5F8F4DF37EC1669CA0ED249C081079 BEE1E4F34D6D9AB45CCFD3A6B31CEB3737646BCC400067A79B5E5F3D104F6568 07CF3FDD8CDF0E847BFE4220074D022F7F9AF1DAFF943ABC445C46A0FB196192 B52191E64B6FABB382CDB62AEA0505CB2DF689792B8BE063588DC472039A2574 FB5D9E2C862F636D863DA934EF1B5F62CBEBBE84760E55B714C0F974D4982AD8 122B9C8DE3C9953E8E7E24B90489D803F7C340B550727B9424FD643E2EA64D7E 571F977A2DC7D1AFCADC297A4F36D5A59417725FD0A53B2C5EBF73BDAB07C791 7CB8B9EECB12759F95917ABB4C33F1528B733516EA481A9C81C2379FAEDCDB2E D679B0D3458D0C93AC093E3C8F547D4598AA12B38916E355A758DD90445B5364 6189ACCF5D95DFB0F2ADCC25FC9D2A6F4A276336AF73008020DB1285225148BC A02265C50A3DEB475ED9BCCC642990D8C78882640D31BB6EEE992B1EA31EFE2F 3AFBCAD698F61AC6EF7780AF582C662A989876074707A1B576AF35C4FACBE498 8E2CCE35A4C648143BC1255ED43EC7F8E280A6A5B647E71F7E0B3473CD5AD5CD D7DF3579F4089777975176E40C89F6252E179FAD3A21AF4C7DC0C699E4AABDB4 0B275E6932F9B5FE0C34B6C6CF53113938C620BEC81401862DCDCE5CAA61BB9A D06C29BA94B3C0A02F50301691486A62AF64C7A00D3152F0292A795502C3D443 3613F02413A05D6CE4FC7E89C47445F0AED9AB8D04CE7DC9D87A4653BF101225 2B0FBC8E25A93EFB082B0A532087DB860A256F1A88200BC1781BC2012381801E 0FC297A0F7522E92619D0A06395508F86BF98BCCF5B065B936FE01540FE0B8F3 2817B2324FEF751197E2229011805BA961B5B06AF639A5AA8C10E760DC7FF118 87D64F7B12C87506B11FB5DEA1EB3FF76ADCE8FD0850625585385B8B1BC81710 4E98280601C712BE44DDBA81A741D377FD36692487AAB52E5509172E586BD54E 40A07E555361DC64AC29A60173B9061F10071958284DEB20CFBD8F6DA5AD8E7C 4E21FAED5B0EE1017AC165354A8FADEF05F7EF24BCA6B1FC6689EA737BF98D19 A69033E1EDCB74557F78D8FDBD2A0A0620F45A0396FD106EDEA6A378B1A275FF 3C6AD0D735C425164EF0E28F7381D69E20C9EE0BE32D9B31F6AEC057EC169026 D9A8F0C26462C4B2BFC2DBEDD3F087777C32B40BE41B8F7FE9291A5E18EAE60A E1BA31FB7104E3298227E852E2B8022392450C888B4A7D075BF145EB21F69F48 A6FA9939F896FCD2611920EC1AD15E2EBD4AA224D6FB81F0B62004BADF0CAEDB 2BAB8FB1096215D9C83844D2F8ADE104A005C6876CD2205856C14748D5208627 3B9BA4E6499CB62CA7D67880BD05F94DA2E86431E14E5B8FFBD5F906710FC7E0 E2DD34F2C3042F93B6207C23DFCBEBAC8C03352C7ED77D9CEF478AB594528DD2 7678C062757F89DEA5016CD8EF19E026E1D3D968F7663F3ABB03A486B6407AB9 76BFE8E936993D4C63299C27E8B639307EEC7A44DE6497AA955118FFEE852789 683C1A05E193EDEDEB853983AE7A0BBA148F56CF127D7B93D3ED801B39839177 E57E7362F46EE8F3409D72DAEF0CCDB5C5AA7DED6D0CEC8E98F238E2864A9A74 D62D5F55F1DDC0DBD60BCF5CEE3EFAF0E29D1F882D873B448FB6E92B464D84C0 48D8F80461F531C584903326E8047D4BD1239EE6EF9FD037D85A315DD469F38E 7F661F41CFAA977FA4E15636260BB2EA0D663134A1125AEB9D158A7961C8A220 DC8C06BFD14525FB91E6DFE0AD10682E2E1A2EE68AE38AA9E9AEFE1AB2E200E1 A1E82606EC0D632F4F73C0CD27988ABD424348C21CCA9CBD5241BFBD14CCE58A 5F7A92202677B332DFD318645D2972D906AB8A0A684DE86B2D9DDA027C9AE898 0F787CD4D24E488BFAD8BC64BCBD9C5FD1D4A0DD7D307FE0C1AED5E43F3080AB 97B8AF2D42CEBA032E6153EAE8A529DDB2EAB494FFC36CCD2703A9A5A6BF7AC1 B7FAEE80176CB27008C3D7A937732ADF44586EBE18B66F6F1D5722F3354CD57F CC1B2BC1031197599F7E368E17901BD1F99E7E2CACDB070CC870AA311F34DF9E 42E851B8426CC41B242C12274C5B605F3FDA3CB6633B57DB3740085B6704301C BB26D10ACAF52D666F17FFBF116F8DCFB147784593CFF4EE579830FEE63584FF A94D42A2FF97B7E4D5FAE312001AD818332F68FABCC10C9D11E88E53D6FE7E6F 1873B6FEB92B3D2ECA6B4F808AA0B10002624DF219DDFA1EA7A2EEBB8F48A534 9D368EC29EF25266FD7F86A40FDCA817627CA58560A1328E94E3C3A50E5C8C30 C3FB61798B293A3E163DB0F68F9E73FFEA23DDC5A5E62E9DF96E16235157EF31 DAFBFF7B385C4B51301BC23E495667C4EE4480A189D57060E2F4029E623D6144 4EEE489DBF257BD97D441D8440ABE45290E5D2A0D230E58AB82702B6E0D603BE 52C826B41EB5832A03874852118D5EA2408BB587ED05BC7D1E13396FC2A2E3F5 3538635BF119E04C39EECBBB9A7EBBD89E8F0D1BF9CE9076A2EFD5D4319BE99D 2D1B63BC57FA691958E840347CFA644BA37076332DD1D404FF2AAD9786D28803 018901438B6A8B584CE6D3893113CE3A52DFCED4091B1EF75494441E2D0A31B0 7AEDB0EBCADDF475CEF0CA0257878E55E4DBD232669EFD747462A2FC13BB5EE8 541E6D85E74410D6E7936F0F3AF1906E17FA7122E20FBCBFD55BBF02CC4A71EC 1FD983A74193758104AA2ED87A4AB27C6163DD9CF91FCE7DED599FF9E825C6B3 75DD093E8492B21854CFF276CA12E827C681D9211EDB5E44D17512E9B1CD5896 A0233AF55A3CD8155A6E689F581C8B2DECDC40139942659FB9F5B011968E4955 70B3B935541D9ED629221C3E65435C2171304FC65A1366386751BAEC4D248603 97501065C724A6F97D54B7D7EF5EEBB59E970DA945A9543ABE1B01B99E62341E 90C4A569C70BBF6158FCF7897ED8386DF52382028DD6E8F1A93466E1B85D9775 F57754632925DCD35C680947FCCAF7F76F4E536B7F9C95EFB6014E344FA8B80D E72ED9DCFB771BA791754CD8193D0E7FBE24F030D30D4194FD2FC68F8E6D5A60 595D0C1A5616C9C8693DBEABBECB77AEAC6CB3BB1891829472403097A5BC7D87 C95E32D5D331569B3C16CF6ED9FF0277ABE2E3D5E2309EFB175907BBBA1A1AC9 D1AB2B95D23010D6DF6527603D14F16FD123DB2365A35FD1C704287B22754F53 BEF819ADF0F4F93F7A8F7EF1CFA002079A66BFFFFD04DC1449D3D4448F16D2A5 1ECD37E3D1E16CB34DF5A2E87714276FCBCF5EFD367FDE2893CE1534AB8D0912 289DE350A5D99FDB292E535F0B408DD2EA6C14D8D96CC64DA39722E731656804 0681744FFB9739F0EC725156DCAB8C6F5324EAA882959BC8E18734A3D368E6AE AB53484056B9376C291B927050F4D8D60027B444EAAB20B21584167D17F95335 183ED69327802526500484F6EEE91AC1957E874C58829BCCCF541D71CBDEC26F 98116E37646966E7B2AE8FCBE9181619119B24803D6D54772BF91232BFC41DF1 5D69E7DDE2B3A86CBAA15A731F8295723C3EB87B766A86755E5B2F700A3D7D75 7EA7CDD279613F9B0655C3D8F8274FF9DFE237DC79F96672116F63661BD3822F 4BF4EAD79C834D72A38E9D19CA4F8685743CD3D2A8FC98AF75D9C89FA2C01869 F4CEA9D8AE4BF859D688A2AE41D7E122AF3002846573F4969AF3C94CAC0A8A31 64084F0B110B35CBEEFC29BB6ACDC67135EC46DED6D10C580FF2E7A031731B8D 0C29A0AF366047E47291D3CD98EA501418225969FDEE77951C9945739B024D35 4C60A330556CD482EB5CC619216463C5F0AF260340340B53C996CF8B4E827796 D14E56F8174379D2B9839E956ACF318A719A3FD8C7E4BAA52A2C8EAA325876EF 2C4C2033596D03898A1345BCF4B77FD91912AA723C954BF1937E3E42152C4D1D 057EBEDA8449FEF00F7AE1CD8F4032B51ADAC1249EBEBAD47B2992BE01DAA34D BC6AA35DA7B5A83BBBC280FB78AF2E0A04569017E4160822D0E037ABD26DB499 7A93BB5CBD738223CE0C8E2309FF3A8E10CE76B7829E661347EBFDD852E8EFF4 E30E360BD697C13F82C9EC6018990B4BE30C9FBDD08E83B8C2762DBD4EA08307 8FE1B25BC1C76B77094A68994BB0343F44B7F44986218004283F39FBAC6FD50D 23D50CD24F078864572A0D6E8B2663EF0C2B63257F864A3D542F5625496F2748 B268BC2FBEEF67EA842AADAC517A4EB3EDF583B85F8DE1064D54199F484207CB 4B985636822034BCD378AC69C56099BD06D06C8FC373477D6BD9B43D87EDFCEB 603EEC79201FBC3F85A5A407B51263C262469DD56800E9623B50802A54B710F9 E20FC4F21D814F1EC94BEFA1594D2C4BED626AAB98B75EC6F60970F958C5D170 B76AC17B61AC23026AD2680989785A2D24C2AE3D70E172F4CD70C485C8C8B2E5 895C5D339ADF0B821932CEC3A0BDE9BE79178976D3848553FFCF55D15090B383 F2D083D637629040997C028497F645C1416F07B19DE6D1D9DF3DA73ECAF83625 926E9040342E33697659FF29FFA7A15B2514808576105663835F26F590025C3B E6180E4A9D9CA4AC04292D2BDFEB5944EDBC91AEB36094AD1D421C547346446C 4CC24C8A1B888A6C27D7F48E9C2D3EBD927A9850C69AD91B9E7E8ADD03112ADB 88A79C100E8131F13B0A419AC04A02622540FCBC22450F11F4254DF231135D9F E1CD058AF5D9BA9196D98EAD2B8C010941548220F2E3F733F3F7D66B0C7D3B53 DEB764DA535963532DBC064CFA1D72B17FF39A6CA5AA1B40810B1970569032A3 72A3DA1CFE48A4557E11A0127B3C2F33A92511478CFD1F59AA9DD13425A08A18 C356775A73A8C29ED79E3F473A4864D58ED38AE574BCB3828A9A86D4E23A625D B291DF34FC26E2F95FF755636E598C9F8DA4638BF3F5C75B2099697EEA8DDA99 58255F2503EB0D2E05EBCC4919807DF1DE807FC93438F63703D558DF390F7393 EA5F35F12E84BC9AC178A225B6E1F16B3EC46F1F0B185ADF178434D696A4BB81 2B7F2916949DFF456F54E90B300523F0E940033EFABE808D456EE42D8D4CB45A 90ABBC1B241F6126BF3663BCEF3D8D190C4DF7D2C308B2667DA60FE2D8B3F065 B18EA370B85FDCA7F73A389FCDE5DAA5A6C86E0726963C4A045F89011D61088E 5BC558ACA6EC2E8E21A2B251FB7D8A4CD2CAAA62BFA4226E054D0EB0FFC6EB35 5FF6211BB64F57ACB5A3D9F05317083B2D6FED245AB9D4CC708ED2F9C20F0E88 334667EB0E2B37DBB8E6B2750CCECA30481E819828135A64B83A0F74371C83C9 2F0640BCEE83D2C28CDF13694729859BC2E210C2D5D0A51EAA0AC6184BF73FA3 DC7816951B264C8EBC3CEC5A4CB339F0417D1CBF9FD605A2C80370F8AC05008E 32B2F4994EC372FE48D7FB226EB577A2FA99C47A3CB556EADAFF6022AE4E6533 BE28107F55A80D6C76A141094380E753DC09B28B77EF0581C58DE11F0BC88901 51DCCCAC37B1D5195F90FCE9CD4B0A4F490DF3F00083A1C469E32EF2FEB61B3B 0A2DF540476965619B38AA6A6B1495D830F8EAC60D3D4816739A52F89EF7AD8B 0C0C0E049F456C0843F5BC48DFF9E2179359AA0EF8D5F8E10CD6613C40F2A6ED 7690A9601336F7D1C9ADB6C19D30954F58E2E7A6746A65D05707A68309CBF43E A3938EA5843C8D75A784B61872303893D0F32E4A54110F09483856BF356FAB62 79A5650BA543F4FC59631A7BD1E5BB750EE6BC95E6A745F2EEB091B9EDB10FEA 37A953E0E05479B6AFE680D1F8948F63FBE196E4C7B87FB22BF02B31C872BA83 FA653053B258E10C75F76A4E7BA24013B4F962C279E7AA6D5A0B48EE3754478A 97C1B3A227CD0EA118E3CB6BFDDC79E7CE3516FD93E2E92203DE226301B9C2B1 13E5A3E45F2568FF7411C59F75DD40E42FA8646924513CF2F8D31824B284C1BE 691F45C1704B9310C40ECD86A806FA74807147088DA3E9B50C826EB21F950B6E F0024B76F50EE2BDD87E08A375B5A569013E322A6676F8E0E84F5822C32AA808 2B479A7B38F2000D7336657889A3D4CDB37176BC3E4F642ED0711C964B16BB84 5028C1FAB2D50D376C7A102719652C942B4F530D9573A93BEDF89401F5F1D658 56DE1FAE4EDF8B8DFD25A4A73229D35EF31DC7D3027BCA9240613BE8639D1B37 1A6011F79BB70474F691091D3690E278B3E195E18405261EE1C2AF929FFA4F2B 2605D4957FDB3CB66996432CED778DC3D7836CDA4CFA8F2D9EC4A1CC66ED0B4A 3DD09AFBF6E750CE095E2ABE308BD0E17BA62577B4526CB731464A9FD036E6A0 91711F7A8D101BA545F5526CA29E9AC7C7D30207456A5AD86B51D0FF971F190D 23DC2AA5653215BB29C3428B3CB084B56C8D463BB6BD121250A6B6C8E5DE5AC0 4C6647971C8E147EFF792A3ED9E0D6A978959D994DCF4C4DB368B599B856C426 41FD38F08568FAD2DE64F289B96BE5BCAAC265C616626D16793DDBE9404582D5 F268339486EDDEB6E7D1A4638D736E72DE6FDB0FBA426F580A89E1BF6F4B80D2 20EA7FCD818C2F6CD38F29C6D1E4277E461D05D9C012A2B5D91FA0D46E3D56F2 E84EC6EC2F3F5C8DC0323A691D957F5F4EAE73B59DE1A9C0D877BA4B3762830E 494D804E61B006A61654F288F0AE3620F1A945AADDD5CC11217FFC8345FB2841 12BE8352D02E457C54234003F15E0ED98A78F2D87F4AB1F9832EF76F9C49778B B08ABE4391A3744F9457B59461E8FC0E5A867246D03F8A827CC2154953D6C514 B82A5DEB7A4067A9E9E19E79CF0C3FA00642436E95C71A5665691439B9FF18B6 AE4F85A213EAAF878D987B6DEB3A29C382B0CC9603D3521841BE889BEB6A56C4 1DE94AD0BE27A4DE2903EF7DEE5EC362C66A6FDF166A2C53D5B5F8001EF5CB7D 3A3BE1ED04880269EFAA 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont TeXDict begin 40258431 52099146 1000 600 600 (usermanual.dvi) @start /Fa 209[28 46[{ TeX74afc74cEncoding ReEncodeFont }1 90.9091 /CMTI10 rf /Fb 209[43 46[{ TeX74afc74cEncoding ReEncodeFont }1 119.552 /CMBXTI10 rf /Fc 133[43 3[51 54 38 38 38 1[54 49 54 81 27 51 1[27 54 49 1[43 54 43 54 49 7[73 73 100 73 2[54 72 1[66 76 73 89 61 76 1[35 1[77 1[66 75 70 69 73 7[49 49 49 49 49 49 49 49 49 49 1[27 46[{ TeXf7b6d320Encoding ReEncodeFont }50 99.6264 /CMR12 rf /Fd 138[39 5[39 2[39 4[39 3[39 39 35[39 1[39 16[39 43[{ TeX09fbbfacEncoding ReEncodeFont }9 74.7198 /CMTT9 rf /Fe 193[62 1[62 16[62 43[{ TeX09fbbfacEncoding ReEncodeFont }3 119.552 /CMTT12 rf /Ff 209[24 46[{ TeX74afc74cEncoding ReEncodeFont }1 74.7198 /CMTI9 rf /Fg 133[34 41 41 55 41 43 30 30 30 41 43 38 43 64 21 41 1[21 43 38 23 34 43 34 43 38 21 12[43 6[48 4[60 3[55 1[58 1[36 1[60 3[38 38 38 38 38 38 38 38 38 38 38 21 26 2[38 29[43 45 11[{ TeXf7b6d320Encoding ReEncodeFont }49 74.7198 /CMR9 rf /Fh 206[33 49[{ TeXf7b6d320Encoding ReEncodeFont }1 58.1154 /CMR7 rf /Fi 139[27 1[28 1[39 35 39 59 20 2[20 3[31 39 31 1[35 9[72 5[55 13[51 21[24 45[{ TeXf7b6d320Encoding ReEncodeFont }16 66.4176 /CMR8 rf /Fj 150[30 30 104[{ TeXbbad153fEncoding ReEncodeFont } 2 74.7198 /CMSY9 rf /Fk 133[55 65 65 89 65 68 48 48 50 65 68 61 68 102 34 65 1[34 68 61 37 56 68 55 68 60 34 45[61 61 61 1[34 33[68 72 11[{ TeXf7b6d320Encoding ReEncodeFont }32 109.091 /CMBX12 rf /Fl 134[48 48 1[48 51 35 36 39 1[51 45 51 76 25 2[25 1[45 28 42 51 40 51 44 3[25 1[25 3[94 69 70 63 51 69 1[62 68 71 86 55 71 1[36 71 1[57 60 70 66 65 69 6[25 45 45 45 3[45 1[45 2[25 1[25 1[45 42[{ TeXf7b6d320Encoding ReEncodeFont }51 90.9091 /CMB10 rf /Fm 129[48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 1[48 48 48 48 48 48 48 48 48 48 2[48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 1[48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 1[48 1[48 48 48 33[{ TeX09fbbfacEncoding ReEncodeFont }88 90.9091 /CMTT10 rf /Fn 136[66 2[35 1[36 2[45 2[25 6[40 11[68 68 93 68 68 66 51 67 1[62 71 68 83 57 2[33 68 71 59 62 69 66 64 68 6[25 11[25 30 45[{ TeXf7b6d320Encoding ReEncodeFont } 31 90.9091 /CMSL10 rf /Fo 242[91 13[{ TeXbbad153fEncoding ReEncodeFont } 1 90.9091 /CMSY10 rf /Fp 133[72 3[85 90 63 64 66 1[90 81 90 134 45 85 1[45 90 81 49 74 90 72 90 78 8[122 167 122 1[112 90 2[110 121 126 153 97 2[60 1[127 1[106 124 117 1[122 7[81 81 81 81 81 81 81 81 81 81 48[{ TeXf7b6d320Encoding ReEncodeFont }47 143.462 /CMBX12 rf /Fq 133[60 71 71 97 71 75 52 53 55 1[75 67 75 112 37 71 1[37 75 67 1[61 75 60 75 65 37 6[102 102 139 102 103 94 75 100 101 92 101 105 128 81 105 1[50 105 106 85 88 103 97 96 102 3[105 3[67 67 67 67 67 67 67 67 67 67 67 37 45 2[67 29[75 12[{ TeXf7b6d320Encoding ReEncodeFont }64 119.552 /CMBX12 rf /Fr 131[91 45 40 48 48 66 48 51 35 36 36 48 51 45 51 76 25 48 28 25 51 45 28 40 51 40 51 45 25 2[25 1[25 56 68 68 93 68 68 66 51 67 71 62 71 68 83 57 71 1[33 68 71 59 62 69 66 64 68 1[43 1[71 1[25 25 45 45 45 45 45 45 45 45 45 45 45 25 30 25 1[45 35 35 25 1[76 1[76 1[25 18[76 51 51 53 11[{ TeXf7b6d320Encoding ReEncodeFont }85 90.9091 /CMR10 rf /Fs 166[146 6[144 2[145 2[116 152 3[152 1[127 2[138 12[97 6[54 46[{ TeXf7b6d320Encoding ReEncodeFont }10 172.154 /CMBX12 rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize end %%EndSetup %%Page: 1 1 TeXDict begin 1 0 bop 150 1317 a Fs(BERKELEY)65 b(LOGO)h(5.5)p 150 1383 3600 34 v 2648 1480 a Fr(Berk)m(eley)32 b(Logo)g(User)e(Man)m (ual)150 5068 y Fq(Brian)45 b(Harv)l(ey)p 150 5141 3600 17 v eop end %%Page: 1 2 TeXDict begin 1 1 bop 150 -116 a Fr(Chapter)30 b(1:)41 b(In)m(tro)s(duction)2592 b(1)150 299 y Fp(1)80 b(In)l(tro)t(duction) 150 641 y Fq(1.1)68 b(Ov)l(erview)275 883 y Fr(Cop)m(yrigh)m(t)727 880 y(c)702 883 y Fo(\015)30 b Fr(1993)i(b)m(y)e(the)h(Regen)m(ts)g(of) g(the)f(Univ)m(ersit)m(y)i(of)f(California)275 1016 y(This)e(program)h (is)g(free)h(soft)m(w)m(are;)h(y)m(ou)e(can)h(redistribute)f(it)g (and/or)h(mo)s(dify)e(it)i(under)e(the)h(terms)150 1125 y(of)k(the)h(GNU)f(General)h(Public)f(License)h(as)f(published)f(b)m(y) h(the)g(F)-8 b(ree)35 b(Soft)m(w)m(are)h(F)-8 b(oundation;)36 b(either)150 1235 y(v)m(ersion)31 b(2)g(of)f(the)h(License,)g(or)f (\(at)i(y)m(our)e(option\))h(an)m(y)g(later)g(v)m(ersion.)275 1367 y(This)38 b(program)h(is)h(distributed)e(in)h(the)h(hop)s(e)f (that)h(it)g(will)g(b)s(e)f(useful,)i(but)d Fn(WITHOUT)h(ANY)150 1477 y(W)-10 b(ARRANTY)13 b Fr(;)31 b(without)g(ev)m(en)h(the)f (implied)g(w)m(arran)m(t)m(y)h(of)f Fn(MER)m(CHANT)-8 b(ABILITY)32 b(or)f(FITNESS)150 1587 y(F)m(OR)f(A)g(P)-8 b(AR)g(TICULAR)30 b(PURPOSE)p Fr(.)f(See)h(the)g(GNU)g(General)h (Public)f(License)g(for)g(more)g(details.)275 1719 y(Y)-8 b(ou)39 b(should)e(ha)m(v)m(e)j(receiv)m(ed)g(a)f(cop)m(y)h(of)f(the)f (GNU)i(General)f(Public)g(License)g(along)h(with)e(this)150 1829 y(program;)i(if)d(not,)i(write)e(to)h(the)f(F)-8 b(ree)38 b(Soft)m(w)m(are)g(F)-8 b(oundation,)40 b(Inc.,)e(675)h(Mass)e (Av)m(e,)j(Cam)m(bridge,)150 1938 y(MA)31 b(02139,)i(USA.)275 2071 y(This)21 b(is)h(a)h(program)f(that)h(is)f(still)h(b)s(eing)f (written.)38 b(Man)m(y)23 b(things)f(are)g(missing,)i(including)e (adequate)150 2180 y(do)s(cumen)m(tation.)41 b(This)27 b(man)m(ual)i(assumes)e(that)i(y)m(ou)f(already)h(kno)m(w)f(ho)m(w)g (to)h(program)f(in)g(Logo,)i(and)150 2290 y(merely)h(presen)m(ts)f(the) h(details)g(of)f(this)h(new)f(implemen)m(tation.)275 2422 y(Read)g(Computer)p 914 2422 28 4 v 39 w(Science)p 1240 2422 V 41 w(Logo)p 1473 2422 V 41 w(St)m(yle,)h(V)-8 b(olume)p 2063 2422 V 41 w(1:)p 2174 2422 V 2245 2422 V 110 w(Sym)m(b)s(olic)p 2645 2422 V 41 w(Computing)p 3131 2422 V 69 w(b)m(y)29 b(Brian)h(Har-)150 2532 y(v)m(ey)43 b(\(MIT)f(Press,)i(1997\))g(for)e(a)g(tutorial)h(on)e(Logo)i (programming)f(with)f(emphasis)h(on)g(sym)m(b)s(olic)150 2641 y(computation.)275 2774 y(Here)30 b(are)h(the)g(sp)s(ecial)g (features)f(of)h(this)f(dialect)i(of)f(Logo:)390 3016 y(Source)f(\014le)h(compatible)g(among)g(Unix,)g(DOS,)f(Windo)m(ws,)h (and)e(Mac)j(platforms.)390 3235 y(Random-access)g(arra)m(ys.)390 3454 y(V)-8 b(ariable)32 b(n)m(um)m(b)s(er)d(of)h(inputs)g(to)h (user-de\014ned)e(pro)s(cedures.)390 3673 y(Mutators)i(for)f(list)h (structure)f(\(dangerous\).)390 3892 y(P)m(ause)h(on)f(error,)g(and)g (other)h(impro)m(v)m(emen)m(ts)g(to)g(error)f(handling.)390 4112 y(Commen)m(ts)h(and)e(con)m(tin)m(uation)k(lines;)d(formatting)i (is)e(preserv)m(ed)g(when)390 4221 y(pro)s(cedure)f(de\014nitions)h (are)h(sa)m(v)m(ed)g(or)g(edited.)390 4440 y(T)-8 b(errapin-st)m(yle)31 b(tok)m(enization)i(\(e.g.,)g([2)p Fm(+)p Fr(3])e(is)g(a)f(list)h(with) f(one)h(mem)m(b)s(er\))390 4550 y(but)f(LCSI-st)m(yle)g(syn)m(tax)h (\(no)g(sp)s(ecial)g(forms)f(except)h(TO\).)61 b(The)29 b(b)s(est)h(of)390 4660 y(b)s(oth)g(w)m(orlds.)390 4879 y(First-class)i(instruction)e(and)g(expression)g(templates)i(\(see)f (APPL)-8 b(Y\).)390 5098 y(Macros.)275 5230 y(F)g(eatures)38 b Fl(not)f Fr(found)e(in)i(Berk)m(eley)h(Logo)g(include)e(rob)s(otics,) j(m)m(usic,)g(GUIs,)g(animation,)g(paral-)150 5340 y(lelism,)31 b(and)f(m)m(ultimedia.)42 b(F)-8 b(or)31 b(those,)g(buy)e(a)i (commercial)h(v)m(ersion.)p eop end %%Page: 2 3 TeXDict begin 2 2 bop 150 -116 a Fr(2)2596 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fq(1.2)68 b(Getter/Setter)47 b(V)-11 b(ariable)46 b(Syn)l(tax)275 552 y Fr(Logo)31 b(distinguishes)f Fn(PR)m(OCEDURES)36 b Fr(from)30 b Fn(V)-10 b(ARIABLES)p Fr(.)30 b(A)h(pro)s(cedure)f(is)g(a)h(set)g(of)g(instruc-)150 662 y(tions)39 b(to)g(carry)f(out)h(some)g(computation;)k(a)c(v)-5 b(ariable)39 b(is)g(a)g(named)f(con)m(tainer)h(that)g(holds)f(a)h(data) 150 771 y(v)-5 b(alue)31 b(suc)m(h)f(as)h(a)f(n)m(um)m(b)s(er,)g(w)m (ord,)g(list,)h(or)f(arra)m(y)-8 b(.)275 915 y(In)34 b(traditional)i(Logo)g(syn)m(tax,)h(a)e(non-n)m(umeric)g(w)m(ord)g(t)m (yp)s(ed)f(without)h(punctuation)g(represen)m(ts)150 1025 y(a)j(request)f(to)i(in)m(v)m(ok)m(e)g(the)f(pro)s(cedure)e(named) h(b)m(y)g(that)h(w)m(ord.)62 b(A)38 b(w)m(ord)f(t)m(yp)s(ed)g(with)g(a) h(preceding)150 1134 y(quotation)32 b(mark)e(represen)m(ts)g(the)h(w)m (ord)f(itself.)41 b(F)-8 b(or)31 b(example,)h(in)e(the)g(instruction) 390 1278 y Fm(PRINT)46 b(FIRST)h("WORD)275 1422 y Fr(the)31 b(pro)s(cedures)f(named)g Fm(FIRST)g Fr(and)h Fm(PRINT)e Fr(are)j(in)m(v)m(ok)m(ed,)h(but)d(the)h(pro)s(cedure)f(named)h Fn(W)m(ORD)150 1532 y Fr(is)f(not)h(in)m(v)m(ok)m(ed;)h(the)f(w)m(ord)f Fn(W-O-R-D)36 b Fr(is)31 b(the)f(input)g(to)h(FIRST.)275 1676 y(What)d(ab)s(out)g(v)-5 b(ariables?)41 b(There)28 b(are)g(t)m(w)m(o)i(things)e(one)g(can)h(do)f(with)g(a)h(v)-5 b(ariable:)40 b(giv)m(e)30 b(it)f(a)f(v)-5 b(alue,)150 1785 y(and)35 b(\014nd)f(out)i(its)g(v)-5 b(alue.)56 b(T)-8 b(o)36 b(giv)m(e)h(a)f(v)-5 b(ariable)36 b(a)g(v)-5 b(alue,)38 b(Logo)f(pro)m(vides)e(the)h(primitiv)m(e)g(pro)s(cedure)150 1895 y Fm(MAKE)p Fr(,)25 b(whic)m(h)g(requires)g(t)m(w)m(o)i(inputs:)37 b(the)25 b(name)g(of)h(the)f(v)-5 b(ariable)26 b(and)f(the)g(new)g(v)-5 b(alue)26 b(to)g(b)s(e)e(assigned.)150 2004 y(The)37 b(\014rst)f(input,)i(the)f(name)g(of)h(the)f(v)-5 b(ariable,)40 b(is)d(just)f(a)i(w)m(ord,)h(and)d(if)h(\(as)h(is)f(almost)h(alw)m(a)m (ys)h(the)150 2114 y(case\))c(the)f(programmer)f(w)m(an)m(ts)h(to)g (assign)g(a)g(v)-5 b(alue)34 b(to)g(a)g(sp)s(eci\014c)g(v)-5 b(ariable)34 b(whose)f(name)h(is)f(kno)m(wn)150 2224 y(in)d(adv)-5 b(ance,)31 b(that)g(input)f(is)g(quoted,)h(just)f(as)g (an)m(y)h(kno)m(wn)f(sp)s(eci\014c)g(w)m(ord)g(w)m(ould)g(b)s(e:)390 2367 y Fm(MAKE)47 b("MY.VAR)e(FIRST)i("WORD)275 2511 y Fr(giv)m(es)31 b(the)g(v)-5 b(ariable)31 b(named)f Fn(MY.V)-10 b(AR)31 b Fr(the)g(v)-5 b(alue)31 b(W)f(\(the)h(\014rst)f (letter)i(of)e(W)m(ORD\).)275 2655 y(T)-8 b(o)41 b(\014nd)f(the)i(v)-5 b(alue)41 b(of)h(a)g(v)-5 b(ariable,)45 b(Logo)d(pro)m(vides)g(the)f (primitiv)m(e)h(pro)s(cedure)e Fm(THING)p Fr(,)j(whic)m(h)150 2765 y(tak)m(es)c(a)f(v)-5 b(ariable)39 b(name)e(as)h(its)g(input,)h (and)e(outputs)h(the)f(v)-5 b(alue)39 b(of)e(the)h(accessible)i(v)-5 b(ariable)38 b(with)150 2874 y(that)31 b(name.)41 b(Th)m(us)390 3018 y Fm(PRINT)46 b(THING)h("MY.VAR)275 3162 y Fr(will)25 b(prin)m(t)h(W)g(\(supp)s(osing)e(the)i Fm(MAKE)e Fr(ab)s(o)m(v)m(e)j (has)e(b)s(een)g(done\).)39 b(Since)26 b(\014nding)e(the)i(v)-5 b(alue)26 b(of)f(a)h(sp)s(e-)150 3271 y(ci\014c,)k(kno)m(wn)g(v)-5 b(ariable)30 b(name)f(is)h(suc)m(h)f(a)h(common)g(op)s(eration,)g(Logo) h(also)g(pro)m(vides)e(an)h(abbreviated)150 3381 y(notation)i(that)f (com)m(bines)g Fm(THING)d Fr(with)j(quote:)390 3525 y Fm(PRINT)46 b(:MY.VAR)275 3669 y Fr(The)26 b(colon)i(\(whic)m(h)f(Logo) h(old-timers)g(pronounce)e Fm(")p Fr(dots)p Fm(")p Fr(\))h(replaces)h Fm(THING)d Fr(and)i Fm(")f Fr(in)h(the)g(earlier)150 3778 y(v)m(ersion)k(of)f(the)h(instruction.)275 3922 y(New)m(comers)23 b(to)g(Logo)h(often)e(complain)h(ab)s(out)f(the)h (need)f(for)g(all)i(this)e(punctuation.)38 b(In)21 b(particular,)150 4032 y(Logo)34 b(programmers)e(who)g(learned)g(ab)s(out)h(dots)f(and)g (quotes)h(without)g(also)g(learning)g(ab)s(out)f Fm(THING)150 4141 y Fr(w)m(onder)e(wh)m(y)g(an)g(instruction)g(suc)m(h)g(as)390 4285 y Fm(MAKE)47 b("NEW.VAR)e(:OLD.VAR)275 4429 y Fr(uses)38 b(t)m(w)m(o)h(di\013eren)m(t)g(punctuation)g(marks)f(to)h(iden)m(tify)g (the)g(t)m(w)m(o)g(v)-5 b(ariables.)66 b(\(Ha)m(ving)40 b(read)f(the)150 4539 y(paragraphs)33 b(ab)s(o)m(v)m(e,)i(y)m(ou)f (will)f(understand)f(that)i(actually)h(b)s(oth)d(v)-5 b(ariable)34 b(names)g(are)f(quoted,)i(but)150 4648 y(the)j(pro)s (cedure)e Fm(THING)g Fr(is)h(in)m(v)m(ok)m(ed)i(to)g(\014nd)c(the)j(v) -5 b(alue)38 b(of)g Fn(OLD.V)-10 b(AR)p Fr(,)38 b(since)g(it's)g(that)g (v)-5 b(alue,)40 b(not)150 4758 y Fn(OLD.V)-10 b(AR)p Fr('s)35 b(name,)i(that)e Fm(MAKE)f Fr(needs)g(to)i(kno)m(w.)54 b(It)35 b(w)m(ouldn't)g(mak)m(e)h(sense)f(to)h(ask)f(for)f Fm(THING)g Fr(of)150 4867 y Fn(NEW.V)-10 b(AR)p Fr(,)31 b(since)g(w)m(e)g(ha)m(v)m(en't)h(giv)m(en)f Fn(NEW.V)-10 b(AR)31 b Fr(a)g(v)-5 b(alue)31 b(y)m(et.\))275 5011 y(Although)21 b(Logo's)h(punctuation)f(rules)g(mak)m(e)h(sense)f(once)h (understo)s(o)s(d,)f(they)g(do)h(form)e(a)i(barrier)e(to)150 5121 y(en)m(try)k(for)f(the)h(Logo)g(b)s(eginner.)38 b(Wh)m(y)-8 b(,)26 b(then,)f(couldn't)e(Logo)i(b)s(e)e(designed)g(so)h (that)g(an)f(unpunctuated)150 5230 y(w)m(ord)i(w)m(ould)f(represen)m(t) h(a)h(pro)s(cedure)e(if)h(there)g(is)g(a)g(pro)s(cedure)f(b)m(y)h(that) g(name,)i(or)e(a)g(v)-5 b(ariable)26 b(if)f(there)150 5340 y(is)30 b(a)h(v)-5 b(ariable)31 b(b)m(y)g(that)g(name?)40 b(Then)29 b(w)m(e)i(could)g(sa)m(y)p eop end %%Page: 3 4 TeXDict begin 3 3 bop 150 -116 a Fr(Chapter)30 b(1:)41 b(In)m(tro)s(duction)2592 b(3)390 299 y Fm(PRINT)46 b(MY.VAR)275 436 y Fr(and)25 b(Logo)j(w)m(ould)e(realize)i(that)f Fn(MY.V)-10 b(AR)27 b Fr(is)f(the)h(name)f(of)h(a)f(v)-5 b(ariable,)28 b(not)f(of)g(a)f(pro)s(cedure.)38 b(The)150 545 y(traditional)33 b(reason)e(not)h(to)g(use)f(this)g(con)m(v)m(en)m (tion)i(is)e(that)h(Logo)h(allo)m(ws)f(the)g(same)f(w)m(ord)g(to)h (name)g(a)150 655 y(pro)s(cedure)j(and)h(a)g(v)-5 b(ariable)37 b(at)g(the)f(same)h(time.)59 b(This)35 b(is)h(most)h(often)f(imp)s (ortan)m(t)h(for)f(w)m(ords)f(that)150 765 y(name)30 b(data)h(t)m(yp)s(es,)g(as)g(in)f(the)g(follo)m(wing)i(pro)s(cedure:) 390 902 y Fm(TO)47 b(PLURAL)f(:WORD)390 1011 y(OUTPUT)g(WORD)h(:WORD)f ("S)390 1121 y(END)275 1258 y Fr(Here)28 b(the)f(name)h Fn(W)m(ORD)33 b Fr(is)27 b(a)h(natural)g(c)m(hoice)h(for)e(the)h(input) e(to)j Fm(PLURAL)p Fr(,)d(since)i(it)g(describ)s(es)f(the)150 1367 y(kind)i(of)h(input)f(that)h Fm(PLURAL)e Fr(exp)s(ects.)41 b(Within)30 b(the)g(pro)s(cedure,)f(w)m(e)h(use)g Fm(WORD)e Fr(to)j(represen)m(t)f(Logo's)150 1477 y(primitiv)m(e)40 b(pro)s(cedure)e(that)h(com)m(bines)h(t)m(w)m(o)g(input)e(w)m(ords)h (to)g(form)g(a)g(new,)i(longer)f(w)m(ord;)j(w)m(e)c(use)150 1587 y Fm(:WORD)32 b Fr(to)i(represen)m(t)g(the)f(v)-5 b(ariable)35 b(con)m(taining)g(the)e(input,)h(whatev)m(er)g(actual)h(w) m(ord)e(is)g(giv)m(en)i(when)150 1696 y(PLURAL)30 b(is)h(in)m(v)m(ok)m (ed.)390 1833 y Fm(?)47 b(PRINT)g(PLURAL)f("COMPUTER)390 1943 y(COMPUTERS)275 2080 y Fr(Ho)m(w)m(ev)m(er,)e(if)39 b(a)h(Logo)h(instruction)f(includes)f(an)g(unquoted)g(w)m(ord)g(that)i (is)e Fl(not)h Fr(the)g(name)g(of)g(a)150 2189 y(pro)s(cedure,)29 b(Logo)h(could)g(lo)s(ok)g(for)g(a)f(v)-5 b(ariable)31 b(of)f(that)g(name)f(instead.)41 b(This)29 b(w)m(ould)g(allo)m(w)i(a)f Fm(")p Fr(punc-)150 2299 y(tuationless)p Fm(")40 b Fr(Logo,)i Fl(*)d(PR)m(O)m(VIDED)g(THA)-8 b(T)40 b(USERS)d(WHO)i(W)-10 b(ANT)39 b(TO)g(W)m(ORK)g(WITHOUT)150 2408 y(COLONS)44 b(F)m(OR)h(V)-10 b(ARIABLES)42 b(CHOOSE)h(V)-10 b(ARIABLE)43 b(NAMES)g(THA)-8 b(T)45 b(ARE)f(NOT)h(ALSO)150 2518 y(PR)m(OCEDURE)30 b(NAMES.)g(*)275 2655 y Fr(What)j(ab)s(out)g(assigning)g(a)g(v)-5 b(alue)34 b(to)f(a)g(v)-5 b(ariable?)49 b(Could)32 b(w)m(e)h(do)g (without)g(the)g(quotation)h(mark)150 2765 y(on)k Fm(MAKE)p Fr('s)g(\014rst)g(input?)64 b(Alas,)41 b(no.)65 b(Although)39 b(the)g(\014rst)f(input)f(to)i Fm(MAKE)f Fr(is)g Fl(usually)g Fr(a)h(constan)m(t,)150 2874 y(kno)m(wn)30 b(v)-5 b(ariable)31 b(name,)g(sometimes)g(it)g(isn't,)g(as)f(in)g(this)h(example:)390 3011 y Fm(TO)47 b(INCREMENT)e(:VAR)390 3121 y(MAKE)i(:VAR)f(\(THING)g (:VAR\)+1)g(;)i(Note:)e(it's)h(not)g("VAR)f(here!)390 3230 y(END)390 3450 y(?)h(MAKE)g("X)g(5)390 3559 y(?)g(INCREMENT)f("X) 390 3669 y(?)h(PRINT)g(:X)390 3778 y(6)275 3915 y Fr(The)33 b(pro)s(cedure)h Fm(INCREMENT)d Fr(tak)m(es)36 b(a)f(v)-5 b(ariable)35 b(name)g(as)f(its)h(input)e(and)h(c)m(hanges)h(the)g(v)-5 b(alue)35 b(of)150 4025 y(that)i(v)-5 b(ariable.)60 b(In)36 b(this)h(example)g(there)g(are)g(t)m(w)m(o)h(v)-5 b(ariables;)41 b(the)36 b(v)-5 b(ariable)38 b(whose)e(name)h(is)g Fn(V)-10 b(AR)p Fr(,)150 4134 y(and)27 b(whose)g(v)-5 b(alue)29 b(is)e(the)h(w)m(ord)f(X;)h(and)f(the)h(v)-5 b(ariable)29 b(whose)e(name)h(is)f Fn(X)37 b Fr(and)27 b(whose)h(v)-5 b(alue)28 b(c)m(hanges)150 4244 y(from)i(5)h(to)g(6.)41 b(Supp)s(ose)28 b(w)m(e)j(c)m(hanged)g(the)f(b)s(eha)m(vior)h(of)f Fm(MAKE)f Fr(so)i(that)g(it)g(to)s(ok)g(the)f(w)m(ord)g(after)h Fm(MAKE)150 4354 y Fr(as)g(the)f(name)h(of)f(the)h(v)-5 b(ariable)31 b(to)g(c)m(hange;)h(w)m(e)f(w)m(ould)f(b)s(e)f(unable)h (to)i(write)e Fm(INCREMENT)p Fr(:)390 4491 y Fm(TO)47 b(INCREMENT)e(:VAR)i(;)h(nonworking!)390 4600 y(MAKE)f(VAR)g(\(THING)f (VAR\)+1)390 4710 y(END)275 4847 y Fr(This)29 b(w)m(ould)h(assign)h(a)g (new)f(v)-5 b(alue)30 b(to)i Fn(V)-10 b(AR)p Fr(,)30 b(not)h(to)g Fn(X)p Fr(.)275 4984 y(What)d(w)m(e)h(can)f(do)g(is)g(to)g (allo)m(w)i(an)e Fl(alternativ)m(e)i Fr(to)f Fm(MAKE)p Fr(,)e(a)h Fm(")p Fr(setter)p Fm(")h Fr(pro)s(cedure)e(for)g(a)i (particular)150 5093 y(v)-5 b(ariable.)42 b(The)29 b(notation)j(will)f (b)s(e)390 5230 y Fm(?)47 b(SETFOO)g(7)390 5340 y(?)g(PRINT)g(FOO)p eop end %%Page: 4 5 TeXDict begin 4 4 bop 150 -116 a Fr(4)2596 b(BERKELEY)30 b(LOGO)g(5.5)390 299 y Fm(7)275 438 y(SETFOO)23 b Fr(is)h(a)h Fm(")p Fr(setter)h(pro)s(cedure)p Fm(")d Fr(that)i(tak)m(es)i(one)e (input)e(\(in)i(this)g(case)g(the)g(input)f(7\))i(and)e(assigns)150 548 y(its)31 b(v)-5 b(alue)31 b(to)g(the)f(v)-5 b(ariable)31 b(named)f(F)m(OO.)275 688 y(Berk)m(eley)35 b(Logo)g(allo)m(ws)g(users)e (to)i(c)m(ho)s(ose)f(either)h(the)f(traditional)h(notation,)h(in)d (whic)m(h)h(case)h(the)150 797 y(same)22 b(name)g(can)g(b)s(e)f(used)g (b)s(oth)g(for)h(a)g(pro)s(cedure)f(and)g(for)g(a)h(v)-5 b(ariable,)25 b(or)d(the)g(getter/setter)i(notation,)150 907 y(in)36 b(whic)m(h)h(v)-5 b(ariable)37 b Fn(F)m(OO)42 b Fr(is)37 b(set)g(with)f Fm(SETFOO)f Fr(and)h(examined)h(with)g Fn(F)m(OO)p Fr(,)g(but)f(the)h(same)g(name)150 1016 y(can't)31 b(b)s(e)f(used)g(for)g(pro)s(cedure)f(and)h(v)-5 b(ariable.)275 1156 y(Here)37 b(is)f(ho)m(w)h(this)f(c)m(hoice)j(is)d(allo)m(w)m(ed:) 55 b(Berk)m(eley)39 b(Logo)e(uses)f(traditional)i(notation,)i(with)c (pro-)150 1266 y(cedures)d(distinct)g(from)g(v)-5 b(ariables.)50 b(Ho)m(w)m(ev)m(er,)36 b(if)d(there)h(is)f(a)h(v)-5 b(ariable)34 b(named)e Fn(Allo)m(wGetSet)38 b Fr(whose)150 1375 y(v)-5 b(alue)28 b(is)f(TR)m(UE)h(\(whic)m(h)g(there)f(is,)i(b)m(y)e(default,) h(when)f(Logo)h(starts)g(up\),)g(then)f(if)h(a)f(Logo)i(instruction)150 1485 y(refers)24 b(to)i(a)e Fl(nonexisten)m(t)i Fr(pro)s(cedure)e(\(so) h(that)g(the)g(error)f(message)i Fm(")p Fr(I)e(don't)h(kno)m(w)f(ho)m (w)h(to)g(...)p Fm(")g Fr(w)m(ould)150 1594 y(result\),)31 b(Logo)g(tries)g(the)g(follo)m(wing)h(t)m(w)m(o)f(steps:)390 1734 y(1.)61 b(If)30 b(the)h(name)f(is)h(at)g(least)g(four)f(c)m (haracters)i(long,)f(and)f(the)g(\014rst)g(three)390 1844 y(c)m(haracters)i(are)f(the)f(letters)i(SET)d(\(upp)s(er)g(or)h (lo)m(w)m(er)i(case\),)g(and)e(if)g(the)g(name)390 1953 y(is)g(follo)m(w)m(ed)i(in)e(the)h(instruction)f(b)m(y)h(another)f(v)-5 b(alue,)31 b(and)f(if)g(the)h(name)390 2063 y(without)f(the)h(SET)e(is) i(the)f(name)h(of)f(a)h(v)-5 b(ariable)31 b(that)g(already)g(exists,)g (then)390 2172 y(Logo)g(will)g(in)m(v)m(ok)m(e)i Fm(MAKE)c Fr(with)h(its)h(\014rst)e(input)h(b)s(eing)g(the)g(name)h(without)f (the)390 2282 y(SET,)g(and)f(its)i(second)g(input)e(b)s(eing)h(the)g (follo)m(wing)i(v)-5 b(alue.)390 2501 y(2.)61 b(If)30 b(step)h(1's)g(conditions)f(are)h(not)g(met,)g(but)e(the)i(name)f(is) 390 2611 y(the)h(name)f(of)h(an)f(accessible)i(v)-5 b(ariable,)31 b(then)f(Logo)i(will)f(in)m(v)m(ok)m(e)390 2720 y Fm(THING)e Fr(with)h(that)h(name)f(as)h(input,)f(to)h(\014nd)e(the)h(v)-5 b(ariable's)31 b(v)-5 b(alue.)275 2860 y(Step)30 b(1)g(requires)g(that) h(the)g(v)-5 b(ariable)31 b(already)g(exist)g(so)g(that)g(missp)s (ellings)f(of)g(names)g(of)h(SETxxx)150 2969 y(primitiv)m(es)26 b(\(e.g.,)i Fm(SETHEADING)p Fr(\))22 b(will)k(still)g(b)s(e)e(caugh)m (t,)k(instead)d(of)g(silen)m(tly)h(creating)h(a)e(new)g(v)-5 b(ariable.)150 3079 y(The)30 b(command)g Fm(GLOBAL)f Fr(can)h(b)s(e)g(used)g(to)h(create)h(a)e(v)-5 b(ariable)32 b(without)e(giving)h(it)g(a)g(v)-5 b(alue.)275 3219 y(One)34 b(\014nal)i(p)s(oin)m(t:)50 b(The)35 b Fm(TO)g Fr(command)g(in)g(Logo)i (has)e(alw)m(a)m(ys)i(b)s(een)e(a)g(sp)s(ecial)h(case;)k(the)35 b(rest)h(of)150 3328 y(the)31 b(line)g(starting)h(with)f(TO)f(is)h(not) g(ev)-5 b(aluated)32 b(as)f(ordinary)f(Logo)i(expressions)f(are.)42 b(In)30 b(particular,)150 3438 y(the)37 b(colons)g(used)f(to)h(mark)g (the)f(names)h(of)g(inputs)e(to)i(the)g(pro)s(cedure)f(do)g(not)h (cause)g Fm(THING)e Fr(to)j(b)s(e)150 3547 y(in)m(v)m(ok)m(ed.)60 b(They)36 b(are)g(merely)h(mnemonic)f(aids,)i(reminding)e(the)g(Logo)i (user)d(that)i(these)g(w)m(ords)f(are)150 3657 y(names)g(of)g(v)-5 b(ariables.)57 b(\(Arguably)-8 b(,)38 b(this)e(nonstan)m(tard)g(b)s (eha)m(vior)f(of)h(TO)f(adds)g(to)i(Logo)g(b)s(eginners')150 3767 y(confusion)e(ab)s(out)h(colons.\))58 b(T)-8 b(o)37 b(a)f(programmer)f(using)h(colonless)h(v)-5 b(ariable)36 b(references,)i(the)e(colons)150 3876 y(in)29 b(the)g(TO)f(line)h(are)h (unnecessary)e(and)g(meaningless.)41 b(Berk)m(eley)31 b(Logo)f(therefore)f(mak)m(es)h(the)f(colons)150 3986 y(optional:)390 4125 y Fm(TO)47 b(FOO)g(:IN1)g(:IN2)275 4265 y Fr(and)390 4404 y Fm(TO)g(FOO)g(IN1)g(IN2)275 4544 y Fr(are)30 b(b)s(oth)g(allo)m(w)m(ed.)150 4814 y Fq(1.3)68 b(En)l(tering)46 b(and)f(Lea)l(ving)h(Logo)275 5063 y Fr(The)29 b(pro)s(cess)h(to)h(start)g(Logo)h(dep)s(ends)c(on)j (y)m(our)f(op)s(erating)h(system:)150 5230 y(`)p Fm(Unix:)p Fr(')190 b(T)m(yp)s(e)26 b(the)h(w)m(ord)g Fm(logo)e Fr(to)j(the)f(shell.)40 b(\(The)27 b(directory)g(in)f(whic)m(h)h(y)m (ou'v)m(e)h(installed)g(Logo)630 5340 y(m)m(ust)i(b)s(e)g(in)g(y)m(our) g(path.\))p eop end %%Page: 5 6 TeXDict begin 5 5 bop 150 -116 a Fr(Chapter)30 b(1:)41 b(In)m(tro)s(duction)2592 b(5)150 299 y(`)p Fm(DOS:)p Fr(')238 b(Change)22 b(directories)h(to)g(the)f(one)h(con)m(taining)g (Logo)g(\(probably)f Fn(C:)p Fm(\\)p Fn(UCBLOGO)5 b Fr(\).)22 b(Then)630 408 y(t)m(yp)s(e)31 b Fm(UCBLOGO)d Fr(for)i(the)h(large)g (memory)f(v)m(ersion,)h(or)g Fm(BL)f Fr(for)g(the)g(640K)i(v)m(ersion.) 150 564 y(`)p Fm(Mac:)p Fr(')238 b(Double-clic)m(k)33 b(on)d(the)h(LOGO)f(icon)h(within)e(the)i Fm(")p Fr(UCB)f(Logo)p Fm(")h Fr(folder.)150 719 y(`)p Fm(Windows:)p Fr(')630 829 y(Double-clic)m(k)i(on)d(the)h(UCBWLOGO)f(icon)h(in)f(the)h (UCBLOGO)f(folder.)275 984 y(T)-8 b(o)30 b(lea)m(v)m(e)j(Logo,)f(en)m (ter)f(the)f(command)h Fm(bye)p Fr(.)275 1116 y(After)21 b(initialization,)26 b(Logo)21 b(lo)s(oks)h(for)e(a)i(\014le)e(in)h (the)g(curren)m(t)g(w)m(orking)g(directory)g(named)f(startup.lg)150 1226 y(and,)45 b(if)d(one)g(is)g(found,)i(executes)f(the)g(Logo)g (instructions)f(in)g(it.)76 b(Then,)44 b(under)d(Unix,)k(DOS,)d(or)150 1335 y(Windo)m(ws,)35 b(if)f(y)m(ou)g(include)f(one)h(or)g(more)g (\014lenames)g(on)g(the)g(command)f(line)h(when)f(starting)i(Logo,)150 1445 y(those)24 b(\014les)f(will)g(b)s(e)g(loaded)g(b)s(efore)g(the)g (in)m(terpreter)h(starts)f(reading)h(commands)e(from)h(y)m(our)g (terminal.)150 1555 y(If)30 b(y)m(ou)h(load)g(a)g(\014le)f(that)h (executes)h(some)f(program)f(that)h(includes)f(a)h Fm(BYE)f Fr(command,)g(Logo)i(will)e(run)150 1664 y(that)d(program)f(and)g (exit.)41 b(Y)-8 b(ou)27 b(can)g(therefore)g(write)g(standalone)g (programs)f(in)g(Logo)i(and)e(run)f(them)150 1774 y(with)f(shell/batc)m (h)h(scripts.)38 b(T)-8 b(o)25 b(supp)s(ort)d(this)i(tec)m(hnique,)i (Logo)f(do)s(es)f(not)g(prin)m(t)g(its)g(usual)f(w)m(elcoming)150 1883 y(and)30 b(parting)g(messages)i(if)e(y)m(ou)h(giv)m(e)g(\014le)g (argumen)m(ts)g(to)g(the)f(logo)i(command.)275 2016 y(If)26 b(y)m(ou)h(t)m(yp)s(e)g(y)m(our)g(in)m(terrupt)g(c)m(haracter)h(\(see)g (table)g(b)s(elo)m(w\))g(Logo)g(will)f(stop)g(what)g(it's)g(doing)h (and)150 2125 y(return)33 b(to)i(top-lev)m(el,)i(as)d(if)g(y)m(ou)g (did)f Fm(THROW)47 b("TOPLEVEL)m Fr(.)52 b(If)33 b(y)m(ou)h(t)m(yp)s(e) g(y)m(our)g(quit)g(c)m(haracter)i(Logo)150 2235 y(will)31 b(pause)f(as)g(if)h(y)m(ou)f(did)g(P)-8 b(A)m(USE.)1154 2367 y Fm(Unix)524 b(DOS/Windows)474 b(Mac)390 2587 y(toplevel)189 b(usually)46 b(ctrl-C)332 b(ctrl-Q)285 b(command-.)45 b(\(period\))390 2806 y(pause)333 b(usually)46 b(ctrl-\\)332 b(ctrl-W)285 b(command-,)45 b(\(comma\))275 2938 y Fr(If)40 b(y)m(ou)i(ha)m(v)m(e)h(an)e(en)m(vironmen)m(t)h(v)-5 b(ariable)42 b(called)h Fn(LOGOLIB)j Fr(whose)41 b(v)-5 b(alue)42 b(is)f(the)h(name)f(of)h(a)150 3048 y(directory)-8 b(,)42 b(then)d(Logo)g(will)h(use)e(that)h(directory)h(instead)f(of)g (the)g(default)g(library)-8 b(.)66 b(If)38 b(y)m(ou)h(in)m(v)m(ok)m(e) 150 3157 y(a)d(pro)s(cedure)f(that)h(has)g(not)g(b)s(een)f(de\014ned,)h (Logo)h(\014rst)e(lo)s(oks)h(for)f(a)i(\014le)e(in)h(the)g(curren)m(t)f (directory)150 3267 y(named)30 b(pro)s(c.lg)g(where)g Fm(proc)f Fr(is)h(the)g(pro)s(cedure)f(name)h(in)g(lo)m(w)m(er)h(case)g (letters.)42 b(If)30 b(suc)m(h)f(a)i(\014le)f(exists,)150 3377 y(Logo)35 b(loads)g(that)f(\014le.)52 b(If)34 b(the)g(missing)g (pro)s(cedure)f(is)h(still)h(unde\014ned,)e(or)h(if)g(there)h(is)f(no)g (suc)m(h)g(\014le,)150 3486 y(Logo)26 b(then)f(lo)s(oks)g(in)g(the)g (library)g(directory)h(for)f(a)g(\014le)g(named)g(pro)s(c)f(\(no)i Fm(.lg)p Fr(\))e(and,)i(if)f(it)g(exists,)i(loads)150 3596 y(it.)40 b(If)27 b(neither)g(\014le)g(con)m(tains)h(a)g (de\014nition)f(for)g(the)g(pro)s(cedure,)g(then)g(Logo)h(signals)g(an) f(error.)39 b(Sev)m(eral)150 3705 y(pro)s(cedures)32 b(that)h(are)h(primitiv)m(e)f(in)g(most)g(v)m(ersions)h(of)f(Logo)h (are)f(included)g(in)f(the)h(default)h(library)-8 b(,)150 3815 y(so)32 b(if)h(y)m(ou)f(use)g(a)h(di\013eren)m(t)g(library)e(y)m (ou)i(ma)m(y)g(w)m(an)m(t)g(to)g(include)f(some)h(or)f(all)h(of)f(the)h (default)f(library)150 3924 y(in)e(it.)150 4176 y Fq(1.4)68 b(T)-11 b(ok)l(enization)275 4418 y Fr(Names)33 b(of)h(pro)s(cedures,)e (v)-5 b(ariables,)35 b(and)e(prop)s(ert)m(y)f(lists)i(are)f (case-insensitiv)m(e.)52 b(So)33 b(are)g(the)g(sp)s(e-)150 4527 y(cial)j(w)m(ords)e(END,)i(TR)m(UE,)f(and)f(F)-10 b(ALSE.)35 b(Case)g(of)g(letters)h(is)f(preserv)m(ed)f(in)h(ev)m (erything)g(y)m(ou)h(t)m(yp)s(e,)150 4637 y(ho)m(w)m(ev)m(er.)275 4769 y(Within)d(square)f(brac)m(k)m(ets,)k(w)m(ords)c(are)h(delimited)h (only)f(b)m(y)g(spaces)g(and)f(square)h(brac)m(k)m(ets.)50 b([2)p Fm(+)p Fr(3])150 4879 y(is)33 b(a)g(list)h(con)m(taining)g(one)g (w)m(ord.)48 b(Note,)35 b(ho)m(w)m(ev)m(er,)g(that)f(the)f(Logo)h (primitiv)m(es)f(that)h(in)m(terpret)f(suc)m(h)150 4988 y(a)i(list)g(as)f(a)h(Logo)g(instruction)f(or)h(expression)f(\(R)m(UN,) h(IF,)g(etc.\))54 b(reparse)34 b(the)g(list)h(as)g(if)f(it)h(had)f(not) 150 5098 y(b)s(een)c(t)m(yp)s(ed)g(inside)g(brac)m(k)m(ets.)275 5230 y(After)c(a)h(quotation)g(mark)f(outside)h(square)f(brac)m(k)m (ets,)j(a)d(w)m(ord)g(is)h(delimited)g(b)m(y)f(a)h(space,)h(a)e(square) 150 5340 y(brac)m(k)m(et,)32 b(or)f(a)f(paren)m(thesis.)p eop end %%Page: 6 7 TeXDict begin 6 6 bop 150 -116 a Fr(6)2596 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(A)37 b(w)m(ord)h(not)g(after)g(a)g(quotation)h (mark)e(or)h(inside)g(square)f(brac)m(k)m(ets)i(is)f(delimited)g(b)m(y) g(a)g(space,)150 408 y(a)f(brac)m(k)m(et,)i(a)e(paren)m(thesis,)h(or)e (an)g(in\014x)g(op)s(erator)g Fm(+-*/=<>)n Fr(.)58 b(Note)38 b(that)f(w)m(ords)e(follo)m(wing)j(colons)150 518 y(are)h(in)g(this)g (category)-8 b(.)69 b(Note)40 b(that)g(quote)f(and)f(colon)i(are)g(not) f(delimiters.)67 b(Eac)m(h)40 b(in\014x)e(op)s(erator)150 628 y(c)m(haracter)i(is)f(a)f(w)m(ord)h(in)f(itself,)j(except)f(that)f (the)f(t)m(w)m(o-c)m(haracter)k(sequences)d Fm(<=)f(>=)g Fr(and)g Fm(<>)f Fr(\(the)150 737 y(latter)32 b(meaning)e(not-equal\))i (with)e(no)h(in)m(terv)m(ening)g(space)g(are)g(recognized)g(as)g(a)g (single)g(w)m(ord.)275 878 y(A)e(w)m(ord)g(consisting)h(of)g(a)g (question)g(mark)f(follo)m(w)m(ed)i(b)m(y)e(a)h(n)m(um)m(b)s(er)e (\(e.g.,)k(?37\),)f(when)d(runparsed)150 988 y(\(i.e.,)k(where)e(a)h (pro)s(cedure)e(name)h(is)h(exp)s(ected\),)g(is)g(treated)g(as)g(if)f (it)h(w)m(ere)g(the)f(sequence)390 1129 y Fm(\()47 b(?)h(37)f(\))275 1270 y Fr(making)42 b(the)g(n)m(um)m(b)s(er)f(an)h(input)f(to)h(the)h (?)75 b(pro)s(cedure.)f(\(See)43 b(the)f(discussion)f(of)h(templates,) 150 1379 y(b)s(elo)m(w.\))74 b(This)40 b(sp)s(ecial)i(treatmen)m(t)h (do)s(es)e(not)g(apply)g(to)h(w)m(ords)f(read)g(as)g(data,)k(to)d(w)m (ords)f(with)g(a)150 1489 y(non-n)m(um)m(b)s(er)29 b(follo)m(wing)j (the)e(question)h(mark,)f(or)h(if)f(the)g(question)h(mark)f(is)h(bac)m (kslashed.)275 1630 y(A)22 b(line)h(\(an)g(instruction)f(line)h(or)f (one)h(read)g(b)m(y)f(READLIST)f(or)i(READ)m(W)m(ORD\))i(can)d(b)s(e)g (con)m(tin)m(ued)150 1739 y(on)m(to)33 b(the)g(follo)m(wing)g(line)g (if)f(its)g(last)h(c)m(haracter)h(is)e(a)h(tilde)f(\()p Fm(~)p Fr(\).)47 b(READ)m(W)m(ORD)34 b(preserv)m(es)e(the)g(tilde)150 1849 y(and)e(the)g(newline;)h(READLIST)e(do)s(es)h(not.)275 1990 y(Lines)g(read)g(with)g(READRA)-10 b(WLINE)31 b(are)g(nev)m(er)f (con)m(tin)m(ued.)275 2131 y(An)25 b(instruction)g(line)h(or)g(a)f (line)h(read)g(b)m(y)f(READLIST)g(\(but)g(not)h(b)m(y)f(READ)m(W)m (ORD\))j(is)d(automat-)150 2240 y(ically)33 b(con)m(tin)m(ued)f(to)g (the)g(next)g(line,)g(as)g(if)f(ended)g(with)g(a)h(tilde,)g(if)g(there) f(are)h(unmatc)m(hed)f(brac)m(k)m(ets,)150 2350 y(paren)m(theses,)43 b(braces,)g(or)c(v)m(ertical)j(bars)e(p)s(ending.)68 b(Ho)m(w)m(ev)m(er,)44 b(it's)d(an)f(error)f(if)h(the)g(con)m(tin)m (uation)150 2459 y(line)35 b(con)m(tains)g(only)g(the)f(w)m(ord)g(END;) h(this)f(is)h(to)g(prev)m(en)m(t)g(runa)m(w)m(a)m(y)g(pro)s(cedure)e (de\014nitions.)52 b(Lines)150 2569 y(explicitly)32 b(con)m(tin)m(ued)f (with)f(a)h(tilde)g(a)m(v)m(oid)h(this)e(restriction.)275 2710 y(If)35 b(a)h(line)g(b)s(eing)f(t)m(yp)s(ed)g(in)m(teractiv)m(ely) k(on)c(the)h(k)m(eyb)s(oard)g(is)f(con)m(tin)m(ued,)j(either)e(with)g (a)g(tilde)g(or)150 2819 y(automatically)-8 b(,)34 b(Logo)d(will)g (displa)m(y)g(a)f(tilde)i(as)e(a)h(prompt)e(c)m(haracter)j(for)e(the)h (con)m(tin)m(uation)h(line.)275 2960 y(A)f(semicolon)h(b)s(egins)e(a)h (commen)m(t)h(in)f(an)g(instruction)g(line.)42 b(Logo)33 b(ignores)e(c)m(haracters)h(from)f(the)150 3070 y(semicolon)h(to)g(the) f(end)f(of)h(the)g(line.)43 b(A)30 b(tilde)i(as)f(the)g(last)h(c)m (haracter)g(still)g(indicates)g(a)f(con)m(tin)m(uation)150 3180 y(line,)g(but)f(not)g(a)h(con)m(tin)m(uation)h(of)f(the)f(commen)m (t.)42 b(F)-8 b(or)31 b(example,)h(t)m(yping)e(the)h(instruction)390 3320 y Fm(print)46 b("abc;comment)f(~)390 3430 y(def)275 3571 y Fr(will)c(prin)m(t)g(the)h(w)m(ord)f(ab)s(cdef.)74 b(Semicolon)42 b(has)f(no)h(sp)s(ecial)g(meaning)g(in)f(data)h(lines)g (read)f(b)m(y)150 3680 y(READ)m(W)m(ORD)29 b(or)f(READLIST,)f(but)g (suc)m(h)h(a)g(line)g(can)g(later)g(b)s(e)f(reparsed)g(using)g(R)m(UNP) -8 b(ARSE)29 b(and)150 3790 y(then)h(commen)m(ts)h(will)g(b)s(e)f (recognized.)275 3931 y(The)h(t)m(w)m(o-c)m(haracter)36 b(sequence)d(#!)46 b(at)33 b(the)g(b)s(eginning)f(of)g(a)h(line)g(also) g(starts)g(a)f(commen)m(t.)48 b(Unix)150 4041 y(users)30 b(can)g(therefore)h(write)g(a)f(\014le)h(con)m(taining)h(Logo)f (commands,)f(starting)i(with)e(the)g(line)390 4181 y Fm(#!)47 b(/usr/local/bin/logo)275 4322 y Fr(\(or)26 b(wherev)m(er)f(y)m(our)h(Logo)h(executable)g(liv)m(es\))g(and)e(the)h (\014le)g(will)g(b)s(e)f(executable)i(directly)g(from)e(the)150 4432 y(shell.)275 4573 y(T)-8 b(o)36 b(include)g(an)h(otherwise)f (delimiting)i(c)m(haracter)g(\(including)e(semicolon)i(or)e(tilde\))h (in)f(a)h(w)m(ord,)150 4682 y(precede)d(it)h(with)e(bac)m(kslash)i(\()p Fm(\\)p Fr(\).)52 b(If)33 b(the)h(last)h(c)m(haracter)h(of)e(a)g(line)g (is)g(a)h(bac)m(kslash,)g(then)f(the)g(new-)150 4792 y(line)40 b(c)m(haracter)i(follo)m(wing)f(the)f(bac)m(kslash)g(will)g (b)s(e)g(part)f(of)h(the)g(last)h(w)m(ord)e(on)h(the)g(line,)j(and)c (the)150 4902 y(line)h(con)m(tin)m(ues)g(on)m(to)h(the)e(follo)m(wing)i (line.)68 b(T)-8 b(o)40 b(include)f(a)h(bac)m(kslash)g(in)f(a)g(w)m (ord,)j(use)d Fm(\\\\)p Fr(.)67 b(If)39 b(the)150 5011 y(com)m(bination)34 b(bac)m(kslash-newline)f(is)g(en)m(tered)g(at)g (the)g(terminal,)h(Logo)f(will)g(issue)g(a)g(bac)m(kslash)g(as)g(a)150 5121 y(prompt)22 b(c)m(haracter)i(for)e(the)g(con)m(tin)m(uation)j (line.)38 b(All)23 b(of)g(this)f(applies)h(to)g(data)g(lines)g(read)f (with)g(READ-)150 5230 y(W)m(ORD)34 b(or)f(READLIST)f(as)h(w)m(ell)h (as)f(to)g(instruction)g(lines.)49 b(A)33 b(c)m(haracter)h(en)m(tered)g (with)e(bac)m(kslash)150 5340 y(is)43 b(EQUALP)g(to)h(the)f(same)g(c)m (haracter)i(without)e(the)g(bac)m(kslash,)48 b(but)42 b(can)h(b)s(e)g(distinguished)f(b)m(y)p eop end %%Page: 7 8 TeXDict begin 7 7 bop 150 -116 a Fr(Chapter)30 b(1:)41 b(In)m(tro)s(duction)2592 b(7)150 299 y(the)42 b(BA)m(CKSLASHEDP)f (predicate.)75 b(\(Ho)m(w)m(ev)m(er,)47 b(BA)m(CKSLASHEDP)42 b(recognizes)h(bac)m(kslashed-)150 408 y(ness)35 b(only)h(on)g(c)m (haracters)h(for)e(whic)m(h)h(it)g(is)g(necessary:)51 b(whitespace,)38 b(paren)m(theses,)g(brac)m(k)m(ets,)h(in\014x)150 518 y(op)s(erators,)31 b(bac)m(kslash,)g(v)m(ertical)i(bar,)d(tilde,)h (quote,)g(question)g(mark,)f(colon,)i(and)e(semicolon.\))275 653 y(A)36 b(line)g(read)g(with)f(READRA)-10 b(WLINE)37 b(has)e(no)h(sp)s(ecial)h(quoting)f(mec)m(hanism;)j(b)s(oth)c(bac)m (kslash)150 762 y(and)30 b(v)m(ertical)i(bar)e(\(describ)s(ed)g(b)s (elo)m(w\))h(are)f(just)g(ordinary)g(c)m(haracters.)275 897 y(An)d(alternativ)m(e)j(notation)f(to)g(include)e(otherwise)i (delimiting)f(c)m(haracters)i(in)d(w)m(ords)g(is)h(to)h(enclose)150 1006 y(a)35 b(group)f(of)h(c)m(haracters)h(in)e(v)m(ertical)j(bars.)52 b(All)35 b(c)m(haracters)h(b)s(et)m(w)m(een)g(v)m(ertical)g(bars)e(are) h(treated)h(as)150 1116 y(if)30 b(they)h(w)m(ere)g(letters.)41 b(In)30 b(data)h(read)f(with)g(READ)m(W)m(ORD)i(the)f(v)m(ertical)h (bars)e(are)h(preserv)m(ed)f(in)g(the)150 1225 y(resulting)e(w)m(ord.) 40 b(In)28 b(data)h(read)f(with)g(READLIST)f(\(or)i(resulting)g(from)e (a)i(P)-8 b(ARSE)28 b(or)g(R)m(UNP)-8 b(ARSE)150 1335 y(of)35 b(a)g(w)m(ord\))g(the)g(v)m(ertical)i(bars)d(do)h(not)g(app)s (ear)f(explicitly;)39 b(all)c(p)s(oten)m(tially)i(delimiting)e(c)m (haracters)150 1445 y(\(including)24 b(spaces,)i(brac)m(k)m(ets,)h (paren)m(theses,)e(and)f(in\014x)f(op)s(erators\))h(app)s(ear)g(as)g (though)g(en)m(tered)g(with)150 1554 y(a)g(bac)m(kslash.)39 b(Within)23 b(v)m(ertical)j(bars,)e(bac)m(kslash)g(ma)m(y)g(still)g(b)s (e)f(used;)i(the)f(only)f(c)m(haracters)i(that)f(m)m(ust)150 1664 y(b)s(e)30 b(bac)m(kslashed)h(in)f(this)g(con)m(text)i(are)f(bac)m (kslash)g(and)f(v)m(ertical)i(bar)e(themselv)m(es.)275 1798 y(Characters)41 b(en)m(tered)h(b)s(et)m(w)m(een)f(v)m(ertical)j (bars)c(are)i(forev)m(er)f(sp)s(ecial,)k(ev)m(en)d(if)f(the)g(w)m(ord)g (or)g(list)150 1908 y(con)m(taining)d(them)e(is)h(later)g(reparsed)f (with)g(P)-8 b(ARSE)36 b(or)h(R)m(UNP)-8 b(ARSE.)37 b(Characters)f(t)m (yp)s(ed)h(after)g(a)150 2017 y(bac)m(kslash)30 b(are)g(treated)g (somewhat)f(di\013eren)m(tly:)41 b(When)29 b(a)h(quoted)f(w)m(ord)g (con)m(taining)i(a)e(bac)m(kslashed)150 2127 y(c)m(haracter)c(is)f (runparsed,)f(the)g(bac)m(kslashed)i(c)m(haracter)g(loses)f(its)g(sp)s (ecial)g(qualit)m(y)h(and)e(acts)h(thereafter)150 2237 y(as)f(if)g(t)m(yp)s(ed)g(normally)-8 b(.)39 b(This)22 b(distinction)i(is)f(imp)s(ortan)m(t)g(only)g(if)g(y)m(ou)h(are)f (building)g(a)g(Logo)h(expression)150 2346 y(out)31 b(of)f(parts,)g(to) i(b)s(e)d(R)m(UN)i(later,)h(and)e(w)m(an)m(t)h(to)g(use)f(paren)m (theses.)41 b(F)-8 b(or)31 b(example,)390 2481 y Fm(PRINT)46 b(RUN)h(\(SE)g("\\\()g(2)h("+)f(3)g("\\\)\))275 2615 y Fr(will)30 b(prin)m(t)g(5,)h(but)390 2750 y Fm(RUN)47 b(\(SE)g("MAKE)f(""|\(|)h(2\))275 2884 y Fr(will)d(create)j(a)e(v)-5 b(ariable)45 b(whose)f(name)h(is)f(op)s(en-paren)m(thesis.)84 b(\(Eac)m(h)45 b(example)g(w)m(ould)g(fail)g(if)150 2994 y(v)m(ertical)32 b(bars)e(and)g(bac)m(kslashes)h(w)m(ere)g(in)m(terc)m (hanged.\))p eop end %%Page: 8 9 TeXDict begin 8 8 bop 150 -116 a Fr(8)2596 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 9 10 TeXDict begin 9 9 bop 150 -116 a Fr(Chapter)30 b(2:)41 b(Data)32 b(Structure)d(Primitiv)m(es)2055 b(9)150 299 y Fp(2)80 b(Data)55 b(Structure)c(Primitiv)l(es)150 767 y Fq(2.1)68 b(Constructors)150 1150 y Fk(w)m(ord)390 1369 y Fm(WORD)47 b(word1)f(word2)390 1478 y(\(WORD)g(word1)h(word2)f (word3)g(...\))275 1637 y Fr(outputs)29 b(a)i(w)m(ord)f(formed)g(b)m(y) g(concatenating)j(its)e(inputs.)150 1911 y Fk(list)390 2130 y Fm(LIST)47 b(thing1)f(thing2)390 2240 y(\(LIST)g(thing1)g (thing2)h(thing3)f(...\))275 2399 y Fr(outputs)30 b(a)i(list)g(whose)f (mem)m(b)s(ers)f(are)i(its)f(inputs,)g(whic)m(h)g(can)g(b)s(e)g(an)m(y) g(Logo)i(datum)d(\(w)m(ord,)i(list,)150 2508 y(or)e(arra)m(y\).)150 2782 y Fk(sen)m(tence)390 3001 y Fm(SENTENCE)46 b(thing1)g(thing2)390 3110 y(SE)h(thing1)f(thing2)390 3220 y(\(SENTENCE)f(thing1)h(thing2)g (thing3)h(...\))390 3330 y(\(SE)g(thing1)f(thing2)g(thing3)g(...\))275 3489 y Fr(outputs)25 b(a)h(list)h(whose)f(mem)m(b)s(ers)f(are)h(its)g (inputs,)g(if)g(those)h(inputs)e(are)h(not)g(lists,)i(or)e(the)g(mem)m (b)s(ers)150 3598 y(of)31 b(its)f(inputs,)g(if)g(those)h(inputs)e(are)i (lists.)150 3872 y Fk(fput)390 4091 y Fm(FPUT)47 b(thing)f(list)275 4250 y Fr(outputs)34 b(a)g(list)i(equal)f(to)g(its)g(second)f(input)g (with)g(one)h(extra)g(mem)m(b)s(er,)g(the)g(\014rst)f(input,)g(at)i (the)150 4360 y(b)s(eginning.)56 b(If)36 b(the)g(second)g(input)f(is)g (a)i(w)m(ord,)g(then)e(the)h(\014rst)f(input)g(m)m(ust)h(b)s(e)f(a)h (one-letter)i(w)m(ord,)150 4469 y(and)30 b(FPUT)g(is)h(equiv)-5 b(alen)m(t)31 b(to)g(W)m(ORD.)150 4743 y Fk(lput)390 4962 y Fm(LPUT)47 b(thing)f(list)275 5121 y Fr(outputs)34 b(a)g(list)i(equal)f(to)g(its)g(second)f(input)g(with)g(one)h(extra)g (mem)m(b)s(er,)g(the)g(\014rst)f(input,)g(at)i(the)150 5230 y(end.)66 b(If)38 b(the)i(second)f(input)f(is)h(a)g(w)m(ord,)i (then)e(the)g(\014rst)f(input)g(m)m(ust)h(b)s(e)f(a)i(one-letter)h(w)m (ord,)g(and)150 5340 y(LPUT)30 b(is)g(equiv)-5 b(alen)m(t)32 b(to)f(W)m(ORD)g(with)g(its)f(inputs)g(in)g(the)g(other)h(order.)p eop end %%Page: 10 11 TeXDict begin 10 10 bop 150 -116 a Fr(10)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(arra)m(y)390 518 y Fm(ARRAY)46 b(size)390 628 y(\(ARRAY)g(size)h(origin\))275 756 y Fr(outputs)32 b(an)h(arra)m(y)g(of)g Fm(size)f Fr(mem)m(b)s(ers)g(\(m)m (ust)h(b)s(e)g(a)g(p)s(ositiv)m(e)h(in)m(teger\),)i(eac)m(h)e(of)f (whic)m(h)f(initially)150 866 y(is)d(an)g(empt)m(y)g(list.)41 b(Arra)m(y)29 b(mem)m(b)s(ers)f(can)h(b)s(e)f(selected)j(with)d(ITEM)h (and)f(c)m(hanged)h(with)g(SETITEM.)150 976 y(The)36 b(\014rst)g(mem)m(b)s(er)g(of)g(the)h(arra)m(y)g(is)f(mem)m(b)s(er)g(n) m(um)m(b)s(er)f(1)i(unless)f(an)g Fm(origin)f Fr(input)h(\(m)m(ust)g(b) s(e)g(an)150 1085 y(in)m(teger\))c(is)e(giv)m(en,)h(in)e(whic)m(h)h (case)h(the)f(\014rst)f(mem)m(b)s(er)g(of)h(the)h(arra)m(y)f(has)g (that)g(n)m(um)m(b)s(er)f(as)h(its)g(index.)150 1195 y(\(T)m(ypically)35 b(0)e(is)g(used)f(as)i(the)f(origin)g(if)g(an)m (ything.\))50 b(Arra)m(ys)33 b(are)g(prin)m(ted)g(b)m(y)g(PRINT)f(and)h (friends,)150 1304 y(and)d(can)g(b)s(e)g(t)m(yp)s(ed)g(in,)h(inside)f (curly)g(braces;)g(indicate)i(an)e(origin)h(with)f Fm({a)47 b(b)h(c}@0)o Fr(.)275 1433 y(See)30 b([ITEM],)h(page)g(12)g(,)g ([SETITEM],)f(page)h(13)g(,)f([PRINT],)h(page)g(19)g(.)150 1640 y Fk(mdarra)m(y)390 1859 y Fm(MDARRAY)46 b(sizelist)f(\(library)h (procedure\))390 1968 y(\(MDARRAY)g(sizelist)f(origin\))275 2097 y Fr(outputs)33 b(a)i(m)m(ulti-dimensional)g(arra)m(y)-8 b(.)54 b(The)34 b(\014rst)f(input)h(m)m(ust)g(b)s(e)g(a)g(list)h(of)g (one)f(or)h(more)f(p)s(osi-)150 2207 y(tiv)m(e)i(in)m(tegers.)56 b(The)34 b(second)h(input,)g(if)g(presen)m(t,)h(m)m(ust)f(b)s(e)f(a)h (single)h(in)m(teger)g(that)g(applies)f(to)g(ev)m(ery)150 2316 y(dimension)30 b(of)g(the)h(arra)m(y)-8 b(.)275 2445 y(Ex:)51 b Fm(\(MDARRAY)45 b([3)i(5])h(0\))35 b Fr(outputs)g(a)h(t)m(w)m(o-dimensional)i(arra)m(y)e(whose)f(mem)m(b)s (ers)g(range)h(from)150 2555 y([0)31 b(0])g(to)g([2)g(4])q(.)150 2761 y Fk(listtoarra)m(y)390 2980 y Fm(LISTTOARRAY)45 b(list)390 3090 y(\(LISTTOARRAY)f(list)j(origin\))275 3219 y Fr(outputs)30 b(an)h(arra)m(y)g(of)h(the)f(same)g(size)h(as)f (the)h(input)e(list,)i(whose)f(mem)m(b)s(ers)f(are)h(the)h(mem)m(b)s (ers)e(of)150 3328 y(the)h(input)e(list.)150 3535 y Fk(arra)m(ytolist) 390 3754 y Fm(ARRAYTOLIST)45 b(array)275 3883 y Fr(outputs)30 b(a)h(list)g(whose)f(mem)m(b)s(ers)g(are)h(the)g(mem)m(b)s(ers)f(of)g (the)h(input)f(arra)m(y)-8 b(.)42 b(The)30 b(\014rst)g(mem)m(b)s(er)g (of)150 3993 y(the)h(output)f(is)g(the)h(\014rst)e(mem)m(b)s(er)h(of)g (the)h(arra)m(y)-8 b(,)32 b(regardless)e(of)h(the)f(arra)m(y's)h (origin.)150 4199 y Fk(com)m(bine)390 4418 y Fm(COMBINE)46 b(thing1)g(thing2)g(\(library)g(procedure\))275 4547 y Fr(if)37 b(thing2)h(is)f(a)h(w)m(ord,)h(outputs)d(W)m(ORD)j(thing1)e (thing2.)62 b(If)37 b(thing2)h(is)f(a)h(list,)i(outputs)d(FPUT)150 4657 y(thing1)31 b(thing2.)275 4785 y(See)f([W)m(ORD],)i(page)f(9)g(,)g ([FPUT],)g(page)g(9)150 4992 y Fk(rev)m(erse)390 5211 y Fm(REVERSE)46 b(list)g(\(library)g(procedure\))275 5340 y Fr(outputs)29 b(a)i(list)g(whose)f(mem)m(b)s(ers)g(are)h(the)f (mem)m(b)s(ers)g(of)g(the)h(input)e(list,)j(in)e(rev)m(erse)h(order.)p eop end %%Page: 11 12 TeXDict begin 11 11 bop 150 -116 a Fr(Chapter)30 b(2:)41 b(Data)32 b(Structure)d(Primitiv)m(es)2009 b(11)150 299 y Fk(gensym)390 518 y Fm(GENSYM)46 b(\(library)g(procedure\))275 655 y Fr(outputs)29 b(a)i(unique)f(w)m(ord)g(eac)m(h)h(time)g(it's)g (in)m(v)m(ok)m(ed.)42 b(The)30 b(w)m(ords)g(are)h(of)f(the)h(form)f (G1,)h(G2,)h(etc.)150 918 y Fq(2.2)68 b(Data)46 b(Selectors)150 1257 y Fk(\014rst)390 1476 y Fm(FIRST)g(thing)275 1613 y Fr(if)39 b(the)g(input)f(is)h(a)h(w)m(ord,)h(outputs)d(the)h(\014rst) g(c)m(haracter)h(of)g(the)f(w)m(ord.)66 b(If)39 b(the)g(input)f(is)i(a) f(list,)150 1722 y(outputs)27 b(the)g(\014rst)g(mem)m(b)s(er)f(of)i (the)f(list.)41 b(If)26 b(the)i(input)e(is)h(an)h(arra)m(y)-8 b(,)29 b(outputs)d(the)i(origin)g(of)f(the)g(arra)m(y)150 1832 y(\(that)k(is,)g(the)g(INDEX)f(OF)h(the)f(\014rst)g(mem)m(b)s(er)g (of)g(the)h(arra)m(y\).)150 2061 y Fk(\014rsts)390 2280 y Fm(FIRSTS)46 b(list)275 2417 y Fr(outputs)33 b(a)i(list)f(con)m (taining)i(the)e(FIRST)g(of)g(eac)m(h)h(mem)m(b)s(er)f(of)g(the)g (input)f(list.)53 b(It)34 b(is)g(an)g(error)g(if)150 2527 y(an)m(y)f(mem)m(b)s(er)f(of)h(the)f(input)g(list)h(is)g(empt)m(y) -8 b(.)48 b(\(The)32 b(input)g(itself)h(ma)m(y)g(b)s(e)f(empt)m(y)-8 b(,)35 b(in)d(whic)m(h)g(case)i(the)150 2636 y(output)c(is)g(also)i (empt)m(y)-8 b(.\))42 b(This)29 b(could)i(b)s(e)e(written)i(as)390 2773 y Fm(to)47 b(firsts)f(:list)390 2883 y(output)g(map)h("first)f (:list)390 2992 y(end)275 3129 y Fr(but)29 b(is)h(pro)m(vided)g(as)g(a) h(primitiv)m(e)g(in)f(order)g(to)h(sp)s(eed)e(up)g(the)h(iteration)i (to)s(ols)f Fm(MAP)p Fr(,)f Fm(MAP.SE)p Fr(,)f(and)150 3239 y Fm(FOREACH)p Fr(.)390 3376 y Fm(to)47 b(transpose)e(:matrix)390 3485 y(if)i(emptyp)f(first)h(:matrix)e([op)i([]])390 3595 y(op)g(fput)g(firsts)f(:matrix)g(transpose)f(bfs)i(:matrix)390 3704 y(end)275 3841 y Fr(See)30 b([MAP],)i(page)f(77)g(,)f([MAPdSE],)h (page)g(77)g(,)g([F)m(OREA)m(CH],)h(page)f(77)150 4070 y Fk(last)390 4289 y Fm(LAST)47 b(wordorlist)275 4426 y Fr(if)39 b(the)h(input)f(is)h(a)g(w)m(ord,)i(outputs)e(the)g(last)g (c)m(haracter)i(of)e(the)g(w)m(ord.)69 b(If)39 b(the)h(input)f(is)h(a)g (list,)150 4536 y(outputs)30 b(the)g(last)i(mem)m(b)s(er)d(of)i(the)f (list.)150 4765 y Fk(but\014rst)390 4984 y Fm(BUTFIRST)46 b(wordorlist)390 5094 y(BF)h(wordorlist)275 5230 y Fr(if)28 b(the)h(input)e(is)i(a)f(w)m(ord,)h(outputs)f(a)h(w)m(ord)f(con)m (taining)i(all)f(but)f(the)h(\014rst)e(c)m(haracter)j(of)f(the)g (input.)150 5340 y(If)h(the)g(input)g(is)g(a)h(list,)g(outputs)f(a)h (list)g(con)m(taining)h(all)f(but)f(the)g(\014rst)g(mem)m(b)s(er)g(of)g (the)h(input.)p eop end %%Page: 12 13 TeXDict begin 12 12 bop 150 -116 a Fr(12)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(but\014rsts)390 518 y Fm(BUTFIRSTS)45 b(list)390 628 y(BFS)i(list)275 766 y Fr(outputs)27 b(a)g(list)i(con)m (taining)g(the)e(BUTFIRST)g(of)h(eac)m(h)h(mem)m(b)s(er)d(of)i(the)g (input)e(list.)41 b(It)27 b(is)h(an)f(error)150 876 y(if)35 b(an)m(y)g(mem)m(b)s(er)f(of)i(the)f(input)f(list)h(is)g(empt)m(y)h(or) f(an)f(arra)m(y)-8 b(.)56 b(\(The)34 b(input)g(itself)i(ma)m(y)g(b)s(e) e(empt)m(y)-8 b(,)37 b(in)150 986 y(whic)m(h)30 b(case)i(the)e(output)g (is)g(also)i(empt)m(y)-8 b(.\))42 b(This)29 b(could)i(b)s(e)e(written)i (as)390 1124 y Fm(to)47 b(butfirsts)e(:list)390 1234 y(output)h(map)h("butfirst)e(:list)390 1343 y(end)275 1482 y Fr(but)29 b(is)h(pro)m(vided)g(as)g(a)h(primitiv)m(e)g(in)f (order)g(to)h(sp)s(eed)e(up)g(the)h(iteration)i(to)s(ols)f Fm(MAP)p Fr(,)f Fm(MAP.SE)p Fr(,)f(and)150 1592 y Fm(FOREACH)p Fr(.)275 1730 y(See)h([MAP],)i(page)f(77)g(,)f([MAPdSE],)h(page)g(77)g (,)g([F)m(OREA)m(CH],)h(page)f(77)150 1963 y Fk(butlast)390 2182 y Fm(BUTLAST)46 b(wordorlist)390 2292 y(BL)h(wordorlist)275 2430 y Fr(if)29 b(the)g(input)g(is)g(a)h(w)m(ord,)f(outputs)g(a)h(w)m (ord)f(con)m(taining)i(all)f(but)f(the)g(last)i(c)m(haracter)g(of)e (the)h(input.)150 2540 y(If)g(the)g(input)g(is)g(a)h(list,)g(outputs)f (a)h(list)g(con)m(taining)h(all)f(but)f(the)g(last)i(mem)m(b)s(er)d(of) i(the)f(input.)150 2772 y Fk(item)390 2992 y Fm(ITEM)47 b(index)f(thing)275 3130 y Fr(if)37 b(the)g Fm(thing)f Fr(is)h(a)h(w)m(ord,)h(outputs)e(the)g Fm(index)p Fr(th)f(c)m(haracter) j(of)e(the)h(w)m(ord.)61 b(If)37 b(the)g Fm(thing)f Fr(is)i(a)150 3240 y(list,)30 b(outputs)e(the)h Fm(index)p Fr(th)f(mem)m(b)s(er)g(of) h(the)g(list.)41 b(If)28 b(the)h Fm(thing)e Fr(is)i(an)g(arra)m(y)-8 b(,)30 b(outputs)e(the)i Fm(index)p Fr(th)150 3350 y(mem)m(b)s(er)i(of) h(the)g(arra)m(y)-8 b(.)49 b Fm(Index)32 b Fr(starts)h(at)g(1)h(for)e (w)m(ords)h(and)f(lists;)j(the)e(starting)g(index)g(of)g(an)f(arra)m(y) 150 3459 y(is)e(sp)s(eci\014ed)g(when)f(the)i(arra)m(y)g(is)f(created.) 150 3692 y Fk(mditem)390 3911 y Fm(MDITEM)46 b(indexlist)f(array)i (\(library)e(procedure\))275 4050 y Fr(outputs)g(the)g(mem)m(b)s(er)g (of)h(the)g(m)m(ultidimensional)h Fm(array)d Fr(selected)j(b)m(y)e(the) h(list)h(of)e(n)m(um)m(b)s(ers)150 4159 y Fm(indexlist)p Fr(.)150 4392 y Fk(pic)m(k)390 4611 y Fm(PICK)i(list)f(\(library)g (procedure\))275 4750 y Fr(outputs)29 b(a)i(randomly)f(c)m(hosen)h(mem) m(b)s(er)f(of)g(the)h(input)e(list.)150 4982 y Fk(remo)m(v)m(e)390 5201 y Fm(REMOVE)46 b(thing)g(list)h(\(library)f(procedure\))275 5340 y Fr(outputs)29 b(a)i(cop)m(y)g(of)g Fm(list)e Fr(with)h(ev)m(ery) h(mem)m(b)s(er)f(equal)h(to)g Fm(thing)e Fr(remo)m(v)m(ed.)p eop end %%Page: 13 14 TeXDict begin 13 13 bop 150 -116 a Fr(Chapter)30 b(2:)41 b(Data)32 b(Structure)d(Primitiv)m(es)2009 b(13)150 299 y Fk(remdup)390 518 y Fm(REMDUP)46 b(list)h(\(library)e(procedure\))275 651 y Fr(outputs)35 b(a)h(cop)m(y)h(of)f Fm(list)e Fr(with)i(duplicate) g(mem)m(b)s(ers)f(remo)m(v)m(ed.)58 b(If)36 b(t)m(w)m(o)h(or)f(more)g (mem)m(b)s(ers)f(of)150 760 y(the)29 b(input)g(are)g(equal,)i(the)e (righ)m(tmost)i(of)e(those)h(mem)m(b)s(ers)e(is)i(the)f(one)h(that)g (remains)f(in)g(the)g(output.)150 980 y Fk(quoted)390 1199 y Fm(QUOTED)46 b(thing)g(\(library)g(procedure\))275 1332 y Fr(outputs)25 b(its)h(input,)g(if)g(a)g(list;)j(outputs)c(its)h (input)f(with)h(a)g(quotation)h(mark)f(prep)s(ended,)f(if)h(a)g(w)m (ord.)150 1584 y Fq(2.3)68 b(Data)46 b(Mutators)150 1913 y Fk(setitem)390 2132 y Fm(SETITEM)g(index)g(array)h(value)275 2265 y Fr(command.)j(Replaces)35 b(the)f Fm(index)p Fr(th)f(mem)m(b)s (er)g(of)h Fm(array)e Fr(with)i(the)g(new)f Fm(value)p Fr(.)50 b(Ensures)32 b(that)150 2374 y(the)25 b(resulting)g(arra)m(y)g (is)g(not)g(circular,)h(i.e.,)i Fm(value)23 b Fr(ma)m(y)i(not)g(b)s(e)f (a)h(list)h(or)f(arra)m(y)g(that)g(con)m(tains)h Fm(array)p Fr(.)150 2594 y Fk(mdsetitem)390 2813 y Fm(MDSETITEM)45 b(indexlist)h(array)g(value)g(\(library)g(procedure\))275 2946 y Fr(command.)40 b(Replaces)32 b(the)e(mem)m(b)s(er)g(of)g Fm(array)f Fr(c)m(hosen)i(b)m(y)f Fm(indexlist)e Fr(with)i(the)h(new)f Fm(value)p Fr(.)150 3165 y Fk(.set\014rst)390 3384 y Fm(.SETFIRST)45 b(list)i(value)275 3517 y Fr(command.)40 b(Changes)30 b(the)h(\014rst)e(mem)m(b)s(er)h(of)h Fm(list)e Fr(to)i(b)s(e)f Fm(value)p Fr(.)275 3650 y(W)-10 b(ARNING:)22 b(Primitiv)m(es)h(whose)f(names)f(start)h(with)g(a)g(p)s(erio)s(d)e (are)i(D)m(ANGER)m(OUS.)i(Their)d(use)g(b)m(y)150 3759 y(non-exp)s(erts)i(is)g(not)g(recommended.)38 b(The)23 b(use)g(of)h(.SETFIRST)d(can)j(lead)g(to)g(circular)f(list)h (structures,)150 3869 y(whic)m(h)33 b(will)i(get)f(some)h(Logo)g (primitiv)m(es)f(in)m(to)h(in\014nite)e(lo)s(ops;)j(unexp)s(ected)d(c)m (hanges)i(to)f(other)g(data)150 3978 y(structures)41 b(that)i(share)e(storage)j(with)d(the)h(list)h(b)s(eing)f(mo)s (di\014ed;)k(and)c(the)g(loss)g(of)g(memory)g(if)g(a)150 4088 y(circular)31 b(structure)f(is)g(released.)150 4307 y Fk(.setbf)390 4526 y Fm(.SETBF)46 b(list)h(value)275 4659 y Fr(command.)40 b(Changes)30 b(the)h(but\014rst)e(of)h Fm(list)f Fr(to)j(b)s(e)d Fm(value)p Fr(.)275 4792 y(W)-10 b(ARNING:)33 b(Primitiv)m(es)g(whose)g(names)f(start)h(with)f(a)h(p)s (erio)s(d)e(are)i(D)m(ANGER)m(OUS.)g(Their)f(use)150 4902 y(b)m(y)26 b(non-exp)s(erts)f(is)g(not)h(recommended.)39 b(The)25 b(use)h(of)g(.SETBF)f(can)h(lead)g(to)h(circular)f(list)g (structures,)150 5011 y(whic)m(h)33 b(will)i(get)f(some)h(Logo)g (primitiv)m(es)f(in)m(to)h(in\014nite)e(lo)s(ops;)j(unexp)s(ected)d(c)m (hanges)i(to)f(other)g(data)150 5121 y(structures)f(that)h(share)g (storage)h(with)f(the)f(list)i(b)s(eing)e(mo)s(di\014ed;)i(Logo)f (crashes)g(and)f(coredumps)g(if)150 5230 y(the)39 b(but\014rst)e(of)i (a)g(list)g(is)g(not)g(itself)h(a)f(list;)k(and)c(the)f(loss)h(of)g (memory)g(if)g(a)g(circular)g(structure)f(is)150 5340 y(released.)p eop end %%Page: 14 15 TeXDict begin 14 14 bop 150 -116 a Fr(14)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(.setitem)390 518 y Fm(.SETITEM)46 b(index)g(array)g(value)275 651 y Fr(command.)65 b(Changes)39 b(the)g Fm(index)p Fr(th)e(mem)m(b)s(er)h(of)h Fm(array)e Fr(to)j(b)s(e)e Fm(value)p Fr(,)i(lik)m(e)g(SETITEM,)e(but)150 760 y(without)30 b(c)m(hec)m(king)j(for)d(circularit)m(y)-8 b(.)275 893 y(W)e(ARNING:)33 b(Primitiv)m(es)g(whose)g(names)f(start)h (with)f(a)h(p)s(erio)s(d)e(are)i(D)m(ANGER)m(OUS.)g(Their)f(use)150 1003 y(b)m(y)38 b(non-exp)s(erts)g(is)h(not)f(recommended.)65 b(The)38 b(use)g(of)h(.SETITEM)e(can)i(lead)g(to)g(circular)g(arra)m (ys,)150 1112 y(whic)m(h)28 b(will)h(get)g(some)g(Logo)h(primitiv)m(es) f(in)m(to)g(in\014nite)f(lo)s(ops;)h(and)f(the)h(loss)g(of)f(memory)g (if)h(a)g(circular)150 1222 y(structure)h(is)g(released.)275 1355 y(See)g([SETITEM],)g(page)h(13.)150 1574 y Fk(push)390 1793 y Fm(PUSH)47 b(stackname)e(thing)h(\(library)g(procedure\))275 1926 y Fr(command.)58 b(Adds)36 b(the)g Fm(thing)f Fr(to)j(the)e(stac)m (k)i(that)f(is)g(the)f(v)-5 b(alue)37 b(of)g(the)f(v)-5 b(ariable)38 b(whose)e(name)150 2036 y(is)g Fm(stackname)p Fr(.)57 b(This)35 b(v)-5 b(ariable)37 b(m)m(ust)g(ha)m(v)m(e)g(a)g (list)g(as)g(its)f(v)-5 b(alue;)41 b(the)36 b(initial)i(v)-5 b(alue)37 b(should)e(b)s(e)h(the)150 2145 y(empt)m(y)31 b(list.)41 b(New)31 b(mem)m(b)s(ers)e(are)i(added)f(at)h(the)f(fron)m (t)h(of)f(the)h(list.)150 2364 y Fk(p)s(op)390 2584 y Fm(POP)47 b(stackname)e(\(library)h(procedure\))275 2716 y Fr(outputs)26 b(the)i(most)g(recen)m(tly)h(PUSHed)e(mem)m(b)s(er)g (of)g(the)h(stac)m(k)h(that)f(is)f(the)h(v)-5 b(alue)28 b(of)f(the)h(v)-5 b(ariable)150 2826 y(whose)30 b(name)h(is)f Fm(stackname)e Fr(and)i(remo)m(v)m(es)h(that)g(mem)m(b)s(er)f(from)g (the)h(stac)m(k.)150 3045 y Fk(queue)390 3264 y Fm(QUEUE)46 b(queuename)g(thing)g(\(library)g(procedure\))275 3397 y Fr(command.)53 b(Adds)34 b(the)h Fm(thing)f Fr(to)h(the)g(queue)g (that)g(is)g(the)g(v)-5 b(alue)36 b(of)f(the)g(v)-5 b(ariable)35 b(whose)g(name)150 3507 y(is)h Fm(queuename)p Fr(.)57 b(This)35 b(v)-5 b(ariable)37 b(m)m(ust)g(ha)m(v)m(e)g(a)g(list)g(as)g (its)f(v)-5 b(alue;)41 b(the)36 b(initial)i(v)-5 b(alue)37 b(should)e(b)s(e)h(the)150 3616 y(empt)m(y)31 b(list.)41 b(New)31 b(mem)m(b)s(ers)e(are)i(added)f(at)h(the)f(bac)m(k)i(of)e(the) h(list.)150 3836 y Fk(dequeue)390 4055 y Fm(DEQUEUE)46 b(queuename)f(\(library)h(procedure\))275 4188 y Fr(outputs)23 b(the)g(least)i(recen)m(tly)g(QUEUEd)e(mem)m(b)s(er)g(of)g(the)h(queue) f(that)h(is)g(the)g(v)-5 b(alue)24 b(of)f(the)h(v)-5 b(ariable)150 4297 y(whose)30 b(name)h(is)f Fm(queuename)e Fr(and)i(remo)m(v)m(es)h(that)g(mem)m(b)s(er)f(from)g(the)h(queue.)150 4550 y Fq(2.4)68 b(Predicates)150 4878 y Fk(w)m(ordp)390 5098 y Fm(WORDP)46 b(thing)390 5207 y(WORD?)g(thing)275 5340 y Fr(outputs)29 b(TR)m(UE)i(if)f(the)h(input)e(is)i(a)f(w)m(ord,)h (F)-10 b(ALSE)29 b(otherwise.)p eop end %%Page: 15 16 TeXDict begin 15 15 bop 150 -116 a Fr(Chapter)30 b(2:)41 b(Data)32 b(Structure)d(Primitiv)m(es)2009 b(15)150 299 y Fk(listp)390 518 y Fm(LISTP)46 b(thing)390 628 y(LIST?)g(thing)275 765 y Fr(outputs)29 b(TR)m(UE)i(if)f(the)h(input)e(is)i(a)f(list,)i(F) -10 b(ALSE)29 b(otherwise.)150 995 y Fk(arra)m(yp)390 1214 y Fm(ARRAYP)46 b(thing)390 1323 y(ARRAY?)g(thing)275 1461 y Fr(outputs)29 b(TR)m(UE)i(if)f(the)h(input)e(is)i(an)f(arra)m(y) -8 b(,)31 b(F)-10 b(ALSE)30 b(otherwise.)150 1691 y Fk(empt)m(yp)390 1910 y Fm(EMPTYP)46 b(thing)390 2019 y(EMPTY?)g(thing)275 2157 y Fr(outputs)29 b(TR)m(UE)i(if)f(the)h(input)e(is)i(the)f(empt)m (y)h(w)m(ord)f(or)g(the)h(empt)m(y)g(list,)g(F)-10 b(ALSE)30 b(otherwise.)150 2386 y Fk(equalp)390 2606 y Fm(EQUALP)46 b(thing1)g(thing2)390 2715 y(EQUAL?)g(thing1)g(thing2)390 2825 y(thing1)g(=)i(thing2)275 2962 y Fr(outputs)39 b(TR)m(UE)h(if)f (the)h(inputs)f(are)h(equal,)j(F)-10 b(ALSE)39 b(otherwise.)69 b(Tw)m(o)40 b(n)m(um)m(b)s(ers)f(are)h(equal)g(if)150 3072 y(they)35 b(ha)m(v)m(e)h(the)f(same)g(n)m(umeric)g(v)-5 b(alue.)54 b(Tw)m(o)35 b(non-n)m(umeric)f(w)m(ords)h(are)g(equal)g(if)g (they)g(con)m(tain)h(the)150 3181 y(same)d(c)m(haracters)g(in)f(the)h (same)f(order.)46 b(If)32 b(there)h(is)f(a)g(v)-5 b(ariable)34 b(named)d Fn(CASEIGNOREDP)37 b Fr(whose)150 3291 y(v)-5 b(alue)27 b(is)g(TR)m(UE,)h(then)e(an)h(upp)s(er)e(case)j(letter)g(is)f (considered)g(the)g(same)g(as)h(the)f(corresp)s(onding)f(lo)m(w)m(er) 150 3400 y(case)36 b(letter.)55 b(\(This)34 b(is)h(the)g(case)h(b)m(y)e (default.\))55 b(Tw)m(o)35 b(lists)g(are)g(equal)h(if)e(their)h(mem)m (b)s(ers)f(are)h(equal.)150 3510 y(An)c(arra)m(y)h(is)f(only)h(equal)g (to)g(itself;)h(t)m(w)m(o)g(separately)g(created)f(arra)m(ys)g(are)g (nev)m(er)f(equal)h(ev)m(en)g(if)g(their)150 3620 y(mem)m(b)s(ers)h (are)i(equal.)52 b(\(It)34 b(is)g(imp)s(ortan)m(t)h(to)f(b)s(e)g(able)g (to)h(kno)m(w)f(if)g(t)m(w)m(o)h(expressions)f(ha)m(v)m(e)h(the)g(same) 150 3729 y(arra)m(y)25 b(as)g(their)g(v)-5 b(alue)25 b(b)s(ecause)g(arra)m(ys)g(are)g(m)m(utable;)i(if,)f(for)f(example,)h (t)m(w)m(o)g(v)-5 b(ariables)26 b(ha)m(v)m(e)g(the)f(same)150 3839 y(arra)m(y)h(as)g(their)g(v)-5 b(alues)26 b(then)f(p)s(erforming)g (SETITEM)f(on)i(one)g(of)g(them)g(will)g(also)g(c)m(hange)h(the)f (other.\))275 3976 y(See)k([CASEIGNOREDP],)h(page)g(89)g(,)f ([SETITEM],)g(page)h(13)150 4206 y Fk(notequalp)390 4425 y Fm(NOTEQUALP)45 b(thing1)h(thing2)390 4535 y(NOTEQUAL?)f(thing1)h (thing2)390 4644 y(thing1)g(<>)h(thing2)275 4781 y Fr(outputs)25 b(F)-10 b(ALSE)26 b(if)g(the)h(inputs)e(are)i(equal,)h(TR)m(UE)e (otherwise.)40 b(See)26 b(EQUALP)g(for)g(the)h(meaning)150 4891 y(of)k(equalit)m(y)g(for)g(di\013eren)m(t)f(data)i(t)m(yp)s(es.) 150 5121 y Fk(b)s(eforep)390 5340 y Fm(BEFOREP)46 b(word1)g(word2)p eop end %%Page: 16 17 TeXDict begin 16 16 bop 150 -116 a Fr(16)2551 b(BERKELEY)30 b(LOGO)g(5.5)390 299 y Fm(BEFORE?)46 b(word1)g(word2)275 438 y Fr(outputs)c(TR)m(UE)g(if)h(w)m(ord1)f(comes)i(b)s(efore)e(w)m (ord2)h(in)f(ASCI)s(I)f(collating)k(sequence)e(\(for)f(w)m(ords)150 547 y(of)49 b(letters,)55 b(in)48 b(alphab)s(etical)i(order\).)96 b(Case-sensitivit)m(y)51 b(is)e(determined)g(b)m(y)g(the)g(v)-5 b(alue)49 b(of)g(CA-)150 657 y(SEIGNOREDP)-8 b(.)37 b(Note)h(that)g(if) f(the)g(inputs)f(are)h(n)m(um)m(b)s(ers,)g(the)g(result)g(ma)m(y)h(not) f(b)s(e)f(the)h(same)h(as)150 766 y(with)30 b(LESSP;)f(for)h(example,)i Fm(BEFOREP)45 b(3)j(12)30 b Fr(is)g(false)h(b)s(ecause)g(3)f(collates)j (after)e(1.)275 905 y(See)f([CASEIGNOREDP],)h(page)g(89)g(,)f([LESSP],) g(page)h(32)150 1138 y Fk(.eq)390 1357 y Fm(.EQ)47 b(thing1)f(thing2) 275 1495 y Fr(outputs)29 b(TR)m(UE)g(if)h(its)g(t)m(w)m(o)h(inputs)d (are)i(the)g(same)g(datum,)f(so)h(that)g(applying)g(a)g(m)m(utator)g (to)h(one)150 1605 y(will)37 b(c)m(hange)g(the)g(other)f(as)h(w)m(ell.) 60 b(Outputs)35 b(F)-10 b(ALSE)36 b(otherwise,)i(ev)m(en)f(if)g(the)f (inputs)g(are)g(equal)h(in)150 1715 y(v)-5 b(alue.)275 1853 y(W)-10 b(ARNING:)22 b(Primitiv)m(es)h(whose)f(names)f(start)h (with)g(a)g(p)s(erio)s(d)e(are)i(D)m(ANGER)m(OUS.)i(Their)d(use)g(b)m (y)150 1963 y(non-exp)s(erts)28 b(is)h(not)g(recommended.)39 b(The)29 b(use)f(of)h(m)m(utators)g(can)g(lead)g(to)h(circular)f(data)g (structures,)150 2072 y(in\014nite)h(lo)s(ops,)h(or)f(Logo)i(crashes.) 150 2305 y Fk(mem)m(b)s(erp)390 2524 y Fm(MEMBERP)46 b(thing1)g(thing2)390 2634 y(MEMBER?)g(thing1)g(thing2)275 2772 y Fr(if)37 b Fm(thing2)f Fr(is)h(a)h(list)g(or)f(an)g(arra)m(y)-8 b(,)41 b(outputs)36 b(TR)m(UE)i(if)f Fm(thing1)f Fr(is)h(EQUALP)g(to)h (a)g(mem)m(b)s(er)f(of)150 2882 y Fm(thing2)p Fr(,)26 b(F)-10 b(ALSE)26 b(otherwise.)40 b(If)26 b Fm(thing2)f Fr(is)i(a)g(w)m(ord,)g(outputs)f(TR)m(UE)h(if)f Fm(thing1)f Fr(is)i(a)g(one-c)m(haracter)150 2992 y(w)m(ord)j(EQUALP)g(to)h(a)g(c)m (haracter)h(of)e Fm(thing2)p Fr(,)f(F)-10 b(ALSE)30 b(otherwise.)275 3130 y(See)g([EQUALP],)h(page)g(15)g(.)150 3363 y Fk(substringp)390 3582 y Fm(SUBSTRINGP)45 b(thing1)h(thing2)390 3692 y(SUBSTRING?)f (thing1)h(thing2)275 3830 y Fr(if)32 b Fm(thing1)e Fr(or)i Fm(thing2)f Fr(is)h(a)g(list)h(or)f(an)g(arra)m(y)-8 b(,)34 b(outputs)d(F)-10 b(ALSE.)32 b(If)g Fm(thing2)e Fr(is)j(a)f(w)m(ord,)g(outputs)150 3940 y(TR)m(UE)e(if)h Fm(thing1)d Fr(is)j(EQUALP)f(to)h(a)g(substring)e(of)h Fm(thing2)p Fr(,)f(F)-10 b(ALSE)30 b(otherwise.)275 4079 y(See)g([EQUALP],)h(page)g(15)g(.)150 4311 y Fk(n)m(um)m(b)s(erp)390 4530 y Fm(NUMBERP)46 b(thing)390 4640 y(NUMBER?)g(thing)275 4779 y Fr(outputs)29 b(TR)m(UE)i(if)f(the)h(input)e(is)i(a)f(n)m(um)m (b)s(er,)g(F)-10 b(ALSE)30 b(otherwise.)150 5011 y Fk(bac)m(kslashedp) 390 5230 y Fm(BACKSLASHEDP)44 b(char)390 5340 y(BACKSLASHED?)g(char)p eop end %%Page: 17 18 TeXDict begin 17 17 bop 150 -116 a Fr(Chapter)30 b(2:)41 b(Data)32 b(Structure)d(Primitiv)m(es)2009 b(17)275 299 y(outputs)30 b(TR)m(UE)h(if)g(the)g(input)g(c)m(haracter)h(w)m(as)g (originally)g(en)m(tered)g(in)m(to)g(Logo)g(with)f(a)g(bac)m(kslash)150 408 y(\()p Fm(\\)p Fr(\))22 b(b)s(efore)f(it)g(or)h(within)e(v)m (ertical)k(bars)c(\()p Fm(|)p Fr(\))i(to)g(prev)m(en)m(t)g(its)g(usual) f(sp)s(ecial)g(syn)m(tactic)j(meaning,)f(F)-10 b(ALSE)150 518 y(otherwise.)58 b(\(Outputs)34 b(TR)m(UE)i(only)g(if)g(the)g(c)m (haracter)h(is)f(a)g(bac)m(kslashed)h(space,)h(tab,)g(newline,)f(or)150 628 y(one)31 b(of)f Fm(\(\)[]+-*/=<>":;\\~?|)c Fr(\))150 883 y Fq(2.5)68 b(Queries)150 1214 y Fk(coun)m(t)390 1434 y Fm(COUNT)46 b(thing)275 1567 y Fr(outputs)23 b(the)h(n)m(um)m(b) s(er)e(of)i(c)m(haracters)h(in)e(the)h(input,)g(if)g(the)g(input)f(is)g (a)h(w)m(ord;)i(outputs)d(the)h(n)m(um)m(b)s(er)150 1677 y(of)33 b(mem)m(b)s(ers)g(in)g(the)g(input,)g(if)h(it)f(is)h(a)f(list)h (or)f(an)g(arra)m(y)-8 b(.)51 b(\(F)-8 b(or)34 b(an)f(arra)m(y)-8 b(,)35 b(this)e(ma)m(y)h(or)f(ma)m(y)h(not)g(b)s(e)150 1787 y(the)d(index)f(of)g(the)h(last)g(mem)m(b)s(er,)f(dep)s(ending)f (on)h(the)h(arra)m(y's)g(origin.\))150 2008 y Fk(ascii)390 2228 y Fm(ASCII)46 b(char)275 2361 y Fr(outputs)23 b(the)h(in)m(teger)h (\(b)s(et)m(w)m(een)f(0)h(and)e(255\))i(that)f(represen)m(ts)g(the)g (input)f(c)m(haracter)i(in)f(the)f(ASCI)s(I)150 2471 y(co)s(de.)38 b(In)m(terprets)22 b(con)m(trol)h(c)m(haracters)g(as)g (represen)m(ting)f(bac)m(kslashed)g(punctuation,)i(and)d(returns)g(the) 150 2581 y(c)m(haracter)35 b(co)s(de)f(for)f(the)g(corresp)s(onding)g (punctuation)g(c)m(haracter)i(without)e(bac)m(kslash.)51 b(\(Compare)150 2690 y(RA)-10 b(W)g(ASCI)s(I.\))150 2912 y Fk(ra)m(w)m(ascii)390 3131 y Fm(RAWASCII)46 b(char)275 3265 y Fr(outputs)23 b(the)h(in)m(teger)h(\(b)s(et)m(w)m(een)f(0)h(and) e(255\))i(that)f(represen)m(ts)g(the)g(input)f(c)m(haracter)i(in)f(the) f(ASCI)s(I)150 3375 y(co)s(de.)40 b(In)m(terprets)29 b(con)m(trol)h(c)m(haracters)h(as)e(represen)m(ting)g(themselv)m(es.)41 b(T)-8 b(o)30 b(\014nd)d(out)i(the)g(ASCI)s(I)f(co)s(de)150 3484 y(of)j(an)f(arbitrary)g(k)m(eystrok)m(e,)i(use)f Fm(RAWASCII)45 b(RC)p Fr(.)150 3706 y Fk(c)m(har)390 3925 y Fm(CHAR)i(int)275 4059 y Fr(outputs)36 b(the)h(c)m(haracter)i (represen)m(ted)e(in)f(the)i(ASCI)s(I)d(co)s(de)i(b)m(y)g(the)g(input,) h(whic)m(h)f(m)m(ust)g(b)s(e)f(an)150 4169 y(in)m(teger)c(b)s(et)m(w)m (een)f(0)g(and)e(255.)275 4303 y(See)h([ASCI)s(I],)g(page)h(17)g(.)150 4524 y Fk(mem)m(b)s(er)390 4744 y Fm(MEMBER)46 b(thing1)g(thing2)275 4877 y Fr(if)35 b Fm(thing2)f Fr(is)i(a)g(w)m(ord)f(or)h(list)g(and)f (if)h(MEMBERP)g(with)f(these)h(inputs)f(w)m(ould)g(output)h(TR)m(UE,) 150 4987 y(outputs)29 b(the)g(p)s(ortion)g(of)h Fm(thing2)e Fr(from)h(the)g(\014rst)g(instance)h(of)f Fm(thing1)f Fr(to)i(the)g(end.)39 b(If)29 b(MEMBERP)150 5097 y(w)m(ould)j(output)g (F)-10 b(ALSE,)32 b(outputs)g(the)g(empt)m(y)h(w)m(ord)f(or)g(list)h (according)h(to)f(the)f(t)m(yp)s(e)h(of)f Fm(thing2)p Fr(.)45 b(It)150 5206 y(is)30 b(an)h(error)f(for)g Fm(thing2)e Fr(to)k(b)s(e)d(an)i(arra)m(y)-8 b(.)275 5340 y(See)30 b([MEMBERP],)i(page)f(16)g(.)p eop end %%Page: 18 19 TeXDict begin 18 18 bop 150 -116 a Fr(18)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(lo)m(w)m(ercase)390 518 y Fm(LOWERCASE)45 b(word)275 649 y Fr(outputs)33 b(a)h(cop)m(y)h(of)f(the)g(input)f(w)m (ord,)h(but)g(with)f(all)i(upp)s(ercase)e(letters)i(c)m(hanged)g(to)f (the)g(corre-)150 758 y(sp)s(onding)29 b(lo)m(w)m(ercase)k(letter.)150 970 y Fk(upp)s(ercase)390 1189 y Fm(UPPERCASE)45 b(word)275 1320 y Fr(outputs)34 b(a)i(cop)m(y)g(of)g(the)f(input)g(w)m(ord,)h(but) f(with)g(all)h(lo)m(w)m(ercase)i(letters)f(c)m(hanged)f(to)g(the)f (corre-)150 1429 y(sp)s(onding)29 b(upp)s(ercase)g(letter.)150 1642 y Fk(standout)390 1861 y Fm(STANDOUT)46 b(thing)275 1991 y Fr(outputs)28 b(a)i(w)m(ord)e(that,)j(when)d(prin)m(ted,)h(will) g(app)s(ear)g(lik)m(e)h(the)g(input)e(but)g(displa)m(y)m(ed)i(in)f (standout)150 2101 y(mo)s(de)38 b(\(b)s(oldface,)k(rev)m(erse)d(video,) i(or)e(whatev)m(er)g(y)m(our)g(terminal)g(do)s(es)f(for)h(standout\).) 65 b(The)38 b(w)m(ord)150 2210 y(con)m(tains)k(terminal-sp)s(eci\014c)g (magic)h(c)m(haracters)f(at)g(the)g(b)s(eginning)e(and)h(end;)46 b(in)41 b(b)s(et)m(w)m(een)h(is)f(the)150 2320 y(prin)m(ted)28 b(form)g(\(as)h(if)g(displa)m(y)m(ed)g(using)f(TYPE\))h(of)f(the)h (input.)39 b(The)28 b(output)h(is)f(alw)m(a)m(ys)i(a)f(w)m(ord,)g(ev)m (en)150 2430 y(if)23 b(the)h(input)e(is)h(of)g(some)h(other)f(t)m(yp)s (e,)j(but)c(it)i(ma)m(y)g(include)e(spaces)i(and)f(other)g(formatting)h (c)m(haracters.)150 2539 y(Note:)42 b(a)31 b(w)m(ord)f(output)g(b)m(y)g (ST)-8 b(ANDOUT)30 b(while)h(Logo)g(is)g(running)d(on)i(one)h(terminal) g(will)g(probably)150 2649 y(not)g(ha)m(v)m(e)g(the)g(desired)f (e\013ect)i(if)e(prin)m(ted)g(on)g(another)h(t)m(yp)s(e)f(of)h (terminal.)275 2779 y(On)j(the)i(Macin)m(tosh,)i(the)d(w)m(a)m(y)i (that)f(standout)f(w)m(orks)g(is)h(incompatible)g(with)f(the)h(use)f (of)g(c)m(har-)150 2889 y(acters)f(whose)g(ASCI)s(I)e(co)s(de)h(is)h (greater)h(than)e(127.)51 b(Therefore,)35 b(y)m(ou)e(ha)m(v)m(e)i(a)f (c)m(hoice)h(to)f(mak)m(e:)48 b(The)150 2998 y(instruction)390 3129 y Fm(CANINVERSE)d(0)275 3259 y Fr(disables)25 b(standout,)h(but)f (enables)h(the)f(displa)m(y)h(of)f(ASCI)s(I)f(co)s(des)h(ab)s(o)m(v)m (e)i(127,)h(and)c(the)i(instruction)390 3390 y Fm(CANINVERSE)45 b(1)275 3520 y Fr(restores)33 b(the)h(default)f(situation)h(in)f(whic)m (h)g(standout)g(is)h(enabled)f(and)f(the)i(extra)g(graphic)f(c)m(har-) 150 3630 y(acters)e(cannot)g(b)s(e)f(prin)m(ted.)150 3842 y Fk(parse)390 4061 y Fm(PARSE)46 b(word)275 4192 y Fr(outputs)25 b(the)g(list)h(that)h(w)m(ould)e(result)g(if)h(the)f (input)g(w)m(ord)g(w)m(ere)h(en)m(tered)g(in)g(resp)s(onse)e(to)i(a)g (READ-)150 4301 y(LIST)i(op)s(eration.)41 b(That)30 b(is,)g Fm(PARSE)46 b(READWORD)28 b Fr(has)h(the)h(same)g(v)-5 b(alue)30 b(as)g(READLIST)e(for)i(the)g(same)150 4411 y(c)m(haracters)i(read.)275 4541 y(See)e([READLIST],)g(page)i(20)f(,)f ([READ)m(W)m(ORD],)j(page)e(20)150 4753 y Fk(runparse)390 4973 y Fm(RUNPARSE)46 b(wordorlist)275 5103 y Fr(outputs)26 b(the)h(list)h(that)g(w)m(ould)f(result)g(if)g(the)g(input)g(w)m(ord)f (or)h(list)h(w)m(ere)g(en)m(tered)g(as)f(an)g(instruction)150 5213 y(line;)g(c)m(haracters)g(suc)m(h)e(as)g(in\014x)f(op)s(erators)h (and)g(paren)m(theses)g(are)g(separate)h(mem)m(b)s(ers)f(of)g(the)g (output.)150 5322 y(Note)32 b(that)f(sublists)e(of)i(a)g(runparsed)d (list)j(are)g(not)f(themselv)m(es)i(runparsed.)p eop end %%Page: 19 20 TeXDict begin 19 19 bop 150 -116 a Fr(Chapter)30 b(3:)41 b(Comm)m(unication)2416 b(19)150 299 y Fp(3)80 b(Comm)l(unication)150 658 y Fq(3.1)68 b(T)-11 b(ransmitters)275 902 y Fr(Note:)59 b(If)39 b(there)h(is)f(a)h(v)-5 b(ariable)40 b(named)e Fn(PRINTDEPTHLIMIT)45 b Fr(with)39 b(a)h(nonnegativ)m(e)h(in)m(teger) 150 1012 y(v)-5 b(alue,)43 b(then)c(complex)h(list)g(and)f(arra)m(y)h (structures)f(will)h(b)s(e)f(prin)m(ted)g(only)g(to)h(the)g(allo)m(w)m (ed)h(depth.)150 1121 y(That)33 b(is,)i(mem)m(b)s(ers)e(of)g(mem)m(b)s (ers)g(of...)51 b(of)34 b(mem)m(b)s(ers)e(will)i(b)s(e)f(allo)m(w)m(ed) i(only)f(so)g(far.)50 b(The)33 b(mem)m(b)s(ers)150 1231 y(omitted)c(b)s(ecause)f(they)g(are)h(just)e(past)h(the)h(depth)e (limit)i(are)f(indicated)h(b)m(y)f(an)g(ellipsis)g(for)g(eac)m(h)h (one,)150 1341 y(so)i(a)f(to)s(o-deep)i(list)f(of)f(t)m(w)m(o)i(mem)m (b)s(ers)d(will)i(prin)m(t)f(as)h([)6 b(.)22 b(.)g(.)47 b(.)23 b(.)f(.)11 b(].)275 1476 y(If)38 b(there)i(is)f(a)h(v)-5 b(ariable)40 b(named)f Fn(PRINTWIDTHLIMIT)46 b Fr(with)39 b(a)g(nonnegativ)m(e)i(in)m(teger)g(v)-5 b(alue,)150 1585 y(then)34 b(only)g(the)g(\014rst)f(so)h(man)m(y)g(mem)m(b)s(ers)f (of)h(an)m(y)h(arra)m(y)f(or)g(list)g(will)h(b)s(e)e(prin)m(ted.)51 b(A)34 b(single)g(ellipsis)150 1695 y(replaces)25 b(all)g(missing)g (data)g(within)f(the)g(structure.)38 b(The)24 b(width)g(limit)h(also)g (applies)g(to)g(the)g(n)m(um)m(b)s(er)e(of)150 1804 y(c)m(haracters)31 b(prin)m(ted)d(in)h(a)h(w)m(ord,)f(except)h(that)g(a)f Fn(PRINTWIDTHLIMIT)36 b Fr(b)s(et)m(w)m(een)29 b(0)h(and)f(9)g(will)h (b)s(e)150 1914 y(treated)i(as)f(if)g(it)h(w)m(ere)f(10)h(when)e (applied)h(to)g(w)m(ords.)42 b(This)31 b(limit)g(applies)g(not)h(only)f (to)g(the)h(top-lev)m(el)150 2024 y(prin)m(ted)e(datum)g(but)f(to)j(an) m(y)e(substructures)f(within)h(it.)275 2158 y(See)g([PRINTDEPTHLIMIT],) g(page)h(90)g(,)g([PRINTWIDTHLIMIT],)g(page)g(90)275 2293 y(If)c(there)h(is)f(a)h(v)-5 b(ariable)29 b(named)e Fn(FULLPRINTP)32 b Fr(whose)c(v)-5 b(alue)28 b(is)g(TR)m(UE,)g(then)f (w)m(ords)g(that)h(w)m(ere)150 2403 y(created)34 b(using)e(bac)m (kslash)h(or)f(v)m(ertical)j(bar)d(\(to)h(include)g(c)m(haracters)h (that)f(w)m(ould)f(otherwise)h(not)g(b)s(e)150 2513 y(treated)f(as)g (part)f(of)g(a)h(w)m(ord\))f(are)h(prin)m(ted)e(with)h(the)h(bac)m (kslashes)g(or)f(v)m(ertical)i(bars)e(sho)m(wn,)g(so)g(that)150 2622 y(the)j(prin)m(ted)f(result)g(could)g(b)s(e)g(re-read)h(b)m(y)f (Logo)h(to)h(pro)s(duce)d(the)h(same)h(v)-5 b(alue.)51 b(If)33 b(FULLPRINTP)150 2732 y(is)f(TR)m(UE)g(then)g(the)g(empt)m(y)g (w)m(ord)g(\(ho)m(w)m(ev)m(er)i(it)e(w)m(as)h(created\))g(prin)m(ts)f (as)g Fm(||)p Fr(.)45 b(\(Otherwise)32 b(it)g(prin)m(ts)150 2841 y(as)f(nothing)f(at)h(all.\))275 2976 y(See)f([FULLPRINTP],)h (page)g(89)g(.)150 3201 y Fk(prin)m(t)390 3420 y Fm(PRINT)46 b(thing)390 3530 y(PR)h(thing)390 3640 y(\(PRINT)f(thing1)g(thing2)g (...\))390 3749 y(\(PR)h(thing1)f(thing2)g(...\))275 3884 y Fr(command.)38 b(Prin)m(ts)24 b(the)h(input)f(or)g(inputs)g(to)h (the)g(curren)m(t)f(write)h(stream)g(\(initially)h(the)f(terminal\).) 150 3994 y(All)i(the)f(inputs)f(are)h(prin)m(ted)g(on)f(a)i(single)f (line,)i(separated)e(b)m(y)g(spaces,)i(ending)d(with)h(a)g(newline.)40 b(If)25 b(an)150 4103 y(input)32 b(is)i(a)g(list,)h(square)e(brac)m(k)m (ets)i(are)f(not)f(prin)m(ted)g(around)g(it,)i(but)d(brac)m(k)m(ets)j (are)f(prin)m(ted)f(around)150 4213 y(sublists.)40 b(Braces)32 b(are)e(alw)m(a)m(ys)i(prin)m(ted)e(around)f(arra)m(ys.)150 4438 y Fk(t)m(yp)s(e)390 4657 y Fm(TYPE)47 b(thing)390 4767 y(\(TYPE)f(thing1)g(thing2)h(...\))275 4902 y Fr(command.)k(Prin)m (ts)33 b(the)h(input)f(or)h(inputs)f(lik)m(e)i(PRINT,)f(except)g(that)h (no)f(newline)f(c)m(haracter)j(is)150 5011 y(prin)m(ted)c(at)g(the)h (end)e(and)h(m)m(ultiple)h(inputs)e(are)h(not)g(separated)h(b)m(y)f (spaces.)46 b(Note:)g(prin)m(ting)32 b(to)h(the)150 5121 y(terminal)39 b(is)g(ordinarily)g Fm(")p Fr(line)g(bu\013ered)p Fm(")p Fr(;)j(that)d(is,)j(the)d(c)m(haracters)h(y)m(ou)f(prin)m(t)g (using)f(TYPE)h(will)150 5230 y(not)33 b(actually)h(app)s(ear)e(on)g (the)h(screen)f(un)m(til)h(either)g(a)g(newline)f(c)m(haracter)i(is)e (prin)m(ted)g(\(for)h(example,)150 5340 y(b)m(y)38 b(PRINT)f(or)i(SHO)m (W\))f(or)g(Logo)h(tries)g(to)g(read)f(from)f(the)i(k)m(eyb)s(oard)f (\(either)h(at)f(the)h(request)f(of)p eop end %%Page: 20 21 TeXDict begin 20 20 bop 150 -116 a Fr(20)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y(y)m(our)39 b(program)h(or)f(after)h(an)f (instruction)g(prompt\).)68 b(This)38 b(bu\013ering)h(mak)m(es)h(the)g (program)f(m)m(uc)m(h)150 408 y(faster)44 b(than)f(it)h(w)m(ould)f(b)s (e)g(if)g(eac)m(h)i(c)m(haracter)g(app)s(eared)d(immediately)-8 b(,)49 b(and)43 b(in)g(most)g(cases)i(the)150 518 y(e\013ect)f(is)e (not)h(disconcerting.)77 b(T)-8 b(o)42 b(accommo)s(date)j(programs)c (that)i(do)f(a)h(lot)g(of)g(p)s(ositioned)f(text)150 628 y(displa)m(y)g(using)f(TYPE,)h(Logo)h(will)f(force)g(prin)m(ting)g (whenev)m(er)f(SETCURSOR)f(is)h(in)m(v)m(ok)m(ed.)77 b(This)150 737 y(solv)m(es)38 b(most)f(bu\013ering)f(problems.)60 b(Still,)39 b(on)e(o)s(ccasion)h(y)m(ou)f(ma)m(y)h(\014nd)d(it)i (necessary)h(to)f(force)h(the)150 847 y(bu\013ered)d(c)m(haracters)j (to)e(b)s(e)g(prin)m(ted)f(explicitly;)41 b(this)36 b(can)h(b)s(e)e (done)h(using)g(the)g(W)-10 b(AIT)36 b(command.)150 956 y Fm(WAIT)47 b(0)30 b Fr(will)g(force)h(prin)m(ting)g(without)f (actually)i(w)m(aiting.)275 1087 y(See)e([SETCURSOR],)f(page)i(26)g(,)g ([W)-10 b(AIT],)31 b(page)g(71)150 1299 y Fk(sho)m(w)390 1518 y Fm(SHOW)47 b(thing)390 1628 y(\(SHOW)f(thing1)g(thing2)h(...\)) 275 1758 y Fr(command.)g(Prin)m(ts)32 b(the)h(input)e(or)i(inputs)f (lik)m(e)h(PRINT,)g(except)g(that)g(if)g(an)f(input)g(is)h(a)g(list)g (it)g(is)150 1868 y(prin)m(ted)d(inside)g(square)g(brac)m(k)m(ets.)275 1998 y(See)g([PRINT],)h(page)g(19)g(.)150 2244 y Fq(3.2)68 b(Receiv)l(ers)150 2565 y Fk(readlist)390 2785 y Fm(READLIST)390 2894 y(RL)275 3025 y Fr(reads)40 b(a)h(line)g(from)f(the)h(read)f (stream)h(\(initially)i(the)e(terminal\))g(and)f(outputs)g(that)i(line) f(as)g(a)150 3134 y(list.)51 b(The)33 b(line)h(is)f(separated)i(in)m (to)f(mem)m(b)s(ers)f(as)h(though)f(it)h(w)m(ere)g(t)m(yp)s(ed)f(in)g (square)h(brac)m(k)m(ets)h(in)e(an)150 3244 y(instruction.)42 b(If)30 b(the)h(read)g(stream)g(is)g(a)g(\014le,)h(and)e(the)h(end)f (of)h(\014le)g(is)g(reac)m(hed,)h(READLIST)d(outputs)150 3354 y(the)38 b(empt)m(y)g(w)m(ord)f(\(not)h(the)g(empt)m(y)g(list\).) 63 b(READLIST)36 b(pro)s(cesses)i(bac)m(kslash,)i(v)m(ertical)f(bar,)h (and)150 3463 y(tilde)f(c)m(haracters)g(in)e(the)h(read)g(stream;)k (the)d(output)e(list)h(will)h(not)f(con)m(tain)h(these)f(c)m(haracters) i(but)150 3573 y(they)33 b(will)h(ha)m(v)m(e)g(had)e(their)h(usual)g (e\013ect.)50 b(READLIST)32 b(do)s(es)h(not,)h(ho)m(w)m(ev)m(er,)i (treat)e(semicolon)g(as)g(a)150 3682 y(commen)m(t)d(c)m(haracter.)150 3894 y Fk(readw)m(ord)390 4114 y Fm(READWORD)390 4223 y(RW)275 4354 y Fr(reads)25 b(a)h(line)g(from)f(the)g(read)h(stream)g (and)e(outputs)h(that)i(line)e(as)h(a)g(w)m(ord.)39 b(The)25 b(output)g(is)g(a)h(single)150 4463 y(w)m(ord)c(ev)m(en)i(if)f(the)g (line)g(con)m(tains)h(spaces,)h(brac)m(k)m(ets,)h(etc.)39 b(If)23 b(the)g(read)f(stream)i(is)e(a)i(\014le,)g(and)f(the)g(end)f (of)150 4573 y(\014le)31 b(is)g(reac)m(hed,)g(READ)m(W)m(ORD)i(outputs) d(the)h(empt)m(y)g(list)g(\(not)g(the)g(empt)m(y)g(w)m(ord\).)42 b(READ)m(W)m(ORD)150 4682 y(pro)s(cesses)32 b(bac)m(kslash,)i(v)m (ertical)h(bar,)e(and)f(tilde)h(c)m(haracters)h(in)f(the)f(read)h (stream.)48 b(In)31 b(the)i(case)h(of)f(a)150 4792 y(tilde)i(used)e (for)h(line)h(con)m(tin)m(uation,)i(the)d(output)g(w)m(ord)g(DOES)f (include)h(the)g(tilde)h(and)f(the)g(newline)150 4902 y(c)m(haracters,)i(so)d(that)h(the)f(user)f(program)h(can)h(tell)g (exactly)h(what)e(the)g(user)g(en)m(tered.)49 b(V)-8 b(ertical)36 b(bars)150 5011 y(in)42 b(the)g(line)g(are)g(also)h (preserv)m(ed)f(in)f(the)h(output.)75 b(Bac)m(kslash)44 b(c)m(haracters)f(are)g(not)f(preserv)m(ed)f(in)150 5121 y(the)33 b(output,)g(but)f(the)h(c)m(haracter)h(follo)m(wing)g(the)f (bac)m(kslash)h(has)e(128)i(added)e(to)i(its)f(represen)m(tation.)150 5230 y(Programs)c(can)h(use)f(BA)m(CKSLASHEDP)g(to)h(c)m(hec)m(k)h(for) e(this)g(co)s(de.)41 b(\(Bac)m(kslashedness)31 b(is)e(preserv)m(ed)150 5340 y(only)h(for)h(certain)g(c)m(haracters.\))p eop end %%Page: 21 22 TeXDict begin 21 21 bop 150 -116 a Fr(Chapter)30 b(3:)41 b(Comm)m(unication)2416 b(21)275 299 y(See)30 b([BA)m(CKSLASHEDP],)h (page)g(16)g(.)150 526 y Fk(readra)m(wline)390 746 y Fm(READRAWLINE)275 882 y Fr(reads)39 b(a)g(line)h(from)f(the)g(read)g (stream)h(and)e(outputs)h(that)h(line)g(as)f(a)h(w)m(ord.)67 b(The)38 b(output)h(is)h(a)150 991 y(single)33 b(w)m(ord)g(ev)m(en)g (if)g(the)f(line)h(con)m(tains)h(spaces,)g(brac)m(k)m(ets,)h(etc.)49 b(If)32 b(the)h(read)f(stream)h(is)g(a)g(\014le,)h(and)150 1101 y(the)f(end)f(of)h(\014le)f(is)h(reac)m(hed,)h(READRA)-10 b(WLINE)33 b(outputs)f(the)h(empt)m(y)g(list)h(\(not)f(the)g(empt)m(y)g (w)m(ord\).)150 1210 y(READRA)-10 b(WLINE)28 b(outputs)f(the)h(exact)h (string)e(of)h(c)m(haracters)h(as)f(they)f(app)s(ear)g(in)g(the)h (line,)h(with)e(no)150 1320 y(sp)s(ecial)k(meaning)g(for)f(bac)m (kslash,)h(v)m(ertical)i(bar,)d(tilde,)h(or)f(an)m(y)h(other)g (formatting)g(c)m(haracters.)275 1456 y(See)f([READ)m(W)m(ORD],)j(page) e(20)g(.)150 1684 y Fk(readc)m(har)390 1903 y Fm(READCHAR)390 2012 y(RC)275 2149 y Fr(reads)g(a)i(single)f(c)m(haracter)i(from)d(the) h(read)g(stream)g(and)g(outputs)f(that)h(c)m(haracter)i(as)e(a)g(w)m (ord.)45 b(If)150 2258 y(the)36 b(read)h(stream)f(is)h(a)f(\014le,)i (and)e(the)g(end)g(of)g(\014le)h(is)f(reac)m(hed,)j(READCHAR)d(outputs) g(the)h(empt)m(y)150 2368 y(list)j(\(not)h(the)e(empt)m(y)i(w)m(ord\).) 68 b(If)39 b(the)h(read)g(stream)g(is)g(a)g(terminal,)j(ec)m(hoing)e (is)e(turned)g(o\013)h(when)150 2477 y(READCHAR)32 b(is)g(in)m(v)m(ok)m (ed,)i(and)d(remains)h(o\013)g(un)m(til)g(READLIST)f(or)h(READ)m(W)m (ORD)i(is)e(in)m(v)m(ok)m(ed)h(or)150 2587 y(a)41 b(Logo)h(prompt)e(is) h(prin)m(ted.)71 b(Bac)m(kslash,)46 b(v)m(ertical)d(bar,)g(and)d(tilde) h(c)m(haracters)i(ha)m(v)m(e)f(no)e(sp)s(ecial)150 2697 y(meaning)31 b(in)f(this)g(con)m(text.)275 2833 y(See)g([READLIST],)g (page)i(20)f(.)150 3060 y Fk(readc)m(hars)390 3279 y Fm(READCHARS)45 b(num)390 3389 y(RCS)i(num)275 3525 y Fr(reads)34 b Fm(num)g Fr(c)m(haracters)i(from)e(the)h(read)g(stream)g (and)f(outputs)g(those)h(c)m(haracters)h(as)f(a)g(w)m(ord.)53 b(If)150 3635 y(the)33 b(read)h(stream)f(is)g(a)h(\014le,)g(and)f(the)g (end)g(of)g(\014le)g(is)h(reac)m(hed,)g(READCHARS)f(outputs)g(the)h (empt)m(y)150 3744 y(list)40 b(\(not)h(the)e(empt)m(y)i(w)m(ord\).)68 b(If)39 b(the)h(read)g(stream)g(is)g(a)g(terminal,)j(ec)m(hoing)e(is)e (turned)g(o\013)h(when)150 3854 y(READCHARS)d(is)h(in)m(v)m(ok)m(ed,)i (and)d(remains)g(o\013)h(un)m(til)g(READLIST)e(or)i(READ)m(W)m(ORD)h (is)e(in)m(v)m(ok)m(ed)150 3963 y(or)c(a)h(Logo)h(prompt)d(is)i(prin)m (ted.)49 b(Bac)m(kslash,)36 b(v)m(ertical)g(bar,)e(and)e(tilde)j(c)m (haracters)f(ha)m(v)m(e)h(no)e(sp)s(ecial)150 4073 y(meaning)e(in)f (this)g(con)m(text.)275 4209 y(See)g([READLIST],)g(page)i(20)f(,)f ([READ)m(W)m(ORD],)j(page)e(20)150 4437 y Fk(shell)390 4656 y Fm(SHELL)46 b(command)390 4765 y(\(SHELL)g(command)g(wordflag\)) 275 4902 y Fr(Under)25 b(Unix,)i(outputs)f(the)h(result)f(of)h(running) d Fm(command)h Fr(as)h(a)h(shell)g(command.)39 b(\(The)26 b(command)150 5011 y(is)k(sen)m(t)h(to)g(`)p Fm(/bin/sh)p Fr(',)e(not)h(`)p Fm(csh)p Fr(')g(or)g(other)g(alternativ)m(es.\))43 b(If)30 b(the)g(command)g(is)g(a)h(literal)g(list)g(in)f(the)150 5121 y(instruction)e(line,)h(and)e(if)h(y)m(ou)h(w)m(an)m(t)f(a)h(bac)m (kslash)f(c)m(haracter)i(sen)m(t)e(to)h(the)f(shell,)h(y)m(ou)f(m)m (ust)g(use)g Fm(\\\\)f Fr(to)150 5230 y(get)h(the)f(bac)m(kslash)h (through)e(Logo's)i(reader)f(in)m(tact.)41 b(The)27 b(output)f(is)h(a)g (list)h(con)m(taining)g(one)g(mem)m(b)s(er)150 5340 y(for)k(eac)m(h)i (line)f(generated)h(b)m(y)e(the)h(shell)g(command.)47 b(Ordinarily)32 b(eac)m(h)i(suc)m(h)e(line)h(is)f(represen)m(ted)h(b)m (y)p eop end %%Page: 22 23 TeXDict begin 22 22 bop 150 -116 a Fr(22)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y(a)36 b(list)h(in)f(the)g(output,)h(as)f(though)g (the)g(line)h(w)m(ere)f(read)g(using)f(READLIST.)h(If)f(a)i(second)f (input)f(is)150 408 y(giv)m(en,)c(regardless)f(of)f(the)h(v)-5 b(alue)30 b(of)g(the)f(input,)g(eac)m(h)i(line)f(is)g(represen)m(ted)f (b)m(y)g(a)h(w)m(ord)f(in)h(the)f(output)150 518 y(as)i(though)f(it)h (w)m(ere)f(read)h(with)f(READ)m(W)m(ORD.)i(Example:)390 654 y Fm(to)47 b(dayofweek)390 763 y(output)f(first)g(first)h(shell)f ([date])390 873 y(end)275 1008 y Fr(This)23 b(is)h Fm(")p Fr(\014rst)f(\014rst)p Fm(")g Fr(to)i(extract)h(the)e(\014rst)f(w)m (ord)h(of)g(the)h(\014rst)e(\(and)h(only\))h(line)f(of)g(the)h(shell)f (output.)275 1144 y(Under)43 b(DOS,)h(SHELL)g(is)g(a)h(command,)j(not)d (an)f(op)s(eration;)52 b(it)45 b(sends)f(its)h(input)e(to)j(a)e(DOS)150 1253 y(command)30 b(pro)s(cessor)g(but)g(do)s(es)g(not)g(collect)j(the) e(result)f(of)h(the)f(command.)275 1389 y(The)24 b(Macin)m(tosh,)29 b(of)c(course,)i(is)f(not)f(programmable)h(\(unless)f(y)m(ou)h(are)g (running)e(the)h(Unix)g(v)m(ersion)150 1499 y(of)31 b(UCBLogo)g(under)e (OS)h(X\).)150 1759 y Fq(3.3)68 b(File)46 b(Access)150 2094 y Fk(setpre\014x)390 2314 y Fm(SETPREFIX)f(string)275 2449 y Fr(command.)80 b(Sets)43 b(a)h(pre\014x)e(that)j(will)e(b)s(e)g (used)g(as)h(the)g(implicit)g(b)s(eginning)f(of)h(\014lenames)f(in)150 2559 y(OPENREAD,)32 b(OPENWRITE,)f(OPENAPPEND,)g(OPENUPD)m(A)-8 b(TE,)33 b(LO)m(AD,)f(and)f(SA)-10 b(VE)31 b(com-)150 2668 y(mands.)63 b(Logo)39 b(will)g(put)e(the)i(appropriate)f (separator)h(c)m(haracter)h(\(slash)e(for)g(Unix,)i(bac)m(kslash)f(for) 150 2778 y(DOS/Windo)m(ws,)29 b(colon)f(for)g(MacOS\))g(b)s(et)m(w)m (een)g(the)g(pre\014x)f(and)g(the)h(\014lename)g(en)m(tered)g(b)m(y)g (the)f(user.)150 2888 y(The)d(input)g(to)i(SETPREFIX)e(m)m(ust)h(b)s(e) f(a)h(w)m(ord,)h(unless)e(it)i(is)e(the)i(empt)m(y)f(list,)i(to)e (indicate)h(that)g(there)150 2997 y(should)j(b)s(e)h(no)g(pre\014x.)275 3133 y(See)44 b([OPENREAD],)h(page)g(22)g(,)j(See)c([OPENWRITE],)g (page)h(22)g(,)j(See)c([OPENAPPEND],)150 3242 y(page)31 b(23)g(,)g(See)g([OPENUPD)m(A)-8 b(TE],)31 b(page)g(23)h(,)e(See)h([LO) m(AD],)g(page)h(63)f(,)f(See)h([SA)-10 b(VE],)31 b(page)g(63)g(.)150 3469 y Fk(pre\014x)390 3688 y Fm(PREFIX)275 3823 y Fr(outputs)e(the)i (curren)m(t)f(\014le)h(pre\014x,)e(or)h([])h(if)g(there)f(is)h(no)f (pre\014x.)275 3959 y(See)g([SETPREFIX],)g(page)h(22)h(.)150 4185 y Fk(op)s(enread)390 4404 y Fm(OPENREAD)46 b(filename)275 4540 y Fr(command.)84 b(Op)s(ens)44 b(the)h(named)g(\014le)g(for)g (reading.)85 b(The)45 b(read)g(p)s(osition)g(is)g(initially)i(at)f(the) 150 4649 y(b)s(eginning)30 b(of)g(the)h(\014le.)150 4876 y Fk(op)s(en)m(write)390 5095 y Fm(OPENWRITE)45 b(filename)275 5230 y Fr(command.)g(Op)s(ens)30 b(the)i(named)g(\014le)g(for)f (writing.)46 b(If)31 b(the)h(\014le)g(already)h(existed,)g(the)f(old)g (v)m(ersion)150 5340 y(is)e(deleted)i(and)d(a)i(new,)f(empt)m(y)h (\014le)f(created.)p eop end %%Page: 23 24 TeXDict begin 23 23 bop 150 -116 a Fr(Chapter)30 b(3:)41 b(Comm)m(unication)2416 b(23)275 299 y(OPENWRITE,)37 b(but)g(not)h(the)g(other)g(OPEN)f(v)-5 b(arian)m(ts,)41 b(will)d(accept)h(as)f(input)f(a)h(t)m(w)m(o-elemen)m(t)150 408 y(list,)31 b(in)e(whic)m(h)g(the)h(\014rst)e(elemen)m(t)j(m)m(ust)f (b)s(e)f(a)g(v)-5 b(ariable)31 b(name,)f(and)f(the)g(second)h(m)m(ust)f (b)s(e)g(a)h(p)s(ositiv)m(e)150 518 y(in)m(teger.)64 b(A)37 b(c)m(haracter)i(bu\013er)e(of)h(the)f(sp)s(eci\014ed)g(size)h (will)g(b)s(e)f(created.)63 b(When)38 b(a)g(SETWRITE)e(is)150 628 y(done)30 b(with)g(this)h(same)f(list)h(\(in)g(the)f(sense)h(of)f (.EQ,)h(not)f(a)h(cop)m(y)-8 b(,)32 b(so)e(y)m(ou)h(m)m(ust)f(do)h (something)f(lik)m(e)390 756 y Fm(?)47 b(make)g("buf)g([foo)f(100])390 865 y(?)h(openwrite)f(:buf)390 975 y(?)h(setwrite)f(:buf)581 1085 y([...])390 1194 y(?)h(close)g(:buf)275 1322 y Fr(and)29 b(not)i(just)390 1450 y Fm(?)47 b(openwrite)f([foo)g(100])390 1560 y(?)h(setwrite)f([foo)h(100])275 1688 y Fr(and)28 b(so)i(on\),)g(the)g(prin)m(ted)f(c)m(haracters)i(are)f(stored)g(in)f (the)h(bu\013er;)f(when)f(a)i(CLOSE)e(is)i(done)f(with)150 1798 y(the)38 b(same)h(list)g(as)f(input,)i(the)e(c)m(haracters)i(from) d(the)i(bu\013er)e(\(treated)i(as)g(one)f(long)h(w)m(ord,)h(ev)m(en)f (if)150 1907 y(spaces)31 b(and)f(newlines)g(are)g(included\))g(b)s (ecome)h(the)g(v)-5 b(alue)31 b(of)f(the)h(sp)s(eci\014ed)e(v)-5 b(ariable.)150 2112 y Fk(op)s(enapp)s(end)390 2331 y Fm(OPENAPPEND)45 b(filename)275 2459 y Fr(command.)39 b(Op)s(ens)26 b(the)i(named)f(\014le)h(for)f(writing.)40 b(If)27 b(the)h(\014le)f(already)h(exists,)h(the)f(write)g(p)s(osition) 150 2569 y(is)i(initially)i(set)f(to)g(the)g(end)f(of)g(the)h(old)f (\014le,)h(so)g(that)g(newly)f(written)g(data)h(will)g(b)s(e)f(app)s (ended)e(to)j(it.)150 2774 y Fk(op)s(en)m(up)s(date)390 2993 y Fm(OPENUPDATE)45 b(filename)275 3121 y Fr(command.)j(Op)s(ens)32 b(the)h(named)g(\014le)g(for)g(reading)g(and)f(writing.)49 b(The)33 b(read)g(and)g(write)g(p)s(osition)150 3231 y(is)f(initially)h(set)f(to)h(the)f(end)f(of)g(the)h(old)g(\014le,)h (if)e(an)m(y)-8 b(.)46 b(Note:)f(eac)m(h)32 b(op)s(en)f(\014le)h(has)g (only)g(one)g(p)s(osition,)150 3340 y(for)g(b)s(oth)g(reading)g(and)g (writing.)46 b(If)32 b(a)h(\014le)f(op)s(ened)g(for)g(up)s(date)f(is)i (b)s(oth)e(READER)i(and)e(WRITER)150 3450 y(at)d(the)g(same)f(time,)i (then)f(SETREADPOS)d(will)j(also)g(a\013ect)h(WRITEPOS)d(and)h(vice)i (v)m(ersa.)40 b(Also,)29 b(if)150 3560 y(y)m(ou)h(alternate)h(reading)f (and)f(writing)h(the)g(same)g(\014le,)g(y)m(ou)g(m)m(ust)f(SETREADPOS)f (b)s(et)m(w)m(een)j(a)f(write)150 3669 y(and)g(a)h(read,)f(and)g (SETWRITEPOS)e(b)s(et)m(w)m(een)j(a)g(read)f(and)g(a)h(write.)275 3797 y(See)44 b([READER],)g(page)h(25)g(,)i([WRITER],)d(page)h(25)f(,)k ([SETREADPOS],)43 b(page)h(25)h(,)i([SET-)150 3907 y(WRITEPOS],)30 b(page)h(25)150 4112 y Fk(close)390 4331 y Fm(CLOSE)46 b(filename)275 4459 y Fr(command.)40 b(Closes)29 b(the)h(named)f (\014le.)40 b(If)29 b(the)g(\014le)h(w)m(as)f(curren)m(tly)g(the)h (reader)f(or)g(writer,)h(then)f(the)150 4569 y(reader)37 b(or)f(writer)h(is)f(c)m(hanged)h(to)h(the)f(k)m(eyb)s(oard)f(or)h (screen,)h(as)f(if)g Fm(SETREAD)45 b([])36 b Fr(or)h Fm(SETWRITE)46 b([])150 4678 y Fr(had)30 b(b)s(een)f(done.)150 4883 y Fk(allop)s(en)390 5102 y Fm(ALLOPEN)275 5230 y Fr(outputs)34 b(a)i(list)g(whose)f(mem)m(b)s(ers)f(are)i(the)g(names)f (of)g(all)h(\014les)g(curren)m(tly)f(op)s(en.)55 b(This)34 b(list)i(do)s(es)150 5340 y(not)31 b(include)f(the)g(dribble)g(\014le,) g(if)h(an)m(y)-8 b(.)p eop end %%Page: 24 25 TeXDict begin 24 24 bop 150 -116 a Fr(24)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(closeall)390 518 y Fm(CLOSEALL)46 b(\(library)f(procedure\))275 650 y Fr(command.)40 b(Closes)31 b(all)g(op)s(en)f(\014les.)40 b(Abbreviates)31 b Fm(FOREACH)46 b(ALLOPEN)g([CLOSE)g(?])275 783 y Fr(See)30 b([F)m(OREA)m(CH],)i(page)f (77)g(,)g([CLOSE],)f(page)h(23)150 1000 y Fk(erase\014le)390 1219 y Fm(ERASEFILE)45 b(filename)390 1329 y(ERF)i(filename)275 1461 y Fr(command.)38 b(Erases)25 b(\(deletes,)j(remo)m(v)m(es\))e(the) g(named)e(\014le,)i(whic)m(h)f(should)f(not)h(curren)m(tly)g(b)s(e)f (op)s(en.)150 1679 y Fk(dribble)390 1898 y Fm(DRIBBLE)46 b(filename)275 2030 y Fr(command.)g(Creates)33 b(a)f(new)g(\014le)g (whose)g(name)h(is)f(the)g(input,)h(lik)m(e)g(OPENWRITE,)f(and)f(b)s (egins)150 2140 y(recording)f(in)f(that)i(\014le)f(ev)m(erything)g (that)h(is)e(read)h(from)f(the)h(k)m(eyb)s(oard)g(or)g(written)g(to)g (the)g(terminal.)150 2250 y(That)37 b(is,)h(this)f(writing)f(is)h(in)f (addition)h(to)h(the)f(writing)f(to)i(WRITER.)e(The)g(in)m(ten)m(t)i (is)f(to)g(create)i(a)150 2359 y(transcript)30 b(of)h(a)f(Logo)i (session,)f(including)f(things)g(lik)m(e)i(prompt)d(c)m(haracters)j (and)e(in)m(teractions.)275 2491 y(See)g([OPENWRITE],)h(page)g(22)g(,)f ([WRITER],)h(page)g(25)150 2709 y Fk(no)s(dribble)390 2928 y Fm(NODRIBBLE)275 3061 y Fr(command.)40 b(Stops)30 b(cop)m(ying)h(information)g(in)m(to)g(the)g(dribble)e(\014le,)i(and)f (closes)h(the)g(\014le.)150 3278 y Fk(setread)390 3497 y Fm(SETREAD)46 b(filename)275 3630 y Fr(command.)59 b(Mak)m(es)38 b(the)e(named)h(\014le)f(the)h(read)f(stream,)j(used)d (for)g(READLIST,)g(etc.)61 b(The)36 b(\014le)150 3739 y(m)m(ust)28 b(already)g(b)s(e)g(op)s(en)f(with)h(OPENREAD)g(or)g (OPENUPD)m(A)-8 b(TE.)29 b(If)e(the)h(input)f(is)h(the)h(empt)m(y)f (list,)150 3849 y(then)33 b(the)g(read)f(stream)i(b)s(ecomes)f(the)g (terminal,)h(as)f(usual.)48 b(Changing)32 b(the)h(read)g(stream)g(do)s (es)g(not)150 3958 y(close)27 b(the)f(\014le)g(that)h(w)m(as)f (previously)g(the)g(read)g(stream,)i(so)e(it)g(is)g(p)s(ossible)g(to)g (alternate)i(b)s(et)m(w)m(een)f(\014les.)275 4091 y(See)j([READLIST],)g (page)i(20)f(,)f([OPENREAD],)h(page)h(22)f(,)f([OPENUPD)m(A)-8 b(TE],)32 b(page)f(23)150 4308 y Fk(set)m(write)390 4527 y Fm(SETWRITE)46 b(filename)275 4660 y Fr(command.)f(Mak)m(es)33 b(the)f(named)g(\014le)g(the)g(write)g(stream,)h(used)e(for)h(PRINT,)f (etc.)47 b(The)31 b(\014le)h(m)m(ust)150 4769 y(already)g(b)s(e)f(op)s (en)g(with)h(OPENWRITE,)f(OPENAPPEND,)h(or)f(OPENUPD)m(A)-8 b(TE.)33 b(If)e(the)h(input)f(is)150 4879 y(the)i(empt)m(y)f(list,)i (then)e(the)h(write)f(stream)h(b)s(ecomes)g(the)f(terminal,)i(as)f (usual.)46 b(Changing)32 b(the)h(write)150 4988 y(stream)42 b(do)s(es)f(not)g(close)i(the)e(\014le)h(that)f(w)m(as)h(previously)f (the)h(write)f(stream,)k(so)c(it)h(is)f(p)s(ossible)g(to)150 5098 y(alternate)32 b(b)s(et)m(w)m(een)f(\014les.)275 5230 y(If)f(the)h(input)f(is)g(a)h(list,)h(then)f(its)g(\014rst)f (elemen)m(t)i(m)m(ust)f(b)s(e)f(a)h(v)-5 b(ariable)31 b(name,)g(and)g(its)g(second)g(and)150 5340 y(last)h(elemen)m(t)h(m)m (ust)d(b)s(e)h(a)g(p)s(ositiv)m(e)h(in)m(teger;)i(a)d(bu\013er)f(of)h (that)h(man)m(y)f(c)m(haracters)i(will)e(b)s(e)g(allo)s(cated,)p eop end %%Page: 25 26 TeXDict begin 25 25 bop 150 -116 a Fr(Chapter)30 b(3:)41 b(Comm)m(unication)2416 b(25)150 299 y(and)31 b(will)g(b)s(ecome)h(the) f(writestream.)44 b(If)31 b(the)g(same)h(list)g(\(same)g(in)f(the)g (.EQ)g(sense,)h(not)f(a)h(cop)m(y\))g(has)150 408 y(b)s(een)j(used)f (as)i(input)f(to)h(OPENWRITE,)f(then)g(the)h(already-allo)s(cated)i (bu\013er)d(will)g(b)s(e)g(used,)i(and)150 518 y(the)c(writer)g(can)g (b)s(e)f(c)m(hanged)h(to)h(and)e(from)g(this)h(bu\013er,)f(with)h(all)g (the)g(c)m(haracters)i(accum)m(ulated)f(as)150 628 y(in)e(a)g(\014le.) 45 b(When)32 b(the)g(same)g(list)g(is)g(used)f(as)h(input)f(to)i (CLOSE,)d(the)i(con)m(ten)m(ts)i(of)e(the)g(bu\013er)f(\(as)h(an)150 737 y(unparsed)27 b(w)m(ord,)h(whic)m(h)g(ma)m(y)h(con)m(tain)h (newline)e(c)m(haracters\))i(will)f(b)s(ecome)g(the)f(v)-5 b(alue)29 b(of)g(the)f(named)150 847 y(v)-5 b(ariable.)50 b(F)-8 b(or)34 b(compatibilit)m(y)h(with)e(earlier)h(v)m(ersions,)g(if) f(the)h(list)g(has)e(not)i(b)s(een)e(op)s(ened)h(when)f(the)150 956 y(SETWRITE)g(is)i(done,)h(it)f(will)g(b)s(e)f(op)s(ened)g (implicitly)-8 b(,)36 b(but)d(the)h(\014rst)f(SETWRITE)f(after)i(this)g (one)150 1066 y(will)d(implicitly)g(close)h(it,)f(setting)h(the)e(v)-5 b(ariable)31 b(and)f(freeing)h(the)f(allo)s(cated)j(bu\013er.)275 1200 y(See)56 b([PRINT],)g(page)h(19)f(,)63 b([OPENWRITE],)56 b(page)h(22)g(;)68 b([OPENAPPEND],)57 b(page)g(23)g(;)150 1310 y([OPENUPD)m(A)-8 b(TE],)32 b(page)f(23)150 1533 y Fk(reader)390 1753 y Fm(READER)275 1887 y Fr(outputs)e(the)h(name)g (of)g(the)h(curren)m(t)e(read)h(stream)h(\014le,)f(or)g(the)g(empt)m(y) h(list)f(if)g(the)h(read)f(stream)g(is)150 1996 y(the)h(terminal.)150 2220 y Fk(writer)390 2439 y Fm(WRITER)275 2573 y Fr(outputs)g(the)h (name)g(of)g(the)g(curren)m(t)g(write)g(stream)g(\014le,)h(or)f(the)g (empt)m(y)g(list)h(if)e(the)h(write)h(stream)150 2683 y(is)d(the)h(terminal.)150 2906 y Fk(setreadp)s(os)390 3126 y Fm(SETREADPOS)45 b(charpos)275 3260 y Fr(command.)67 b(Sets)39 b(the)h(\014le)f(p)s(oin)m(ter)g(of)h(the)f(read)g(stream)h (\014le)f(so)h(that)g(the)f(next)h(READLIST,)150 3370 y(etc.,)d(will)d(b)s(egin)g(reading)g(at)h(the)g Fm(charpos)p Fr(th)d(c)m(haracter)k(in)e(the)g(\014le,)i(coun)m(ting)f(from)e(0.)53 b(\(That)35 b(is,)150 3479 y Fm(SETREADPOS)45 b(0)37 b Fr(will)g(start)g(reading)g(from)g(the)g(b)s(eginning)f(of)h(the)g (\014le.\))61 b(Meaningless)38 b(if)f(the)g(read)150 3589 y(stream)31 b(is)f(the)h(terminal.)275 3723 y(See)f([READLIST],)g (page)i(20)f(.)150 3947 y Fk(set)m(writep)s(os)390 4166 y Fm(SETWRITEPOS)45 b(charpos)275 4300 y Fr(command.)56 b(Sets)36 b(the)g(\014le)g(p)s(oin)m(ter)g(of)g(the)g(write)g(stream)g (\014le)g(so)g(that)g(the)g(next)g(PRINT,)f(etc.,)150 4410 y(will)48 b(b)s(egin)e(writing)i(at)g(the)f Fm(charpos)p Fr(th)e(c)m(haracter)k(in)e(the)h(\014le,)j(coun)m(ting)e(from)d(0.)92 b(\(That)48 b(is,)150 4519 y Fm(SETWRITEPOS)d(0)32 b Fr(will)g(start)h(writing)g(from)f(the)g(b)s(eginning)g(of)g(the)h (\014le.\))47 b(Meaningless)34 b(if)e(the)h(write)150 4629 y(stream)e(is)f(the)h(terminal.)275 4763 y(See)f([PRINT],)h(page)g (19)g(.)150 4987 y Fk(readp)s(os)390 5206 y Fm(READPOS)275 5340 y Fr(outputs)e(the)i(\014le)f(p)s(osition)h(of)f(the)h(curren)m(t) f(read)g(stream)h(\014le.)p eop end %%Page: 26 27 TeXDict begin 26 26 bop 150 -116 a Fr(26)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(writep)s(os)390 518 y Fm(WRITEPOS)275 652 y Fr(outputs)f(the)i(\014le)f(p)s(osition)h(of)f(the)h(curren)m(t)f (write)h(stream)f(\014le.)150 874 y Fk(eofp)390 1093 y Fm(EOFP)390 1203 y(EOF?)275 1336 y Fr(predicate,)i(outputs)e(TR)m(UE) h(if)g(there)g(are)g(no)g(more)f(c)m(haracters)j(to)e(b)s(e)g(read)f (in)h(the)g(read)g(stream)150 1446 y(\014le,)g(F)-10 b(ALSE)30 b(otherwise.)150 1668 y Fk(\014lep)390 1887 y Fm(FILEP)46 b(filename)390 1997 y(FILE?)g(filename)g(\(library)f (procedure\))275 2130 y Fr(predicate,)33 b(outputs)e(TR)m(UE)h(if)g(a)h (\014le)f(of)g(the)g(sp)s(eci\014ed)f(name)h(exists)h(and)e(can)i(b)s (e)e(read,)h(F)-10 b(ALSE)150 2240 y(otherwise.)150 2495 y Fq(3.4)68 b(T)-11 b(erminal)45 b(Access)150 2827 y Fk(k)m(eyp)390 3046 y Fm(KEYP)390 3155 y(KEY?)275 3289 y Fr(predicate,)26 b(outputs)d(TR)m(UE)g(if)h(there)f(are)h(c)m (haracters)h(w)m(aiting)g(to)g(b)s(e)e(read)g(from)g(the)h(read)f (stream.)150 3399 y(If)h(the)h(read)f(stream)h(is)f(a)h(\014le,)h(this) e(is)h(equiv)-5 b(alen)m(t)26 b(to)f Fm(NOT)47 b(EOFP)o Fr(.)38 b(If)24 b(the)h(read)f(stream)h(is)g(the)f(terminal,)150 3508 y(then)k(ec)m(hoing)j(is)d(turned)g(o\013)h(and)f(the)h(terminal)h (is)f(set)g(to)g(CBREAK)g(\(c)m(haracter)i(at)e(a)g(time)h(instead)150 3618 y(of)g(line)h(at)g(a)g(time\))g(mo)s(de.)40 b(It)31 b(remains)f(in)g(this)g(mo)s(de)g(un)m(til)g(some)h(line-mo)s(de)f (reading)h(is)f(requested)150 3728 y(\(e.g.,)h(READLIST\).)d(The)g (Unix)g(op)s(erating)h(system)f(forgets)h(ab)s(out)f(an)m(y)h(p)s (ending)e(c)m(haracters)j(when)150 3837 y(it)h(switc)m(hes)g(mo)s(des,) f(so)h(the)f(\014rst)g(KEYP)g(in)m(v)m(o)s(cation)i(will)f(alw)m(a)m (ys)h(output)e(F)-10 b(ALSE.)275 3971 y(See)30 b([EOFP],)h(page)g(26)g (,)g([READLIST],)f(page)h(20)150 4193 y Fk(cleartext)390 4412 y Fm(CLEARTEXT)390 4522 y(CT)275 4655 y Fr(command.)40 b(Clears)31 b(the)f(text)i(screen)e(of)h(the)f(terminal.)150 4877 y Fk(setcursor)390 5097 y Fm(SETCURSOR)45 b(vector)275 5230 y Fr(command.)75 b(The)42 b(input)f(is)h(a)h(list)g(of)f(t)m(w)m (o)h(n)m(um)m(b)s(ers,)h(the)f(x)f(and)f(y)h(co)s(ordinates)h(of)f(a)h (screen)150 5340 y(p)s(osition)30 b(\(origin)g(in)f(the)g(upp)s(er)f (left)i(corner,)g(p)s(ositiv)m(e)g(direction)g(is)g(southeast\).)41 b(The)29 b(screen)h(cursor)p eop end %%Page: 27 28 TeXDict begin 27 27 bop 150 -116 a Fr(Chapter)30 b(3:)41 b(Comm)m(unication)2416 b(27)150 299 y(is)36 b(mo)m(v)m(ed)h(to)g(the)f (requested)g(p)s(osition.)59 b(This)35 b(command)h(also)h(forces)f(the) h(immediate)g(prin)m(ting)f(of)150 408 y(an)m(y)31 b(bu\013ered)e(c)m (haracters.)150 633 y Fk(cursor)390 852 y Fm(CURSOR)275 986 y Fr(outputs)d(a)h(list)h(con)m(taining)g(the)f(curren)m(t)g(x)g (and)f(y)h(co)s(ordinates)g(of)g(the)g(screen)g(cursor.)39 b(Logo)28 b(ma)m(y)150 1096 y(get)36 b(confused)d(ab)s(out)h(the)h (curren)m(t)f(cursor)g(p)s(osition)g(if,)i(e.g.,)h(y)m(ou)e(t)m(yp)s(e) f(in)g(a)h(long)g(line)g(that)g(wraps)150 1205 y(around)29 b(or)i(y)m(our)f(program)g(prin)m(ts)g(escap)s(e)h(co)s(des)f(that)h (a\013ect)h(the)f(terminal)g(strangely)-8 b(.)150 1430 y Fk(setmargins)390 1649 y Fm(SETMARGINS)45 b(vector)275 1783 y Fr(command.)55 b(The)35 b(input)g(m)m(ust)g(b)s(e)g(a)h(list)g (of)g(t)m(w)m(o)g(n)m(um)m(b)s(ers,)g(as)g(for)f(SETCURSOR.)e(The)i (e\013ect)150 1893 y(is)h(to)g(clear)h(the)f(screen)g(and)f(then)g (arrange)i(for)e(all)i(further)d(prin)m(ting)i(to)g(b)s(e)f(shifted)h (do)m(wn)f(and)g(to)150 2002 y(the)28 b(righ)m(t)h(according)g(to)f (the)h(indicated)f(margins.)40 b(Sp)s(eci\014cally)-8 b(,)30 b(ev)m(ery)e(time)h(a)f(newline)g(c)m(haracter)i(is)150 2112 y(prin)m(ted)k(\(explicitly)i(or)f(implicitly\))h(Logo)f(will)g(t) m(yp)s(e)f(x)p 2130 2112 28 4 v 40 w(margin)h(spaces,)h(and)d(on)i(ev)m (ery)g(in)m(v)m(o)s(cation)150 2222 y(of)f(SETCURSOR)d(the)j(margins)f (will)h(b)s(e)e(added)h(to)h(the)g(input)f(x)g(and)g(y)g(co)s (ordinates.)51 b(\(CURSOR)150 2331 y(will)30 b(rep)s(ort)g(the)g (cursor)f(p)s(osition)h(relativ)m(e)i(to)f(the)f(margins,)g(so)h(that)f (this)g(shift)g(will)g(b)s(e)g(in)m(visible)g(to)150 2441 y(Logo)i(programs.\))41 b(The)30 b(purp)s(ose)f(of)i(this)g (command)f(is)h(to)g(accommo)s(date)i(the)e(displa)m(y)g(of)f(terminal) 150 2550 y(screens)36 b(in)g(lecture)i(halls)e(with)h(inadequate)g(TV)f (monitors)g(that)i(miss)e(the)g(top)h(and)f(left)h(edges)g(of)150 2660 y(the)31 b(screen.)275 2795 y(See)f([SETCURSOR],)f(page)i(26)g(.) 150 3019 y Fk(settextcolor)390 3238 y Fm(SETTEXTCOLOR)44 b(foreground)h(background)390 3347 y(SETTC)h(foreground)f(background) 275 3482 y Fr(Command)36 b(\(Windo)m(ws)i(and)f(DOS)g(extended)g (only\).)62 b(The)37 b(inputs)f(are)i(color)h(n)m(um)m(b)s(ers,)f(as)f (for)150 3592 y(turtle)g(graphics.)58 b(F)-8 b(uture)37 b(prin)m(ting)f(to)h(the)f(text)i(windo)m(w)d(will)i(use)f(the)h(sp)s (eci\014ed)e(colors)i(for)f(fore-)150 3701 y(ground)28 b(\(the)i(c)m(haracters)h(prin)m(ted\))e(and)g(bac)m(kground)g(\(the)h (space)g(under)e(those)i(c)m(haracters\).)42 b(Using)150 3811 y(ST)-8 b(ANDOUT)38 b(will)h(rev)m(ert)g(to)g(the)f(default)h (text)g(windo)m(w)f(colors.)65 b(In)38 b(the)h(DOS)e(extended)i (\(ucbl-)150 3920 y(ogo.exe\))i(v)m(ersion,)g(colors)e(in)f(textscreen) i(mo)s(de)d(are)i(limited)g(to)g(n)m(um)m(b)s(ers)e(0-7,)k(and)d(the)h (coloring)150 4030 y(applies)33 b(only)f(to)h(text)h(prin)m(ted)e(b)m (y)g(the)g(program,)h(not)g(to)g(the)g(ec)m(hoing)g(of)g(text)g(t)m(yp) s(ed)g(b)m(y)f(the)g(user.)150 4139 y(Neither)g(limitation)h(applies)e (to)h(the)g(text)g(p)s(ortion)f(of)g(splitscreen)h(mo)s(de,)f(whic)m(h) g(is)g(actually)i(dra)m(wn)150 4249 y(as)e(graphics)f(in)m(ternally)-8 b(.)275 4384 y(See)30 b([ST)-8 b(ANDOUT],)31 b(page)g(18)g(.)p eop end %%Page: 28 29 TeXDict begin 28 28 bop 150 -116 a Fr(28)2551 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 29 30 TeXDict begin 29 29 bop 150 -116 a Fr(Chapter)30 b(4:)41 b(Arithmetic)2613 b(29)150 299 y Fp(4)80 b(Arithmetic)150 605 y Fq(4.1)68 b(Numeric)45 b(Op)t(erations)150 917 y Fk(sum)390 1136 y Fm(SUM)i(num1)g(num2)390 1246 y(\(SUM)g(num1)f (num2)h(num3)g(...\))390 1356 y(num1)g(+)g(num2)275 1483 y Fr(outputs)29 b(the)i(sum)e(of)i(its)g(inputs.)150 1685 y Fk(di\013erence)390 1905 y Fm(DIFFERENCE)45 b(num1)i(num2)390 2014 y(num1)g(-)g(num2)275 2141 y Fr(outputs)40 b(the)i(di\013erence)g (of)g(its)g(inputs.)73 b(Min)m(us)41 b(sign)h(means)f(in\014x)g (di\013erence)h(in)f(am)m(biguous)150 2251 y(con)m(texts)d(\(when)d (preceded)h(b)m(y)g(a)h(complete)h(expression\),)g(unless)d(it)i(is)f (preceded)g(b)m(y)g(a)h(space)g(and)150 2361 y(follo)m(w)m(ed)32 b(b)m(y)e(a)h(nonspace.)41 b(\(See)31 b(also)g(MINUS.\))150 2563 y Fk(min)m(us)390 2782 y Fm(MINUS)46 b(num)390 2892 y(-)h(num)275 3019 y Fr(outputs)32 b(the)g(negativ)m(e)j(of)e(its)g (input.)46 b(Min)m(us)32 b(sign)h(means)f(unary)g(min)m(us)g(if)g(the)h (previous)f(tok)m(en)150 3129 y(is)40 b(an)g(in\014x)f(op)s(erator)h (or)g(op)s(en)f(paren)m(thesis,)k(or)d(it)g(is)g(preceded)f(b)m(y)h(a)h (space)f(and)f(follo)m(w)m(ed)j(b)m(y)e(a)150 3238 y(nonspace.)h(There) 30 b(is)g(a)h(di\013erence)g(in)f(binding)f(strength)h(b)s(et)m(w)m (een)h(the)g(t)m(w)m(o)h(forms:)390 3365 y Fm(MINUS)46 b(3)i(+)f(4)239 b(means)141 b(-\(3+4\))390 3475 y(-)47 b(3)h(+)f(4)430 b(means)141 b(\(-3\)+4)150 3678 y Fk(pro)s(duct)390 3897 y Fm(PRODUCT)46 b(num1)g(num2)390 4006 y(\(PRODUCT)g(num1)g(num2)h (num3)f(...\))390 4116 y(num1)h(*)g(num2)275 4243 y Fr(outputs)29 b(the)i(pro)s(duct)e(of)i(its)f(inputs.)150 4446 y Fk(quotien)m(t)390 4665 y Fm(QUOTIENT)46 b(num1)g(num2)390 4774 y(\(QUOTIENT)f(num\))390 4884 y(num1)i(/)g(num2)275 5011 y Fr(outputs)28 b(the)h(quotien)m(t)h (of)f(its)g(inputs.)40 b(The)28 b(quotien)m(t)i(of)f(t)m(w)m(o)h(in)m (tegers)h(is)e(an)f(in)m(teger)j(if)e(and)f(only)150 5121 y(if)e(the)h(dividend)e(is)h(a)h(m)m(ultiple)g(of)f(the)h (divisor.)39 b(\(In)26 b(other)h(w)m(ords,)g Fm(QUOTIENT)45 b(5)j(2)25 b Fr(is)i(2.5,)h(not)f(2,)h(but)150 5230 y Fm(QUOTIENT)46 b(4)h(2)33 b Fr(is)h(2,)i(not)e(2.0)g(|)g(it)g(do)s(es)g (the)g(righ)m(t)g(thing.\))51 b(With)35 b(a)f(single)g(input,)g (QUOTIENT)150 5340 y(outputs)c(the)g(recipro)s(cal)i(of)e(the)h(input.) p eop end %%Page: 30 31 TeXDict begin 30 30 bop 150 -116 a Fr(30)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(remainder)390 518 y Fm(REMAINDER)45 b(num1)i(num2)275 662 y Fr(outputs)31 b(the)i(remainder)e(on)i (dividing)e Fm(num1)h Fr(b)m(y)g Fm(num2)p Fr(;)g(b)s(oth)g(m)m(ust)g (b)s(e)f(in)m(tegers)j(and)e(the)g(result)150 771 y(is)e(an)h(in)m (teger)g(with)g(the)f(same)h(sign)f(as)h(n)m(um1.)150 1014 y Fk(mo)s(dulo)390 1233 y Fm(MODULO)46 b(num1)h(num2)275 1377 y Fr(outputs)31 b(the)i(remainder)e(on)i(dividing)e Fm(num1)h Fr(b)m(y)g Fm(num2)p Fr(;)g(b)s(oth)g(m)m(ust)g(b)s(e)f(in)m (tegers)j(and)e(the)g(result)150 1487 y(is)e(an)h(in)m(teger)g(with)g (the)f(same)h(sign)f(as)h(n)m(um2.)150 1729 y Fk(in)m(t)390 1949 y Fm(INT)47 b(num)275 2092 y Fr(outputs)27 b(its)h(input)e(with)h (fractional)j(part)d(remo)m(v)m(ed,)i(i.e.,)h(an)d(in)m(teger)i(with)f (the)f(same)h(sign)g(as)g(the)150 2202 y(input,)g(whose)g(absolute)g(v) -5 b(alue)29 b(is)f(the)g(largest)h(in)m(teger)g(less)g(than)e(or)h (equal)h(to)g(the)f(absolute)g(v)-5 b(alue)29 b(of)150 2312 y(the)i(input.)150 2554 y Fk(round)390 2773 y Fm(ROUND)46 b(num)275 2917 y Fr(outputs)29 b(the)i(nearest)g(in)m(teger)h(to)f(the) f(input.)150 3160 y Fk(sqrt)390 3379 y Fm(SQRT)47 b(num)275 3523 y Fr(outputs)29 b(the)i(square)f(ro)s(ot)h(of)f(the)h(input,)f (whic)m(h)g(m)m(ust)g(b)s(e)g(nonnegativ)m(e.)150 3766 y Fk(p)s(o)m(w)m(er)390 3985 y Fm(POWER)46 b(num1)h(num2)275 4129 y Fr(outputs)29 b Fm(num1)h Fr(to)h(the)f Fm(num2)f Fr(p)s(o)m(w)m(er.)41 b(If)30 b(n)m(um1)g(is)h(negativ)m(e,)h(then)e(n) m(um2)g(m)m(ust)h(b)s(e)e(an)i(in)m(teger.)150 4371 y Fk(exp)390 4591 y Fm(EXP)47 b(num)275 4734 y Fr(outputs)29 b(e)i(\(2.718281828)p Fm(+)p Fr(\))36 b(to)31 b(the)f(input)g(p)s(o)m (w)m(er.)150 4977 y Fk(log10)390 5196 y Fm(LOG10)46 b(num)275 5340 y Fr(outputs)29 b(the)i(common)g(logarithm)g(of)g(the)f(input.)p eop end %%Page: 31 32 TeXDict begin 31 31 bop 150 -116 a Fr(Chapter)30 b(4:)41 b(Arithmetic)2613 b(31)150 299 y Fk(ln)390 518 y Fm(LN)47 b(num)275 656 y Fr(outputs)29 b(the)i(natural)f(logarithm)i(of)e(the)h (input.)150 886 y Fk(sin)390 1105 y Fm(SIN)47 b(degrees)275 1243 y Fr(outputs)29 b(the)i(sine)f(of)h(its)g(input,)e(whic)m(h)h(is)h (tak)m(en)g(in)f(degrees.)150 1473 y Fk(radsin)390 1692 y Fm(RADSIN)46 b(radians)275 1829 y Fr(outputs)29 b(the)i(sine)f(of)h (its)g(input,)e(whic)m(h)h(is)h(tak)m(en)g(in)f(radians.)150 2060 y Fk(cos)390 2279 y Fm(COS)47 b(degrees)275 2416 y Fr(outputs)29 b(the)i(cosine)g(of)g(its)f(input,)g(whic)m(h)g(is)h (tak)m(en)g(in)f(degrees.)150 2647 y Fk(radcos)390 2866 y Fm(RADCOS)46 b(radians)275 3003 y Fr(outputs)29 b(the)i(cosine)g(of)g (its)f(input,)g(whic)m(h)g(is)h(tak)m(en)g(in)f(radians.)150 3234 y Fk(arctan)390 3453 y Fm(ARCTAN)46 b(num)390 3562 y(\(ARCTAN)g(x)h(y\))275 3700 y Fr(outputs)23 b(the)h(arctangen)m(t,)k (in)c(degrees,)i(of)e(its)h(input.)37 b(With)25 b(t)m(w)m(o)h(inputs,)e (outputs)g(the)g(arctangen)m(t)150 3809 y(of)31 b(y/x,)g(if)f(x)g(is)h (nonzero,)f(or)h(90)g(or)f({90)i(dep)s(ending)d(on)h(the)h(sign)f(of)h (y)-8 b(,)31 b(if)f(x)g(is)h(zero.)150 4040 y Fk(radarctan)390 4259 y Fm(RADARCTAN)45 b(num)390 4368 y(\(RADARCTAN)g(x)i(y\))275 4506 y Fr(outputs)23 b(the)h(arctangen)m(t,)k(in)c(radians,)h(of)f(its) h(input.)37 b(With)25 b(t)m(w)m(o)h(inputs,)e(outputs)g(the)g (arctangen)m(t)150 4616 y(of)31 b(y/x,)g(if)f(x)g(is)h(nonzero,)f(or)h (pi/2)g(or)f({pi/2)i(dep)s(ending)c(on)j(the)f(sign)h(of)f(y)-8 b(,)31 b(if)f(x)h(is)f(zero.)275 4753 y(The)f(expression)i Fm(2*\(RADARCTAN)44 b(0)j(1\))30 b Fr(can)h(b)s(e)f(used)f(to)i(get)h (the)e(v)-5 b(alue)31 b(of)g(pi.)150 4983 y Fk(iseq)390 5202 y Fm(ISEQ)47 b(from)f(to)h(\(library)f(procedure\))275 5340 y Fr(outputs)29 b(a)i(list)g(of)g(the)f(in)m(tegers)i(from)e(FR)m (OM)h(to)g(TO,)f(inclusiv)m(e.)p eop end %%Page: 32 33 TeXDict begin 32 32 bop 150 -116 a Fr(32)2551 b(BERKELEY)30 b(LOGO)g(5.5)390 299 y Fm(?)47 b(show)g(iseq)g(3)g(7)390 408 y([3)g(4)h(5)f(6)h(7])390 518 y(?)f(show)g(iseq)g(7)g(3)390 628 y([7)g(6)h(5)f(4)h(3])150 853 y Fk(rseq)390 1072 y Fm(RSEQ)f(from)f(to)h(count)g(\(library)e(procedure\))275 1207 y Fr(outputs)40 b(a)i(list)g(of)g(COUNT)e(equally)j(spaced)e (rational)i(n)m(um)m(b)s(ers)d(b)s(et)m(w)m(een)i(FR)m(OM)g(and)e(TO,) 150 1316 y(inclusiv)m(e.)390 1451 y Fm(?)47 b(show)g(rseq)g(3)g(5)h(9) 390 1561 y([3)f(3.25)g(3.5)g(3.75)f(4)i(4.25)e(4.5)h(4.75)g(5])390 1670 y(?)g(show)g(rseq)g(3)g(5)h(5)390 1780 y([3)f(3.5)g(4)h(4.5)e(5]) 150 2038 y Fq(4.2)68 b(Numeric)45 b(Predicates)150 2372 y Fk(lessp)390 2592 y Fm(LESSP)h(num1)h(num2)390 2701 y(LESS?)f(num1)h(num2)390 2811 y(num1)g(<)g(num2)275 2946 y Fr(outputs)29 b(TR)m(UE)i(if)f(its)h(\014rst)f(input)f(is)h (strictly)i(less)e(than)h(its)f(second.)150 3171 y Fk(greaterp)390 3390 y Fm(GREATERP)46 b(num1)g(num2)390 3499 y(GREATER?)g(num1)g(num2) 390 3609 y(num1)h(>)g(num2)275 3744 y Fr(outputs)29 b(TR)m(UE)i(if)f (its)h(\014rst)f(input)f(is)h(strictly)i(greater)f(than)f(its)h (second.)150 3969 y Fk(lessequalp)390 4188 y Fm(LESSEQUALP)45 b(num1)i(num2)390 4297 y(LESSEQUAL?)e(num1)i(num2)390 4407 y(num1)g(<=)g(num2)275 4542 y Fr(outputs)29 b(TR)m(UE)i(if)f(its)h (\014rst)f(input)f(is)h(less)h(than)f(or)h(equal)f(to)i(its)e(second.) 150 4767 y Fk(greaterequalp)390 4986 y Fm(GREATEREQUALP)44 b(num1)j(num2)390 5096 y(GREATEREQUAL?)d(num1)j(num2)390 5205 y(num1)g(>=)g(num2)275 5340 y Fr(outputs)29 b(TR)m(UE)i(if)f(its)h (\014rst)f(input)f(is)h(greater)i(than)e(or)g(equal)h(to)g(its)g (second.)p eop end %%Page: 33 34 TeXDict begin 33 33 bop 150 -116 a Fr(Chapter)30 b(4:)41 b(Arithmetic)2613 b(33)150 299 y Fq(4.3)68 b(Random)45 b(Num)l(b)t(ers)150 688 y Fk(random)390 907 y Fm(RANDOM)h(num)390 1017 y(\(RANDOM)g(start)g(end\))275 1179 y Fr(with)34 b(one)h(input,)f(outputs)g(a)h(random)f(nonnegativ)m(e)i(in)m(teger)g (less)f(than)f(its)h(input,)g(whic)m(h)f(m)m(ust)150 1289 y(b)s(e)c(a)g(p)s(ositiv)m(e)i(in)m(teger.)275 1451 y(With)c(t)m(w)m(o)h(inputs,)f(RANDOM)h(outputs)e(a)i(random)e(in)m (teger)i(greater)g(than)f(or)g(equal)h(to)f(the)h(\014rst)150 1561 y(input,)24 b(and)e(less)h(than)g(or)f(equal)i(to)f(the)g(second)g (input.)37 b(Both)24 b(inputs)e(m)m(ust)g(b)s(e)h(in)m(tegers,)i(and)e (the)g(\014rst)150 1670 y(m)m(ust)30 b(b)s(e)g(less)g(than)h(the)f (second.)41 b Fm(\(RANDOM)46 b(0)h(9\))30 b Fr(is)g(equiv)-5 b(alen)m(t)32 b(to)f Fm(RANDOM)46 b(10)o Fr(;)31 b Fm(\(RANDOM)46 b(3)h(8\))30 b Fr(is)150 1780 y(equiv)-5 b(alen)m(t)32 b(to)f Fm(\(RANDOM)46 b(6\)+3)o Fr(.)150 2059 y Fk(rerandom)390 2279 y Fm(RERANDOM)390 2388 y(\(RERANDOM)f(seed\))275 2550 y Fr(command.)68 b(Mak)m(es)41 b(the)f(results)g(of)g(RANDOM)g (repro)s(ducible.)68 b(Ordinarily)39 b(the)h(sequence)g(of)150 2660 y(random)g(n)m(um)m(b)s(ers)f(is)h(di\013eren)m(t)h(eac)m(h)h (time)f(Logo)g(is)g(used.)70 b(If)40 b(y)m(ou)g(need)h(the)f(same)h (sequence)g(of)150 2770 y(pseudo-random)26 b(n)m(um)m(b)s(ers)g(rep)s (eatedly)-8 b(,)29 b(e.g.)41 b(to)28 b(debug)f(a)h(program,)g(sa)m(y)g (RERANDOM)g(b)s(efore)f(the)150 2879 y(\014rst)g(in)m(v)m(o)s(cation)j (of)e(RANDOM.)h(If)f(y)m(ou)g(need)g(more)g(than)g(one)g(rep)s(eatable) h(sequence,)g(y)m(ou)f(can)g(giv)m(e)150 2989 y(RERANDOM)j(an)f(in)m (teger)i(input;)e(eac)m(h)h(p)s(ossible)f(input)f(selects)j(a)f(unique) e(sequence)i(of)g(n)m(um)m(b)s(ers.)150 3315 y Fq(4.4)68 b(Prin)l(t)45 b(F)-11 b(ormatting)150 3705 y Fk(form)390 3924 y Fm(FORM)47 b(num)g(width)f(precision)275 4086 y Fr(outputs)24 b(a)h(w)m(ord)g(con)m(taining)i(a)e(prin)m(table)g (represen)m(tation)h(of)f Fm(num)p Fr(,)h(p)s(ossibly)e(preceded)h(b)m (y)g(spaces)150 4196 y(\(and)e(therefore)h(not)f(a)h(n)m(um)m(b)s(er)e (for)h(purp)s(oses)e(of)j(p)s(erforming)e(arithmetic)i(op)s (erations\),)i(with)d(at)h(least)150 4305 y Fm(width)e Fr(c)m(haracters,)k(including)c(exactly)j Fm(precision)20 b Fr(digits)k(after)f(the)g(decimal)h(p)s(oin)m(t.)39 b(\(If)22 b Fm(precision)150 4415 y Fr(is)30 b(0)h(then)f(there)h(will) g(b)s(e)e(no)i(decimal)g(p)s(oin)m(t)f(in)g(the)h(output.\))275 4577 y(As)26 b(a)h(debugging)g(feature,)h(\()p Fm(FORM)47 b(num)g(-1)g(format)n Fr(\))27 b(will)g(prin)m(t)f(the)h(\015oating)h (p)s(oin)m(t)e Fm(num)g Fr(accord-)150 4687 y(ing)31 b(to)g(the)f(C)g(prin)m(tf)g Fm(format)p Fr(,)f(to)i(allo)m(w)390 4849 y Fm(to)47 b(hex)g(:num)390 4959 y(op)g(form)g(:num)f(-1)i ("|\04508X)e(\04508X|)390 5068 y(end)275 5230 y Fr(to)38 b(allo)m(w)i(\014nding)d(out)h(the)h(exact)g(result)f(of)h(\015oating)g (p)s(oin)m(t)f(op)s(erations.)64 b(The)38 b(precise)h(format)150 5340 y(needed)30 b(ma)m(y)h(b)s(e)f(mac)m(hine-dep)s(enden)m(t.)p eop end %%Page: 34 35 TeXDict begin 34 34 bop 150 -116 a Fr(34)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fq(4.5)68 b(Bit)l(wise)46 b(Op)t(erations)150 633 y Fk(bitand)390 852 y Fm(BITAND)g(num1)h(num2)390 961 y(\(BITAND)f(num1)g(num2)h(num3)g(...\))275 1096 y Fr(outputs)29 b(the)i(bit)m(wise)g(AND)g(of)g(its)f(inputs,)g(whic)m (h)g(m)m(ust)g(b)s(e)g(in)m(tegers.)275 1230 y(See)g([AND],)i(page)f (35)g(.)150 1455 y Fk(bitor)390 1674 y Fm(BITOR)46 b(num1)h(num2)390 1783 y(\(BITOR)f(num1)h(num2)f(num3)h(...\))275 1918 y Fr(outputs)29 b(the)i(bit)m(wise)g(OR)f(of)g(its)h(inputs,)f(whic)m (h)g(m)m(ust)g(b)s(e)g(in)m(tegers.)275 2052 y(See)g([OR],)h(page)g(35) g(.)150 2276 y Fk(bitxor)390 2496 y Fm(BITXOR)46 b(num1)h(num2)390 2605 y(\(BITXOR)f(num1)g(num2)h(num3)g(...\))275 2740 y Fr(outputs)29 b(the)i(bit)m(wise)g(EX)m(CLUSIVE)f(OR)g(of)g(its)h (inputs,)f(whic)m(h)g(m)m(ust)g(b)s(e)g(in)m(tegers.)275 2874 y(See)g([OR],)h(page)g(35)g(.)150 3098 y Fk(bitnot)390 3318 y Fm(BITNOT)46 b(num)275 3452 y Fr(outputs)29 b(the)i(bit)m(wise)g (NOT)f(of)g(its)h(input,)f(whic)m(h)g(m)m(ust)g(b)s(e)g(an)g(in)m (teger.)275 3587 y(See)g([NOT],)h(page)g(35)g(.)150 3811 y Fk(ashift)390 4030 y Fm(ASHIFT)46 b(num1)h(num2)275 4164 y Fr(outputs)32 b Fm(num1)h Fr(arithmetic-shifted)i(to)f(the)f (left)i(b)m(y)e Fm(num2)f Fr(bits.)50 b(If)33 b(n)m(um2)g(is)h(negativ) m(e,)j(the)c(shift)150 4274 y(is)d(to)i(the)e(righ)m(t)h(with)f(sign)g (extension.)42 b(The)30 b(inputs)f(m)m(ust)h(b)s(e)g(in)m(tegers.)150 4498 y Fk(lshift)390 4717 y Fm(LSHIFT)46 b(num1)h(num2)275 4852 y Fr(outputs)30 b Fm(num1)f Fr(logical-shifted)k(to)f(the)e(left)i (b)m(y)e Fm(num2)g Fr(bits.)41 b(If)30 b(n)m(um2)h(is)f(negativ)m(e,)j (the)e(shift)g(is)f(to)150 4961 y(the)h(righ)m(t)g(with)f(zero)h (\014ll.)40 b(The)30 b(inputs)g(m)m(ust)g(b)s(e)g(in)m(tegers.)p eop end %%Page: 35 36 TeXDict begin 35 35 bop 150 -116 a Fr(Chapter)30 b(5:)41 b(Logical)32 b(Op)s(erations)2292 b(35)150 299 y Fp(5)80 b(Logical)53 b(Op)t(erations)150 623 y Fk(and)390 842 y Fm(AND)47 b(tf1)g(tf2)390 951 y(\(AND)g(tf1)g(tf2)f(tf3)h(...\))275 1086 y Fr(outputs)38 b(TR)m(UE)h(if)g(all)h(inputs)e(are)h(TR)m(UE,)h (otherwise)f(F)-10 b(ALSE.)39 b(All)h(inputs)e(m)m(ust)h(b)s(e)f(TR)m (UE)150 1196 y(or)i(F)-10 b(ALSE.)39 b(\(Comparison)h(is)g (case-insensitiv)m(e)i(regardless)f(of)f(the)g(v)-5 b(alue)40 b(of)g(CASEIGNOREDP)-8 b(.)150 1305 y(That)34 b(is,)h Fm(true)e Fr(or)h Fm(True)f Fr(or)h Fm(TRUE)f Fr(are)h(all)h(the)g (same.\))52 b(An)34 b(input)f(can)h(b)s(e)g(a)g(list,)i(in)e(whic)m(h)f (case)i(it)150 1415 y(is)f(tak)m(en)g(as)g(an)g(expression)f(to)i(run;) f(that)g(expression)g(m)m(ust)f(pro)s(duce)g(a)h(TR)m(UE)f(or)h(F)-10 b(ALSE)33 b(v)-5 b(alue.)150 1524 y(List)36 b(expressions)g(are)g(ev)-5 b(aluated)38 b(from)d(left)i(to)g(righ)m(t;)i(as)e(so)s(on)e(as)i(a)f (F)-10 b(ALSE)36 b(v)-5 b(alue)36 b(is)g(found,)h(the)150 1634 y(remaining)30 b(inputs)g(are)h(not)f(examined.)41 b(Example:)390 1768 y Fm(MAKE)47 b("RESULT)e(AND)i([NOT)g(\(:X)g(=)g (0\)])g([\(1)g(/)h(:X\))f(>)g(.5])275 1903 y Fr(to)31 b(a)m(v)m(oid)h(the)e(division)g(b)m(y)h(zero)g(if)f(the)h(\014rst)e (part)i(is)f(false.)275 2037 y(See)g([CASEIGNOREDP],)h(page)g(89)g(.) 150 2262 y Fk(or)390 2481 y Fm(OR)47 b(tf1)g(tf2)390 2590 y(\(OR)g(tf1)g(tf2)g(tf3)g(...\))275 2725 y Fr(outputs)33 b(TR)m(UE)h(if)g(an)m(y)h(input)e(is)h(TR)m(UE,)g(otherwise)h(F)-10 b(ALSE.)34 b(All)g(inputs)f(m)m(ust)h(b)s(e)g(TR)m(UE)g(or)150 2834 y(F)-10 b(ALSE.)28 b(\(Comparison)g(is)g(case-insensitiv)m(e)j (regardless)e(of)f(the)h(v)-5 b(alue)28 b(of)h(CASEIGNOREDP)-8 b(.)28 b(That)150 2944 y(is,)43 b Fm(true)c Fr(or)h Fm(True)f Fr(or)h Fm(TRUE)f Fr(are)h(all)h(the)f(same.\))71 b(An)40 b(input)f(can)h(b)s(e)g(a)g(list,)k(in)39 b(whic)m(h)h(case)h(it)g(is) 150 3054 y(tak)m(en)g(as)g(an)f(expression)g(to)h(run;)j(that)c (expression)g(m)m(ust)g(pro)s(duce)f(a)i(TR)m(UE)f(or)g(F)-10 b(ALSE)40 b(v)-5 b(alue.)150 3163 y(List)38 b(expressions)f(are)h(ev)-5 b(aluated)39 b(from)e(left)h(to)h(righ)m(t;)j(as)c(so)s(on)f(as)h(a)g (TR)m(UE)g(v)-5 b(alue)38 b(is)f(found,)i(the)150 3273 y(remaining)30 b(inputs)g(are)h(not)f(examined.)41 b(Example:)390 3407 y Fm(IF)47 b(OR)g(:X=0)g([some.long.computation])41 b([...])275 3542 y Fr(to)31 b(a)m(v)m(oid)h(the)e(long)h(computation)g (if)g(the)f(\014rst)g(condition)h(is)f(met.)275 3676 y(See)g([CASEIGNOREDP],)h(page)g(89)g(.)150 3900 y Fk(not)390 4120 y Fm(NOT)47 b(tf)275 4254 y Fr(outputs)29 b(TR)m(UE)h(if)h(the)f (input)f(is)h(F)-10 b(ALSE,)30 b(and)g(vice)h(v)m(ersa.)42 b(The)29 b(input)h(can)g(b)s(e)g(a)g(list,)h(in)f(whic)m(h)150 4364 y(case)j(it)g(is)f(tak)m(en)h(as)f(an)g(expression)g(to)h(run;)f (that)g(expression)g(m)m(ust)g(pro)s(duce)f(a)h(TR)m(UE)g(or)g(F)-10 b(ALSE)150 4473 y(v)-5 b(alue.)p eop end %%Page: 36 37 TeXDict begin 36 36 bop 150 -116 a Fr(36)2551 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 37 38 TeXDict begin 37 37 bop 150 -116 a Fr(Chapter)30 b(6:)41 b(Graphics)2689 b(37)150 299 y Fp(6)80 b(Graphics)275 544 y Fr(Berk)m(eley)36 b(Logo)g(pro)m(vides)f(traditional)h(Logo)g (turtle)f(graphics)g(with)f(one)h(turtle.)55 b(Multiple)35 b(tur-)150 654 y(tles,)28 b(dynamic)f(turtles,)h(and)e(collision)i (detection)h(are)e(not)g(supp)s(orted.)37 b(This)26 b(is)h(the)g(most)g (hardw)m(are-)150 764 y(dep)s(enden)m(t)33 b(part)h(of)g(Logo;)j(some)e (features)f(ma)m(y)g(exist)h(on)f(some)g(mac)m(hines)h(but)e(not)h (others.)52 b(Nev-)150 873 y(ertheless,)40 b(the)d(goal)i(has)e(b)s (een)g(to)h(mak)m(e)g(Logo)h(programs)e(as)g(p)s(ortable)h(as)f(p)s (ossible,)i(rather)e(than)150 983 y(to)32 b(tak)m(e)i(fullest)e(adv)-5 b(an)m(tage)34 b(of)d(the)h(capabilities)i(of)e(eac)m(h)h(mac)m(hine.) 45 b(In)31 b(particular,)i(Logo)g(attempts)150 1092 y(to)g(scale)h(the) f(screen)f(so)h(that)g(turtle)g(co)s(ordinates)g([{100)h({100])h(and)d ([100)i(100])g(\014t)e(on)g(the)h(graphics)150 1202 y(windo)m(w,)d(and) g(so)g(that)h(the)g(asp)s(ect)g(ratio)g(is)g(1:1.)275 1340 y(The)20 b(cen)m(ter)j(of)e(the)g(graphics)h(windo)m(w)e(\(whic)m (h)i(ma)m(y)f(or)h(ma)m(y)f(not)h(b)s(e)e(the)i(en)m(tire)g(screen,)h (dep)s(ending)150 1450 y(on)35 b(the)g(mac)m(hine)g(used\))g(is)g (turtle)g(lo)s(cation)i([0)e(0].)55 b(P)m(ositiv)m(e)37 b(X)e(is)g(to)h(the)f(righ)m(t;)j(p)s(ositiv)m(e)e(Y)f(is)g(up.)150 1559 y(Headings)29 b(\(angles\))h(are)f(measured)e(in)i(degrees)g(clo)s (c)m(kwise)g(from)f(the)h(p)s(ositiv)m(e)g(Y)g(axis.)40 b(\(This)28 b(di\013ers)150 1669 y(from)h(the)h(common)g(mathematical)i (con)m(v)m(en)m(tion)g(of)e(measuring)g(angles)g(coun)m(terclo)s(c)m (kwise)i(from)e(the)150 1779 y(p)s(ositiv)m(e)g(X)f(axis.\))41 b(The)28 b(turtle)h(is)g(represen)m(ted)f(as)h(an)g(iso)s(celes)h (triangle;)h(the)e(actual)h(turtle)f(p)s(osition)150 1888 y(is)c(at)h(the)f(midp)s(oin)m(t)g(of)g(the)g(base)g(\(the)h (short)f(side\).)39 b(Ho)m(w)m(ev)m(er,)28 b(the)e(turtle)f(is)g(dra)m (wn)f(one)i(step)f(b)s(ehind)150 1998 y(its)32 b(actual)h(p)s(osition,) f(so)g(that)g(the)g(displa)m(y)g(of)f(the)h(base)g(of)g(the)f(turtle's) h(triangle)h(do)s(es)e(not)h(obscure)150 2107 y(a)f(line)f(dra)m(wn)g (p)s(erp)s(endicular)e(to)j(it)g(\(as)g(w)m(ould)f(happ)s(en)f(after)i (dra)m(wing)f(a)h(square\).)275 2246 y(Colors)39 b(are,)j(of)d(course,) i(hardw)m(are-dep)s(enden)m(t.)66 b(Ho)m(w)m(ev)m(er,)43 b(Logo)e(pro)m(vides)e(partial)g(hardw)m(are)150 2355 y(indep)s(endence)29 b(b)m(y)h(in)m(terpreting)h(color)h(n)m(um)m(b)s (ers)d(0)i(through)e(7)i(uniformly)e(on)i(all)g(computers:)390 2494 y Fm(0)95 b(black)381 b(1)95 b(blue)428 b(2)95 b(green)381 b(3)95 b(cyan)390 2603 y(4)g(red)477 b(5)95 b(magenta)284 b(6)95 b(yellow)333 b(7)47 b(white)275 2741 y Fr(Where)36 b(p)s(ossible,)h(Logo)f(pro)m(vides)g(additional)h(user-settable)g (colors;)j(ho)m(w)35 b(man)m(y)h(are)h(a)m(v)-5 b(ailable)150 2851 y(dep)s(ends)42 b(on)j(the)f(hardw)m(are)g(and)g(op)s(erating)h (system)f(en)m(vironmen)m(t.)83 b(If)44 b(at)h(least)h(16)f(colors)h (are)150 2961 y(a)m(v)-5 b(ailable,)33 b(Logo)e(tries)g(to)g(pro)m (vide)g(uniform)e(initial)j(settings)f(for)f(the)h(colors)g(8-15:)438 3099 y Fm(8)95 b(brown)380 b(9)96 b(tan)428 b(10)95 b(forest)285 b(11)95 b(aqua)390 3208 y(12)g(salmon)285 b(13)95 b(purple)284 b(14)95 b(orange)285 b(15)95 b(grey)275 3347 y Fr(Logo)31 b(b)s(egins)f(with)g(a)h(blac)m(k)g(bac)m(kground)f(and)g(white)g(p)s (en.)150 3614 y Fq(6.1)68 b(T)-11 b(urtle)45 b(Motion)150 3955 y Fk(forw)m(ard)390 4174 y Fm(FORWARD)h(dist)390 4284 y(FD)h(dist)275 4422 y Fr(mo)m(v)m(es)e(the)f(turtle)g(forw)m (ard,)j(in)d(the)g(direction)g(that)h(it's)f(facing,)k(b)m(y)c(the)g (sp)s(eci\014ed)f(distance)150 4532 y(\(measured)30 b(in)g(turtle)h (steps\).)150 4763 y Fk(bac)m(k)390 4983 y Fm(BACK)47 b(dist)390 5092 y(BK)g(dist)275 5230 y Fr(mo)m(v)m(es)30 b(the)f(turtle)g(bac)m(kw)m(ard,)g(i.e.,)i(exactly)f(opp)s(osite)f(to)h (the)f(direction)g(that)h(it's)f(facing,)h(b)m(y)f(the)150 5340 y(sp)s(eci\014ed)h(distance.)41 b(\(The)30 b(heading)h(of)f(the)h (turtle)g(do)s(es)f(not)g(c)m(hange.\))p eop end %%Page: 38 39 TeXDict begin 38 38 bop 150 -116 a Fr(38)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(left)390 518 y Fm(LEFT)47 b(degrees)390 628 y(LT)g(degrees)275 774 y Fr(turns)31 b(the)i(turtle)g(coun)m (terclo)s(c)m(kwise)i(b)m(y)d(the)h(sp)s(eci\014ed)f(angle,)i(measured) e(in)g(degrees)i(\(1/360)h(of)150 884 y(a)c(circle\).)150 1133 y Fk(righ)m(t)390 1352 y Fm(RIGHT)46 b(degrees)390 1462 y(RT)h(degrees)275 1608 y Fr(turns)25 b(the)i(turtle)g(clo)s(c)m (kwise)h(b)m(y)f(the)g(sp)s(eci\014ed)f(angle,)i(measured)e(in)h (degrees)g(\(1/360)i(of)e(a)g(circle\).)150 1857 y Fk(setp)s(os)390 2076 y Fm(SETPOS)46 b(pos)275 2223 y Fr(mo)m(v)m(es)31 b(the)g(turtle)g(to)g(an)f(absolute)i(screen)e(p)s(osition.)41 b(The)30 b(input)g(is)g(a)h(list)g(of)g(t)m(w)m(o)g(n)m(um)m(b)s(ers,)f (the)150 2333 y(X)g(and)g(Y)h(co)s(ordinates.)150 2582 y Fk(setxy)390 2801 y Fm(SETXY)46 b(xcor)h(ycor)275 2948 y Fr(mo)m(v)m(es)29 b(the)e(turtle)h(to)h(an)e(absolute)i(screen)e(p)s (osition.)40 b(The)27 b(t)m(w)m(o)i(inputs)e(are)h(n)m(um)m(b)s(ers,)f (the)h(X)g(and)150 3057 y(Y)i(co)s(ordinates.)150 3306 y Fk(setx)390 3525 y Fm(SETX)47 b(xcor)275 3672 y Fr(mo)m(v)m(es)33 b(the)f(turtle)g(horizon)m(tally)i(from)d(its)i(old)f(p)s(osition)g(to) h(a)f(new)f(absolute)i(horizon)m(tal)g(co)s(ordi-)150 3782 y(nate.)41 b(The)30 b(input)g(is)g(the)h(new)f(X)g(co)s(ordinate.) 150 4030 y Fk(set)m(y)390 4250 y Fm(SETY)47 b(ycor)275 4396 y Fr(mo)m(v)m(es)36 b(the)f(turtle)h(v)m(ertically)h(from)d(its)i (old)f(p)s(osition)g(to)h(a)f(new)g(absolute)h(v)m(ertical)h(co)s (ordinate.)150 4506 y(The)30 b(input)f(is)i(the)f(new)g(Y)h(co)s (ordinate.)150 4755 y Fk(setheading)390 4974 y Fm(SETHEADING)45 b(degrees)390 5084 y(SETH)i(degrees)275 5230 y Fr(turns)40 b(the)i(turtle)g(to)h(a)f(new)g(absolute)g(heading.)75 b(The)42 b(input)f(is)g(a)i(n)m(um)m(b)s(er,)g(the)f(heading)g(in)150 5340 y(degrees)31 b(clo)s(c)m(kwise)h(from)e(the)g(p)s(ositiv)m(e)i(Y)e (axis.)p eop end %%Page: 39 40 TeXDict begin 39 39 bop 150 -116 a Fr(Chapter)30 b(6:)41 b(Graphics)2689 b(39)150 299 y Fk(home)390 518 y Fm(HOME)275 670 y Fr(mo)m(v)m(es)21 b(the)g(turtle)f(to)h(the)g(cen)m(ter)g(of)g (the)f(screen.)37 b(Equiv)-5 b(alen)m(t)22 b(to)f Fm(SETPOS)46 b([0)h(0])g(SETHEADING)e(0.)275 822 y Fr(See)30 b([SETPOS],)f(page)i (38)h(,)e(See)h([SETHEADING],)g(page)g(38)g(.)150 1081 y Fk(arc)390 1300 y Fm(ARC)47 b(angle)f(radius)275 1452 y Fr(dra)m(ws)28 b(an)h(arc)g(of)g(a)g(circle,)i(with)d(the)h(turtle)h (at)f(the)g(cen)m(ter,)i(with)d(the)h(sp)s(eci\014ed)g(radius,)f (starting)150 1561 y(at)e(the)f(turtle's)h(heading)f(and)g(extending)g (clo)s(c)m(kwise)i(through)d(the)i(sp)s(eci\014ed)e(angle.)40 b(The)25 b(turtle)g(do)s(es)150 1671 y(not)31 b(mo)m(v)m(e.)150 1971 y Fq(6.2)68 b(T)-11 b(urtle)45 b(Motion)g(Queries)150 2340 y Fk(p)s(os)390 2559 y Fm(POS)275 2711 y Fr(outputs)27 b(the)i(turtle's)f(curren)m(t)g(p)s(osition,)h(as)g(a)f(list)h(of)f(t)m (w)m(o)i(n)m(um)m(b)s(ers,)d(the)i(X)f(and)g(Y)g(co)s(ordinates.)150 2970 y Fk(xcor)390 3189 y Fm(XCOR)47 b(\(library)e(procedure\))275 3341 y Fr(outputs)29 b(a)i(n)m(um)m(b)s(er,)e(the)i(turtle's)g(X)f(co)s (ordinate.)150 3600 y Fk(ycor)390 3819 y Fm(YCOR)47 b(\(library)e (procedure\))275 3971 y Fr(outputs)29 b(a)i(n)m(um)m(b)s(er,)e(the)i (turtle's)g(Y)f(co)s(ordinate.)150 4230 y Fk(heading)390 4449 y Fm(HEADING)275 4601 y Fr(outputs)f(a)i(n)m(um)m(b)s(er,)e(the)i (turtle's)g(heading)f(in)g(degrees.)150 4859 y Fk(to)m(w)m(ards)390 5079 y Fm(TOWARDS)46 b(pos)275 5230 y Fr(outputs)37 b(a)i(n)m(um)m(b)s (er,)h(the)e(heading)h(at)g(whic)m(h)f(the)g(turtle)h(should)f(b)s(e)f (facing)j(so)e(that)h(it)g(w)m(ould)150 5340 y(p)s(oin)m(t)30 b(from)g(its)h(curren)m(t)f(p)s(osition)h(to)g(the)f(p)s(osition)h(giv) m(en)g(as)g(the)f(input.)p eop end %%Page: 40 41 TeXDict begin 40 40 bop 150 -116 a Fr(40)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(scrunc)m(h)390 518 y Fm(SCRUNCH)275 656 y Fr(outputs)k(a)h(list)h(con)m(taining)g(t)m(w)m(o)h(n)m(um)m(b)s (ers,)e(the)g(X)g(and)f(Y)h(scrunc)m(h)f(factors,)j(as)f(used)e(b)m(y)h (SET-)150 765 y(SCR)m(UNCH.)h(\(But)h(note)g(that)g(SETSCR)m(UNCH)e (tak)m(es)j(t)m(w)m(o)g(n)m(um)m(b)s(ers)d(as)h(inputs,)h(not)g(one)g (list)g(of)150 875 y(n)m(um)m(b)s(ers.\))275 1013 y(See)30 b([SETSCR)m(UNCH],)g(page)h(42)g(.)150 1278 y Fq(6.3)68 b(T)-11 b(urtle)45 b(and)g(Windo)l(w)g(Con)l(trol)150 1618 y Fk(sho)m(wturtle)390 1838 y Fm(SHOWTURTLE)390 1947 y(ST)275 2085 y Fr(mak)m(es)31 b(the)f(turtle)h(visible.)150 2316 y Fk(hideturtle)390 2535 y Fm(HIDETURTLE)390 2644 y(HT)275 2782 y Fr(mak)m(es)37 b(the)g(turtle)g(in)m(visible.)60 b(It's)37 b(a)g(go)s(o)s(d)g(idea)g(to)g(do)g(this)f(while)h(y)m(ou're) g(in)g(the)f(middle)h(of)g(a)150 2892 y(complicated)32 b(dra)m(wing,)f(b)s(ecause)f(hiding)g(the)g(turtle)h(sp)s(eeds)e(up)h (the)g(dra)m(wing)g(substan)m(tially)-8 b(.)150 3122 y Fk(clean)390 3341 y Fm(CLEAN)275 3479 y Fr(erases)39 b(all)g(lines)g(that)g(the)g(turtle)g(has)g(dra)m(wn)e(on)i(the)g (graphics)f(windo)m(w.)65 b(The)38 b(turtle's)i(state)150 3589 y(\(p)s(osition,)31 b(heading,)g(p)s(en)e(mo)s(de,)h(etc.\))42 b(is)31 b(not)f(c)m(hanged.)150 3819 y Fk(clearscreen)390 4039 y Fm(CLEARSCREEN)390 4148 y(CS)275 4286 y Fr(erases)e(the)g (graphics)h(windo)m(w)e(and)h(sends)f(the)h(turtle)h(to)f(its)h (initial)g(p)s(osition)g(and)e(heading.)40 b(Lik)m(e)150 4396 y(HOME)30 b(and)g(CLEAN)g(together.)275 4533 y(See)g([HOME],)h (page)g(39)h(.)150 4764 y Fk(wrap)390 4983 y Fm(WRAP)275 5121 y Fr(tells)k(the)g(turtle)h(to)f(en)m(ter)h(wrap)e(mo)s(de:)51 b(F)-8 b(rom)36 b(no)m(w)g(on,)i(if)d(the)h(turtle)h(is)e(ask)m(ed)i (to)g(mo)m(v)m(e)g(past)150 5230 y(the)31 b(b)s(oundary)f(of)h(the)g (graphics)h(windo)m(w,)f(it)g(will)h Fm(")p Fr(wrap)e(around)p Fm(")g Fr(and)h(reapp)s(ear)f(at)i(the)g(opp)s(osite)150 5340 y(edge)g(of)g(the)g(windo)m(w.)43 b(The)31 b(top)h(edge)h(wraps)d (to)i(the)g(b)s(ottom)g(edge,)h(while)e(the)h(left)g(edge)h(wraps)d(to) p eop end %%Page: 41 42 TeXDict begin 41 41 bop 150 -116 a Fr(Chapter)30 b(6:)41 b(Graphics)2689 b(41)150 299 y(the)33 b(righ)m(t)g(edge.)48 b(\(So)33 b(the)g(windo)m(w)f(is)h(top)s(ologically)j(equiv)-5 b(alen)m(t)34 b(to)f(a)g(torus.\))48 b(This)32 b(is)h(the)f(turtle's) 150 408 y(initial)g(mo)s(de.)40 b(Compare)30 b(WINDO)m(W)i(and)e (FENCE.)275 553 y(See)g([FENCE],)h(page)g(41)g(.)150 797 y Fk(windo)m(w)390 1016 y Fm(WINDOW)275 1161 y Fr(tells)g(the)f (turtle)h(to)g(en)m(ter)f(windo)m(w)g(mo)s(de:)40 b(F)-8 b(rom)31 b(no)m(w)f(on,)g(if)g(the)h(turtle)f(is)h(ask)m(ed)f(to)h(mo)m (v)m(e)h(past)150 1270 y(the)26 b(b)s(oundary)d(of)j(the)f(graphics)h (windo)m(w,)g(it)g(will)f(mo)m(v)m(e)i(o\013screen.)40 b(The)25 b(visible)h(graphics)f(windo)m(w)g(is)150 1380 y(considered)d(as)h(just)f(part)g(of)h(an)g(in\014nite)f(graphics)g (plane;)k(the)c(turtle)h(can)g(b)s(e)f(an)m(ywhere)g(on)h(the)g(plane.) 150 1489 y(\(If)36 b(y)m(ou)g(lose)h(the)g(turtle,)h(HOME)e(will)h (bring)e(it)i(bac)m(k)f(to)h(the)g(cen)m(ter)g(of)f(the)g(windo)m(w.\)) 58 b(Compare)150 1599 y(WRAP)31 b(and)e(FENCE.)275 1743 y(See)h([HOME],)h(page)g(39)h(.)150 1988 y Fk(fence)390 2207 y Fm(FENCE)275 2351 y Fr(tells)c(the)f(turtle)g(to)h(en)m(ter)f (fence)h(mo)s(de:)38 b(F)-8 b(rom)28 b(no)m(w)f(on,)h(if)e(the)i (turtle)f(is)g(ask)m(ed)h(to)f(mo)m(v)m(e)i(past)e(the)150 2461 y(b)s(oundary)32 b(of)j(the)f(graphics)h(windo)m(w,)g(it)f(will)h (mo)m(v)m(e)h(as)e(far)h(as)f(it)h(can)g(and)e(then)h(stop)h(at)g(the)f (edge)150 2570 y(with)c(an)g Fm(")p Fr(out)h(of)f(b)s(ounds)p Fm(")e Fr(error)i(message.)42 b(Compare)30 b(WRAP)h(and)f(WINDO)m(W.) 275 2715 y(See)g([WRAP],)i(page)f(40)g(.)150 2959 y Fk(\014ll)390 3178 y Fm(FILL)275 3323 y Fr(\014lls)f(in)g(a)h(region)g(of)g(the)g (graphics)g(windo)m(w)f(con)m(taining)i(the)f(turtle)g(and)f(b)s (ounded)e(b)m(y)j(lines)f(that)150 3432 y(ha)m(v)m(e)36 b(b)s(een)f(dra)m(wn)f(earlier.)56 b(This)34 b(is)h(not)g(p)s(ortable;) j(it)e(do)s(esn't)f(w)m(ork)g(for)g(all)h(mac)m(hines,)h(and)d(ma)m(y) 150 3542 y(not)d(w)m(ork)f(exactly)i(the)f(same)g(w)m(a)m(y)g(on)f (di\013eren)m(t)h(mac)m(hines.)150 3786 y Fk(lab)s(el)390 4005 y Fm(LABEL)46 b(text)275 4149 y Fr(tak)m(es)34 b(a)g(w)m(ord)e(or) h(list)h(as)f(input,)g(and)g(prin)m(ts)f(the)i(input)e(on)h(the)g (graphics)g(windo)m(w,)g(starting)h(at)150 4259 y(the)d(turtle's)f(p)s (osition.)150 4503 y Fk(textscreen)390 4722 y Fm(TEXTSCREEN)390 4832 y(TS)275 4976 y Fr(rearranges)g(the)h(size)g(and)f(p)s(osition)g (of)h(windo)m(ws)e(to)j(maximize)f(the)g(space)g(a)m(v)-5 b(ailable)32 b(in)e(the)h(text)150 5086 y(windo)m(w)i(\(the)i(windo)m (w)e(used)h(for)f(in)m(teraction)j(with)e(Logo\).)53 b(The)34 b(details)h(di\013er)f(among)g(mac)m(hines.)150 5196 y(Compare)c(SPLITSCREEN)e(and)i(FULLSCREEN.)275 5340 y(See)g([SPLITSCREEN],)f(page)i(42)g(.)p eop end %%Page: 42 43 TeXDict begin 42 42 bop 150 -116 a Fr(42)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(fullscreen)390 518 y Fm(FULLSCREEN)390 628 y(FS)275 773 y Fr(rearranges)45 b(the)g(size)h(and)e(p)s(osition)h (of)g(windo)m(ws)f(to)i(maximize)g(the)f(space)h(a)m(v)-5 b(ailable)47 b(in)e(the)150 882 y(graphics)j(windo)m(w.)95 b(The)48 b(details)h(di\013er)g(among)g(mac)m(hines.)95 b(Compare)48 b(SPLITSCREEN)f(and)150 992 y(TEXTSCREEN.)275 1137 y(In)27 b(the)h(DOS)g(v)m(ersion,)h(switc)m(hing)g(from)f (fullscreen)g(to)h(splitscreen)f(loses)h(the)f(part)g(of)h(the)f (picture)150 1247 y(that's)d(hidden)f(b)m(y)g(the)h(text)h(windo)m(w.) 38 b(Also,)27 b(since)e(there)f(m)m(ust)h(b)s(e)f(a)h(text)h(windo)m(w) e(to)h(allo)m(w)h(prin)m(ting)150 1356 y(\(including)36 b(the)f(prin)m(ting)h(of)g(the)g(Logo)g(prompt\),)h(Logo)g (automatically)h(switc)m(hes)f(from)e(fullscreen)150 1466 y(to)c(splitscreen)f(whenev)m(er)f(an)m(ything)i(is)e(prin)m(ted.) 41 b([This)29 b(design)h(decision)g(follo)m(ws)h(from)e(the)h(scarcit)m (y)150 1576 y(of)d(memory)-8 b(,)29 b(so)e(that)h(the)f(extra)h(memory) f(to)h(remem)m(b)s(er)f(an)g(in)m(visible)h(part)f(of)g(a)h(dra)m(wing) f(seems)g(to)s(o)150 1685 y(exp)s(ensiv)m(e.])150 1931 y Fk(splitscreen)390 2150 y Fm(SPLITSCREEN)390 2260 y(SS)275 2405 y Fr(rearranges)42 b(the)g(size)g(and)f(p)s(osition)h(of)g(windo)m (ws)f(to)i(allo)m(w)g(some)f(ro)s(om)g(for)f(text)i(in)m(teraction)150 2514 y(while)28 b(also)h(k)m(eeping)g(most)g(of)f(the)h(graphics)f (windo)m(w)f(visible.)41 b(The)27 b(details)j(di\013er)d(among)i(mac)m (hines.)150 2624 y(Compare)h(TEXTSCREEN)f(and)h(FULLSCREEN.)275 2769 y(See)g([TEXTSCREEN],)g(page)h(41)g(.)150 3015 y Fk(setscrunc)m(h)390 3234 y Fm(SETSCRUNCH)45 b(xscale)h(yscale)275 3379 y Fr(adjusts)26 b(the)h(asp)s(ect)g(ratio)h(and)f(scaling)h(of)f (the)g(graphics)g(displa)m(y)-8 b(.)41 b(After)27 b(this)g(command)f (is)h(used,)150 3489 y(all)k(further)f(turtle)h(motion)g(will)g(b)s(e)f (adjusted)g(b)m(y)g(m)m(ultiplying)h(the)g(horizon)m(tal)h(and)e(v)m (ertical)j(exten)m(t)150 3598 y(of)43 b(the)g(motion)g(b)m(y)g(the)g(t) m(w)m(o)h(n)m(um)m(b)s(ers)e(giv)m(en)h(as)g(inputs.)77 b(F)-8 b(or)44 b(example,)j(after)c(the)g(instruction)150 3708 y Fm(SETSCRUNCH)28 b(2)i(1)45 b Fr(motion)h(at)g(a)g(heading)g(of) g(45)g(degrees)g(will)g(mo)m(v)m(e)h(t)m(wice)g(as)f(far)f(horizon)m (tally)150 3818 y(as)f(v)m(ertically)-8 b(.)82 b(If)43 b(y)m(our)g(squares)g(don't)h(come)g(out)f(square,)k(try)c(this.)80 b(\(Alternativ)m(ely)-8 b(,)50 b(y)m(ou)44 b(can)150 3927 y(delib)s(erately)31 b(misadjust)f(the)g(asp)s(ect)h(ratio)h(to)f (dra)m(w)f(an)g(ellipse.\))275 4072 y(F)-8 b(or)21 b(Unix)f(mac)m (hines)i(and)e(Macin)m(toshes,)k(b)s(oth)c(scale)i(factors)g(are)f (initially)h(1.)38 b(F)-8 b(or)21 b(DOS)f(mac)m(hines,)150 4182 y(the)37 b(scale)i(factors)f(are)g(initially)g(set)g(according)g (to)g(what)f(the)h(hardw)m(are)f(claims)h(the)f(asp)s(ect)h(ratio)150 4292 y(is,)31 b(but)f(the)g(hardw)m(are)h(sometimes)g(lies.)42 b(The)30 b(v)-5 b(alues)31 b(set)g(b)m(y)f(SETSCR)m(UNCH)g(are)g(remem) m(b)s(ered)g(in)150 4401 y(a)35 b(\014le)f(\(called)i(SCR)m(UNCH.D)m(A) -8 b(T\))36 b(and)e(are)g(automatically)k(put)33 b(in)m(to)i(e\013ect)h (when)e(a)g(Logo)i(session)150 4511 y(b)s(egins.)150 4756 y Fk(refresh)390 4976 y Fm(REFRESH)275 5121 y Fr(tells)g(Logo)h (to)f(remem)m(b)s(er)f(the)g(turtle's)h(motions)g(so)g(that)g(they)f (can)h(b)s(e)f(reconstructed)h(in)f(case)150 5230 y(the)g(graphics)g (windo)m(w)f(is)h(o)m(v)m(erla)m(y)m(ed.)57 b(The)34 b(e\013ectiv)m(eness)j(of)e(this)g(command)g(ma)m(y)g(dep)s(end)e(on)i (the)150 5340 y(mac)m(hine)c(used.)p eop end %%Page: 43 44 TeXDict begin 43 43 bop 150 -116 a Fr(Chapter)30 b(6:)41 b(Graphics)2689 b(43)150 299 y Fk(norefresh)390 518 y Fm(NOREFRESH)275 666 y Fr(tells)40 b(Logo)g(not)g(to)g(remem)m(b)s(er)f (the)g(turtle's)h(motions.)69 b(This)38 b(will)i(mak)m(e)g(dra)m(wing)f (faster,)k(but)150 776 y(prev)m(en)m(ts)31 b(reco)m(v)m(ery)h(if)e(the) h(windo)m(w)f(is)g(o)m(v)m(erla)m(y)m(ed.)150 1068 y Fq(6.4)68 b(T)-11 b(urtle)45 b(and)g(Windo)l(w)g(Queries)150 1430 y Fk(sho)m(wnp)390 1649 y Fm(SHOWNP)390 1758 y(SHOWN?)275 1907 y Fr(outputs)23 b(TR)m(UE)h(if)g(the)g(turtle)g(is)g(sho)m(wn)f (\(visible\),)k(F)-10 b(ALSE)23 b(if)h(the)g(turtle)g(is)g(hidden.)37 b(See)24 b(SHO)m(W-)150 2016 y(TUR)-8 b(TLE)30 b(and)g(HIDETUR)-8 b(TLE.)275 2165 y(See)30 b([SHO)m(WTUR)-8 b(TLE],)31 b(page)g(40)g(,)g([HIDETUR)-8 b(TLE],)31 b(page)g(40)g(.)150 2416 y Fk(screenmo)s(de)390 2636 y Fm(SCREENMODE)275 2784 y Fr(outputs)39 b(the)i(w)m(ord)f(TEXTSCREEN,)e(SPLITSCREEN,)h(or) h(FULLSCREEN)f(dep)s(ending)g(on)150 2894 y(the)31 b(curren)m(t)f (screen)g(mo)s(de.)150 3145 y Fk(turtlemo)s(de)390 3365 y Fm(TURTLEMODE)275 3513 y Fr(outputs)25 b(the)i(w)m(ord)f(WRAP)-8 b(,)28 b(FENCE,)e(or)h(WINDO)m(W)h(dep)s(ending)d(on)h(the)h(curren)m (t)f(turtle)h(mo)s(de.)150 3805 y Fq(6.5)68 b(P)l(en)45 b(and)g(Bac)l(kground)f(Con)l(trol)275 4063 y Fr(The)36 b(turtle)h(carries)h(a)f(p)s(en)f(that)i(can)f(dra)m(w)g(pictures.)60 b(A)m(t)38 b(an)m(y)f(time)h(the)f(p)s(en)f(can)i(b)s(e)e(UP)h(\(in)150 4173 y(whic)m(h)g(case)i(mo)m(ving)g(the)f(turtle)g(do)s(es)f(not)h(c)m (hange)h(what's)f(on)f(the)h(graphics)g(screen\))g(or)g(DO)m(WN)150 4282 y(\(in)31 b(whic)m(h)h(case)g(the)g(turtle)f(lea)m(v)m(es)j(a)e (trace\).)45 b(If)31 b(the)h(p)s(en)e(is)h(do)m(wn,)h(it)g(can)f(op)s (erate)h(in)f(one)h(of)g(three)150 4392 y(mo)s(des:)49 b(P)-8 b(AINT)35 b(\(so)h(that)g(it)f(dra)m(ws)g(lines)g(when)f(the)h (turtle)g(mo)m(v)m(es\),)j(ERASE)d(\(so)g(that)h(it)f(erases)150 4501 y(an)m(y)e(lines)g(that)h(migh)m(t)f(ha)m(v)m(e)h(b)s(een)f(dra)m (wn)f(on)g(or)h(through)f(that)i(path)f(earlier\),)i(or)d(REVERSE)g (\(so)150 4611 y(that)f(it)g(in)m(v)m(erts)g(the)g(status)f(of)h(eac)m (h)g(p)s(oin)m(t)g(along)g(the)g(turtle's)g(path\).)150 4863 y Fk(p)s(endo)m(wn)390 5082 y Fm(PENDOWN)390 5192 y(PD)275 5340 y Fr(sets)f(the)h(p)s(en's)e(p)s(osition)i(to)g(DO)m(WN,) h(without)e(c)m(hanging)h(its)g(mo)s(de.)p eop end %%Page: 44 45 TeXDict begin 44 44 bop 150 -116 a Fr(44)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(p)s(en)m(up)390 518 y Fm(PENUP)390 628 y(PU)275 766 y Fr(sets)g(the)h(p)s(en's)e(p)s(osition)i(to)g(UP)-8 b(,)31 b(without)f(c)m(hanging)i(its)e(mo)s(de.)150 999 y Fk(p)s(enpain)m(t)390 1218 y Fm(PENPAINT)390 1328 y(PPT)275 1466 y Fr(sets)g(the)h(p)s(en's)e(p)s(osition)i(to)g(DO)m(WN)g(and)f (mo)s(de)g(to)h(P)-8 b(AINT.)150 1699 y Fk(p)s(enerase)390 1918 y Fm(PENERASE)390 2028 y(PE)275 2166 y Fr(sets)30 b(the)h(p)s(en's)e(p)s(osition)i(to)g(DO)m(WN)g(and)f(mo)s(de)g(to)h (ERASE.)275 2305 y(See)f([ERASE],)h(page)g(58)g(.)150 2538 y Fk(p)s(enrev)m(erse)390 2757 y Fm(PENREVERSE)390 2866 y(PX)275 3005 y Fr(sets)49 b(the)g(p)s(en's)f(p)s(osition)h(to)g (DO)m(WN)h(and)f(mo)s(de)f(to)i(REVERSE.)e(\(This)g(ma)m(y)i(in)m (teract)g(in)150 3115 y(hardw)m(are-dep)s(enden)m(t)29 b(w)m(a)m(ys)j(with)e(use)g(of)g(color.\))275 3253 y(See)g([REVERSE],)g (page)h(10)h(.)150 3486 y Fk(setp)s(encolor)390 3705 y Fm(SETPENCOLOR)45 b(colornumber.or.rgblist)390 3815 y(SETPC)h(colornumber.or.rgblist)275 3953 y Fr(sets)28 b(the)h(p)s(en)e(color)j(to)f(the)g(giv)m(en)g(n)m(um)m(b)s(er,)f(whic) m(h)g(m)m(ust)g(b)s(e)g(a)h(nonnegativ)m(e)h(in)m(teger.)42 b(There)28 b(are)150 4063 y(initial)k(assignmen)m(ts)f(for)f(the)g (\014rst)g(16)h(colors:)438 4202 y Fm(0)95 b(black)f(1)h(blue)g(2)g (green)f(3)h(cyan)438 4311 y(4)g(red)g(5)g(magenta)e(6)i(yellow)f(7)48 b(white)438 4421 y(8)95 b(brown)f(9)h(tan)47 b(10)95 b(forest)46 b(11)95 b(aqua)390 4530 y(12)g(salmon)46 b(13)95 b(purple)46 b(14)95 b(orange)46 b(15)95 b(grey)275 4669 y Fr(but)25 b(other)h(colors)h(can)f(b)s(e)f(assigned)i(to)f(n)m (um)m(b)s(ers)f(b)m(y)h(the)g(P)-8 b(ALETTE)25 b(command.)39 b(Alternativ)m(ely)-8 b(,)150 4779 y(sets)35 b(the)g(p)s(en)f(color)i (to)g(the)f(giv)m(en)h(R)m(GB)g(v)-5 b(alues)35 b(\(a)h(list)f(of)g (three)g(nonnegativ)m(e)i(in)m(tegers)f(less)f(than)150 4888 y(64K)c(\(65536\))i(sp)s(ecifying)d(the)h(amoun)m(t)g(of)f(red,)g (green,)h(and)f(blue)g(in)g(the)h(desired)f(color\).)150 5121 y Fk(setpalette)390 5340 y Fm(SETPALETTE)45 b(colornumber)g (rgblist)p eop end %%Page: 45 46 TeXDict begin 45 45 bop 150 -116 a Fr(Chapter)30 b(6:)41 b(Graphics)2689 b(45)275 299 y(sets)34 b(the)g(actual)h(color)g (corresp)s(onding)d(to)j(a)f(giv)m(en)h(n)m(um)m(b)s(er,)e(if)h(allo)m (w)m(ed)i(b)m(y)d(the)h(hardw)m(are)g(and)150 408 y(op)s(erating)d (system.)42 b(Colorn)m(um)m(b)s(er)30 b(m)m(ust)h(b)s(e)f(an)g(in)m (teger)i(greater)g(than)f(or)f(equal)i(to)f(8.)42 b(\(Logo)33 b(tries)150 518 y(to)d(k)m(eep)f(the)g(\014rst)f(8)i(colors)f(constan)m (t.\))42 b(The)29 b(second)g(input)e(is)i(a)h(list)f(of)g(three)g (nonnegativ)m(e)i(in)m(tegers)150 628 y(less)k(than)g(64K)h(\(65536\))i (sp)s(ecifying)d(the)h(amoun)m(t)f(of)g(red,)i(green,)f(and)f(blue)g (in)g(the)g(desired)g(color.)150 737 y(The)k(actual)h(color)g (resolution)g(on)f(an)m(y)h(screen)f(is)g(probably)f(less)i(than)f (64K,)h(but)e(Logo)i(scales)h(as)150 847 y(needed.)150 1100 y Fk(setp)s(ensize)390 1319 y Fm(SETPENSIZE)k(size)275 1468 y Fr(sets)28 b(the)f(thic)m(kness)i(of)e(the)h(p)s(en.)39 b(The)27 b(input)g(is)h(either)g(a)g(single)g(p)s(ositiv)m(e)h(in)m (teger)g(or)e(a)h(list)h(of)f(t)m(w)m(o)150 1578 y(p)s(ositiv)m(e)k(in) m(tegers)g(\(for)f(horizon)m(tal)i(and)d(v)m(ertical)j(thic)m(kness\).) 43 b(Some)31 b(v)m(ersions)g(pa)m(y)g(no)g(atten)m(tion)i(to)150 1687 y(the)e(second)f(n)m(um)m(b)s(er,)f(but)h(alw)m(a)m(ys)i(ha)m(v)m (e)f(a)g(square)f(p)s(en.)390 1836 y Fm(SETPENPATTERN)44 b(pattern)275 1985 y Fr(sets)29 b(hardw)m(are-dep)s(enden)m(t)g(p)s(en) f(c)m(haracteristics.)43 b(This)28 b(command)h(is)h(not)f(guaran)m (teed)i(compat-)150 2095 y(ible)g(b)s(et)m(w)m(een)g(implemen)m (tations)h(on)e(di\013eren)m(t)h(mac)m(hines.)150 2348 y Fk(setp)s(enpattern)390 2567 y Fm(SETPENSIZE)45 b(size)390 2676 y(SETPENPATTERN)f(pattern)275 2825 y Fr(set)31 b(hardw)m(are-dep)s (enden)m(t)f(p)s(en)g(c)m(haracteristics.)45 b(These)31 b(commands)f(are)i(not)f(guaran)m(teed)h(com-)150 2935 y(patible)f(b)s(et)m(w)m(een)g(implemen)m(tations)h(on)e(di\013eren)m (t)h(mac)m(hines.)150 3188 y Fk(setp)s(en)390 3407 y Fm(SETPEN)46 b(list)h(\(library)e(procedure\))275 3556 y Fr(sets)25 b(the)g(p)s(en's)e(p)s(osition,)j(mo)s(de,)g(thic)m (kness,)h(and)d(hardw)m(are-dep)s(enden)m(t)g(c)m(haracteristics)j (accord-)150 3666 y(ing)h(to)g(the)f(information)h(in)f(the)h(input)f (list,)i(whic)m(h)e(should)f(b)s(e)h(tak)m(en)i(from)e(an)g(earlier)h (in)m(v)m(o)s(cation)i(of)150 3775 y(PEN.)275 3924 y(See)g([PEN],)h (page)g(46)g(.)150 4177 y Fk(setbac)m(kground)390 4397 y Fm(SETBACKGROUND)44 b(colornumber.or.rgblist)390 4506 y(SETBG)i(colornumber.or.rgblist)275 4655 y Fr(set)34 b(the)g(screen)g(bac)m(kground)g(color)h(b)m(y)f(slot)h(n)m(um)m(b)s (er)e(or)h(R)m(GB)h(v)-5 b(alues.)52 b(See)34 b(SETPENCOLOR)150 4765 y(for)c(details.)275 4914 y(See)g([SETPENCOLOR],)f(page)i(44)g(.) 150 5207 y Fq(6.6)68 b(P)l(en)45 b(Queries)p eop end %%Page: 46 47 TeXDict begin 46 46 bop 150 -116 a Fr(46)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(p)s(endo)m(wnp)390 518 y Fm(PENDOWNP)390 628 y(PENDOWN?)275 754 y Fr(outputs)f(TR)m(UE)i(if)f(the)h(p)s(en)e(is) h(do)m(wn,)g(F)-10 b(ALSE)30 b(if)h(it's)g(up.)150 955 y Fk(p)s(enmo)s(de)390 1174 y Fm(PENMODE)275 1300 y Fr(outputs)g(one)i (of)g(the)g(w)m(ords)f(P)-8 b(AINT,)32 b(ERASE,)g(or)h(REVERSE)e (according)j(to)f(the)g(curren)m(t)f(p)s(en)150 1410 y(mo)s(de.)275 1536 y(See)e([ERASE],)h(page)g(58)g(,)f([REVERSE],)h (page)g(10)g(.)150 1737 y Fk(p)s(encolor)390 1956 y Fm(PENCOLOR)390 2066 y(PC)275 2192 y Fr(outputs)c(a)h(color)g(n)m(um)m(b)s(er,)f(a)h (nonnegativ)m(e)i(in)m(teger)f(that)f(is)f(asso)s(ciated)i(with)f(a)g (particular)g(color,)150 2302 y(or)e(a)g(list)g(of)g(R)m(GB)h(v)-5 b(alues)26 b(if)g(suc)m(h)f(a)h(list)h(w)m(as)f(used)f(as)h(the)g(most) g(recen)m(t)h(input)e(to)h(SETPENCOLOR.)150 2411 y(There)k(are)h (initial)g(assignmen)m(ts)g(for)f(the)h(\014rst)f(16)h(colors:)438 2538 y Fm(0)95 b(black)380 b(1)96 b(blue)428 b(2)95 b(green)381 b(3)95 b(cyan)438 2647 y(4)g(red)476 b(5)96 b(magenta)284 b(6)95 b(yellow)333 b(7)47 b(white)438 2757 y(8)95 b(brown)380 b(9)96 b(tan)428 b(10)95 b(forest)285 b(11)95 b(aqua)390 2867 y(12)g(salmon)285 b(13)95 b(purple)284 b(14)95 b(orange)285 b(15)95 b(grey)275 2993 y Fr(but)29 b(other)i(colors)g(can)g(b)s(e)f (assigned)g(to)h(n)m(um)m(b)s(ers)e(b)m(y)h(the)h(P)-8 b(ALETTE)30 b(command.)150 3194 y Fk(palette)390 3413 y Fm(PALETTE)46 b(colornumber)275 3539 y Fr(outputs)34 b(a)i(list)f(of)g(three)h(in)m(tegers,)i(eac)m(h)e(in)f(the)g(range)g (0-65535,)40 b(represen)m(ting)35 b(the)g(amoun)m(t)h(of)150 3649 y(red,)30 b(green,)h(and)f(blue)g(in)g(the)g(color)i(asso)s (ciated)g(with)e(the)g(giv)m(en)i(n)m(um)m(b)s(er.)150 3849 y Fk(p)s(ensize)390 4068 y Fm(PENSIZE)275 4195 y Fr(outputs)27 b(a)i(list)f(of)h(t)m(w)m(o)g(p)s(ositiv)m(e)g(in)m (tegers,)h(sp)s(ecifying)e(the)h(horizon)m(tal)g(and)f(v)m(ertical)i (thic)m(kness)f(of)150 4305 y(the)i(turtle)f(p)s(en.)40 b(\(In)30 b(some)h(implemen)m(tations)h(the)e(t)m(w)m(o)i(n)m(um)m(b)s (ers)d(ma)m(y)i(alw)m(a)m(ys)h(b)s(e)d(equal.\))390 4431 y Fm(PENPATTERN)275 4558 y Fr(outputs)g(hardw)m(are-sp)s(eci\014c)i(p)s (en)e(information.)150 4758 y Fk(p)s(en)390 4977 y Fm(PEN)47 b(\(library)e(procedure\))275 5104 y Fr(outputs)g(a)h(list)g(con)m (taining)h(the)f(p)s(en's)e(p)s(osition,)50 b(mo)s(de,)f(thic)m(kness,) h(and)45 b(hardw)m(are-sp)s(eci\014c)150 5213 y(c)m(haracteristics,)33 b(for)d(use)g(b)m(y)h(SETPEN.)275 5340 y(See)f([SETPEN],)g(page)h(45)g (.)p eop end %%Page: 47 48 TeXDict begin 47 47 bop 150 -116 a Fr(Chapter)30 b(6:)41 b(Graphics)2689 b(47)150 299 y Fk(bac)m(kground)390 518 y Fm(BACKGROUND)390 628 y(BG)275 767 y Fr(outputs)44 b(the)i(graphics)f(bac)m(kground)g(color,)51 b(either)45 b(as)h(a)g(slot)g(n)m(um)m(b)s(er)e(or)h(as)g(an)h(R)m(GB)g(list,)150 876 y(whic)m(hev)m(er)31 b(w)m(a)m(y)g(it)g(w)m(as)g(set.)41 b(\(See)31 b(PENCOLOR.\))150 1144 y Fq(6.7)68 b(sa)l(ving)46 b(and)f(loading)g(pictures)150 1487 y Fk(sa)m(v)m(epict)390 1706 y Fm(SAVEPICT)h(filename)275 1845 y Fr(command.)66 b(W)-8 b(rites)41 b(a)e(\014le)h(with)f(the)g(sp)s(eci\014ed)f(name)i (con)m(taining)g(the)g(state)g(of)g(the)f(graphics)150 1955 y(windo)m(w,)33 b(including)f(an)m(y)h(nonstandard)f(color)i (palette)g(settings,)h(in)d(Logo's)i(in)m(ternal)g(format.)48 b(This)150 2064 y(picture)24 b(can)g(b)s(e)g(restored)g(to)h(the)f (screen)g(using)f(LO)m(ADPICT.)h(The)g(format)g(is)g(not)g(p)s(ortable) g(b)s(et)m(w)m(een)150 2174 y(platforms,)f(nor)c(is)i(it)g(readable)g (b)m(y)f(other)h(programs.)37 b([EPSPICT],)19 b(page)i(47)g(to)g(exp)s (ort)f(Logo)i(graphics)150 2283 y(for)30 b(other)h(programs.)150 2516 y Fk(loadpict)390 2735 y Fm(LOADPICT)46 b(filename)275 2874 y Fr(command.)75 b(Reads)42 b(the)h(sp)s(eci\014ed)e(\014le,)k (whic)m(h)d(m)m(ust)g(ha)m(v)m(e)h(b)s(een)f(written)g(b)m(y)g(a)g(SA) -10 b(VEPICT)150 2984 y(command,)29 b(and)g(restores)h(the)f(graphics)g (windo)m(w)g(and)f(color)i(palette)h(settings)f(to)g(the)f(v)-5 b(alues)30 b(stored)150 3093 y(in)g(the)h(\014le.)40 b(An)m(y)31 b(dra)m(wing)f(previously)g(on)g(the)h(screen)g(is)f (cleared.)275 3232 y(See)g([SA)-10 b(VEPICT],)30 b(page)h(47)g(.)150 3465 y Fk(epspict)390 3684 y Fm(EPSPICT)46 b(filename)275 3823 y Fr(command.)40 b(W)-8 b(rites)30 b(a)g(\014le)f(with)g(the)g(sp) s(eci\014ed)f(name,)i(con)m(taining)h(an)e(Encapsulated)g(P)m (ostscript)150 3933 y(\(EPS\))35 b(represen)m(tation)h(of)f(the)g (state)h(of)f(the)g(graphics)g(windo)m(w.)53 b(This)34 b(\014le)h(can)h(b)s(e)e(imp)s(orted)g(in)m(to)150 4042 y(other)f(programs)g(that)g(understand)e(EPS)h(format.)49 b(Restrictions:)e(the)33 b(dra)m(wing)f(cannot)i(use)f(AR)m(C,)150 4152 y(FILL,)d(PENERASE,)g(or)g(PENREVERSE;)f(an)m(y)i(suc)m(h)f (instructions)g(will)g(b)s(e)g(ignored)g(in)g(the)g(trans-)150 4262 y(lation)i(to)f(P)m(ostscript)g(form.)275 4400 y(See)j([AR)m(C],)h (page)g(39)g(,)g(See)f([FILL],)h(page)g(41)g(,)g(See)f([PENERASE],)g (page)h(44)g(,)g(See)g([PENRE-)150 4510 y(VERSE],)30 b(page)h(44)g(.)150 4778 y Fq(6.8)68 b(Mouse)45 b(Queries)150 5121 y Fk(mousep)s(os)390 5340 y Fm(MOUSEPOS)p eop end %%Page: 48 49 TeXDict begin 48 48 bop 150 -116 a Fr(48)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(outputs)37 b(the)h(co)s(ordinates)g(of)g(the)g (mouse,)i(pro)m(vided)d(that)i(it's)f(within)f(the)h(graphics)g(windo)m (w,)150 408 y(in)c(turtle)h(co)s(ordinates.)54 b(If)34 b(the)h(mouse)f(is)h(outside)g(the)g(graphics)f(windo)m(w,)h(then)g (the)f(last)i(p)s(osition)150 518 y(within)26 b(the)g(windo)m(w)g(is)g (returned.)39 b(Exception:)g(If)26 b(a)h(mouse)f(button)g(is)g(pressed) g(within)f(the)i(graphics)150 628 y(windo)m(w)34 b(and)g(held)g(while)g (the)h(mouse)f(is)h(dragged)g(outside)f(the)h(windo)m(w,)g(the)g (mouse's)f(p)s(osition)h(is)150 737 y(returned)29 b(as)i(if)f(the)h (windo)m(w)f(w)m(ere)g(big)h(enough)f(to)h(include)f(it.)150 961 y Fk(buttonp)390 1181 y Fm(BUTTONP)390 1290 y(BUTTON?)275 1425 y Fr(outputs)i(TR)m(UE)i(if)f(a)h(mouse)f(button)g(is)h(do)m(wn)f (and)f(the)i(mouse)f(is)h(o)m(v)m(er)g(the)g(graphics)f(windo)m(w.)150 1534 y(Once)c(the)h(button)e(is)i(do)m(wn,)f(BUTTONP)g(remains)g(true)g (un)m(til)g(the)h(button)f(is)g(released,)i(ev)m(en)f(if)f(the)150 1644 y(mouse)h(is)h(dragged)f(out)h(of)g(the)f(graphics)g(windo)m(w.) 150 1868 y Fk(buttonp)390 2087 y Fm(BUTTON)275 2222 y Fr(outputs)e(0)h(if)f(BUTTONP)h(w)m(ould)f(output)g(F)-10 b(ALSE;)29 b(otherwise,)g(it)h(outputs)e(an)g(in)m(teger)i(b)s(et)m(w)m (een)150 2331 y(1)j(and)e(3)i(indicating)g(whic)m(h)f(button)g(w)m(as)h (pressed.)45 b(Ordinarily)32 b(1)g(means)g(left,)i(2)f(means)f(righ)m (t,)i(and)150 2441 y(3)d(means)f(cen)m(ter,)i(but)d(op)s(erating)i (systems)g(ma)m(y)g(recon\014gure)f(these.)p eop end %%Page: 49 50 TeXDict begin 49 49 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(49)150 299 y Fp(7)80 b(W)-13 b(orkspace)52 b(Managemen)l(t)150 618 y Fq(7.1)68 b(Pro)t(cedure)45 b(De\014nition)150 935 y Fk(to)390 1154 y Fm(TO)i(procname)f(:input1)g(:input2)f(...)95 b(\(special)46 b(form\))275 1283 y Fr(command.)38 b(Prepares)23 b(Logo)i(to)f(accept)h(a)f(pro)s(cedure)f(de\014nition.)38 b(The)23 b(pro)s(cedure)f(will)i(b)s(e)f(named)150 1393 y Fm(procname)35 b Fr(and)i(there)g(m)m(ust)g(not)h(already)g(b)s(e)e (a)i(pro)s(cedure)e(b)m(y)h(that)h(name.)62 b(The)37 b(inputs)f(will)i(b)s(e)150 1502 y(called)28 b Fm(input1)e Fr(etc.)40 b(An)m(y)28 b(n)m(um)m(b)s(er)d(of)j(inputs)e(are)h(allo)m (w)m(ed,)j(including)d(none.)39 b(Names)28 b(of)f(pro)s(cedures)150 1612 y(and)j(inputs)f(are)i(case-insensitiv)m(e.)275 1741 y(Unlik)m(e)c(ev)m(ery)h(other)f(Logo)h(pro)s(cedure,)f(TO)f(tak)m (es)i(as)f(its)g(inputs)f(the)h(actual)h(w)m(ords)f(t)m(yp)s(ed)f(in)h (the)150 1851 y(instruction)h(line,)h(as)f(if)g(they)g(w)m(ere)g(all)h (quoted,)g(rather)f(than)f(the)h(results)g(of)g(ev)-5 b(aluating)29 b(expressions)150 1960 y(to)i(pro)m(vide)g(the)f(inputs.) 40 b(\(That's)31 b(what)f Fm(")p Fl(sp)s(ecial)g(form)p Fm(")g Fr(means.\))275 2089 y(This)e(v)m(ersion)i(of)g(Logo)g(allo)m (ws)h(v)-5 b(ariable)30 b(n)m(um)m(b)s(ers)e(of)i(inputs)e(to)i(a)g (pro)s(cedure.)39 b(After)30 b(the)g(pro)s(ce-)150 2199 y(dure)f(name)i(come)g(four)f(kinds)f(of)i(things,)f(*in)h(this)f (order*:)581 2328 y Fm(1.)143 b(0)47 b(or)g(more)g(REQUIRED)e(inputs) 190 b(:FOO)46 b(:FROBOZZ)581 2438 y(2.)143 b(0)47 b(or)g(more)g (OPTIONAL)e(inputs)190 b([:BAZ)46 b(87])h([:THINGO)e(5+9])581 2547 y(3.)143 b(0)47 b(or)g(1)h(REST)e(input)572 b([:GARPLY])581 2657 y(4.)143 b(0)47 b(or)g(1)h(DEFAULT)d(number)381 b(5)275 2786 y Fr(Ev)m(ery)23 b(pro)s(cedure)f(has)h(a)h(MINIMUM,)g (DEF)-10 b(A)m(UL)i(T,)25 b(and)e(MAXIMUM)h(n)m(um)m(b)s(er)e(of)i (inputs.)37 b(\(The)150 2895 y(latter)32 b(can)e(b)s(e)g(in\014nite.\)) 275 3024 y(The)k(MINIMUM)i(n)m(um)m(b)s(er)e(of)h(inputs)g(is)g(the)g (n)m(um)m(b)s(er)f(of)h(required)g(inputs,)g(whic)m(h)g(m)m(ust)g(come) 150 3134 y(\014rst.)40 b(A)30 b(required)g(input)f(is)i(indicated)g(b)m (y)f(the)390 3263 y Fm(:inputname)275 3392 y Fr(notation.)275 3521 y(After)44 b(all)h(the)g(required)e(inputs)g(can)i(b)s(e)f(zero)h (or)f(more)h(optional)g(inputs,)i(eac)m(h)e(of)g(whic)m(h)f(is)150 3631 y(represen)m(ted)30 b(b)m(y)h(the)f(follo)m(wing)i(notation:)390 3760 y Fm([:inputname)45 b(default.value.expressio)o(n])275 3889 y Fr(When)21 b(the)h(pro)s(cedure)e(is)i(in)m(v)m(ok)m(ed,)j(if)c (actual)i(inputs)e(are)h(not)f(supplied)g(for)g(these)h(optional)h (inputs,)150 3998 y(the)k(default)g(v)-5 b(alue)27 b(expressions)f(are) h(ev)-5 b(aluated)28 b(to)f(set)g(v)-5 b(alues)27 b(for)g(the)f (corresp)s(onding)g(input)g(names.)150 4108 y(The)32 b(inputs)g(are)h(pro)s(cessed)g(from)f(left)h(to)h(righ)m(t,)g(so)f(a)g (default)g(v)-5 b(alue)34 b(expression)e(can)h(b)s(e)g(based)f(on)150 4218 y(earlier)f(inputs.)40 b(Example:)390 4347 y Fm(to)47 b(proc)g(:inlist)f([:startvalue)e(first)i(:inlist])275 4476 y Fr(If)29 b(the)i(pro)s(cedure)e(is)i(in)m(v)m(ok)m(ed)g(b)m(y)g (sa)m(ying)390 4605 y Fm(proc)47 b([a)g(b)g(c])275 4734 y Fr(then)31 b(the)h(v)-5 b(ariable)33 b Fm(inlist)d Fr(will)i(ha)m(v)m(e)h(the)f(v)-5 b(alue)32 b([A)f(B)f(C])i(and)f(the)h (v)-5 b(ariable)33 b Fm(startvalue)c Fr(will)150 4843 y(ha)m(v)m(e)j(the)e(v)-5 b(alue)31 b(A.)g(If)f(the)g(pro)s(cedure)f (is)i(in)m(v)m(ok)m(ed)h(b)m(y)e(sa)m(ying)390 4972 y Fm(\(proc)46 b([a)i(b)f(c])g("x\))275 5101 y Fr(then)30 b Fm(inlist)e Fr(will)j(ha)m(v)m(e)h(the)e(v)-5 b(alue)31 b([A)g(B)f(C])h(and)e Fm(startvalue)f Fr(will)j(ha)m(v)m(e)g(the)g(v)-5 b(alue)31 b(X.)275 5230 y(After)h(all)i(the)e(required)g(and)g (optional)h(input)f(can)h(come)g(a)g(single)g Fm(rest)e Fr(input,)i(represen)m(ted)f(b)m(y)150 5340 y(the)f(follo)m(wing)g (notation:)p eop end %%Page: 50 51 TeXDict begin 50 50 bop 150 -116 a Fr(50)2551 b(BERKELEY)30 b(LOGO)g(5.5)390 299 y Fm([:inputname])275 438 y Fr(This)41 b(is)h(a)h(rest)f(input)f(rather)h(than)g(an)g(optional)h(input)e(b)s (ecause)i(there)f(is)g(no)g(default)g(v)-5 b(alue)150 547 y(expression.)40 b(There)27 b(can)h(b)s(e)f(at)i(most)f(one)g(rest) g(input.)39 b(When)27 b(the)h(pro)s(cedure)f(is)h(in)m(v)m(ok)m(ed,)h (the)f(v)-5 b(alue)150 657 y(of)34 b(this)f(input)g(will)h(b)s(e)f(a)h (list)g(con)m(taining)h(all)g(of)e(the)h(actual)h(inputs)d(pro)m(vided) i(that)g(w)m(ere)g(not)g(used)150 767 y(for)c(required)g(or)g(optional) i(inputs.)39 b(Example:)390 905 y Fm(to)47 b(proc)g(:in1)f([:in2)h ("foo])f([:in3)h("baz])f([:in4])275 1044 y Fr(If)29 b(this)i(pro)s (cedure)e(is)h(in)m(v)m(ok)m(ed)i(b)m(y)e(sa)m(ying)390 1183 y Fm(proc)47 b("x)275 1322 y Fr(then)30 b Fm(in1)h Fr(has)g(the)g(v)-5 b(alue)32 b(X,)f Fm(in2)g Fr(has)g(the)g(v)-5 b(alue)32 b(F)m(OO,)f Fm(in3)g Fr(has)g(the)g(v)-5 b(alue)32 b(BAZ,and)f Fm(in4)f Fr(has)150 1432 y(the)h(v)-5 b(alue)30 b Fm([])g Fr(\(the)h(empt)m(y)g(list\).)42 b(If)30 b(it's)h(in)m(v)m (ok)m(ed)g(b)m(y)g(sa)m(ying)390 1571 y Fm(\(proc)46 b("a)i("b)f("c)g("d)g("e\))275 1710 y Fr(then)34 b Fm(in1)g Fr(has)g(the)h(v)-5 b(alue)36 b(A,)f Fm(in2)f Fr(has)g(the)h(v)-5 b(alue)35 b(B,)h Fm(in3)e Fr(has)g(the)h(v)-5 b(alue)36 b(C,)e(and)g Fm(in4)g Fr(has)h(the)150 1819 y(v)-5 b(alue)31 b([D)g(E].)275 1958 y(The)37 b(MAXIMUM)j(n)m(um)m(b)s(er)d(of)h(inputs) g(for)g(a)g(pro)s(cedure)f(is)i(in\014nite)f(if)g(a)h(rest)f(input)f (is)i(giv)m(en;)150 2068 y(otherwise,)31 b(it)g(is)f(the)h(n)m(um)m(b)s (er)e(of)i(required)e(inputs)g(plus)h(the)g(n)m(um)m(b)s(er)f(of)i (optional)h(inputs.)275 2207 y(The)i(DEF)-10 b(A)m(UL)i(T)36 b(n)m(um)m(b)s(er)e(of)h(inputs)f(for)h(a)g(pro)s(cedure,)h(whic)m(h)e (is)h(the)h(n)m(um)m(b)s(er)d(of)i(inputs)f(that)150 2316 y(it)43 b(will)g(accept)h(if)f(its)g(in)m(v)m(o)s(cation)i(is)d (not)h(enclosed)h(in)e(paren)m(theses,)k(is)d(ordinarily)f(equal)h(to)h (the)150 2426 y(minim)m(um)28 b(n)m(um)m(b)s(er.)38 b(If)28 b(y)m(ou)h(w)m(an)m(t)g(a)g(di\013eren)m(t)g(default)f(n)m(um)m(b)s(er) f(y)m(ou)i(can)f(indicate)i(that)f(b)m(y)f(putting)150 2535 y(the)j(desired)e(default)i(n)m(um)m(b)s(er)e(as)i(the)f(last)h (thing)g(on)f(the)h(TO)e(line.)41 b(example:)390 2674 y Fm(to)47 b(proc)g(:in1)f([:in2)h("foo])f([:in3])g(3)275 2813 y Fr(This)33 b(pro)s(cedure)g(has)h(a)h(minim)m(um)f(of)g(one)h (input,)f(a)h(default)g(of)f(three)h(inputs,)f(and)g(an)g(in\014nite) 150 2923 y(maxim)m(um.)275 3062 y(Logo)28 b(resp)s(onds)d(to)j(the)f (TO)f(command)h(b)m(y)g(en)m(tering)h(pro)s(cedure)d(de\014nition)i(mo) s(de.)39 b(The)27 b(prompt)150 3171 y(c)m(haracter)46 b(c)m(hanges)f(from)f Fm(?)g Fr(to)g Fm(>)g Fr(and)g(whatev)m(er)h (instructions)f(y)m(ou)g(t)m(yp)s(e)h(b)s(ecome)f(part)g(of)h(the)150 3281 y(de\014nition)30 b(un)m(til)h(y)m(ou)f(t)m(yp)s(e)h(a)g(line)f (con)m(taining)i(only)f(the)f(w)m(ord)g(END.)150 3514 y Fk(de\014ne)390 3733 y Fm(DEFINE)46 b(procname)g(text)275 3872 y Fr(command.)39 b(De\014nes)26 b(a)g(pro)s(cedure)f(with)h(name)g Fm(procname)e Fr(and)h(text)i Fm(text)p Fr(.)38 b(If)26 b(there)g(is)g(already)h(a)150 3982 y(pro)s(cedure)22 b(with)i(the)f(same)h(name,)h(the)f(new)f(de\014nition)g(replaces)i (the)e(old)h(one.)39 b(The)23 b(text)h(input)f(m)m(ust)150 4091 y(b)s(e)33 b(a)h(list)g(whose)f(mem)m(b)s(ers)g(are)h(lists.)51 b(The)33 b(\014rst)g(mem)m(b)s(er)g(is)g(a)h(list)h(of)e(inputs;)i(it)f (lo)s(oks)g(lik)m(e)h(a)f(TO)150 4201 y(line)29 b(but)f(without)h(the)g (w)m(ord)f(TO,)g(without)h(the)g(pro)s(cedure)f(name,)h(and)f(without)h (the)g(colons)g(b)s(efore)150 4311 y(input)j(names.)49 b(In)32 b(other)h(w)m(ords,)h(the)f(mem)m(b)s(ers)f(of)h(this)g (\014rst)f(sublist)h(are)g(w)m(ords)g(for)g(the)g(names)g(of)150 4420 y(required)27 b(inputs)f(and)h(lists)h(for)f(the)g(names)h(of)f (optional)i(or)e(rest)h(inputs.)39 b(The)26 b(remaining)i(sublists)f (of)150 4530 y(the)g(text)g(input)f(mak)m(e)i(up)d(the)i(b)s(o)s(dy)e (of)i(the)g(pro)s(cedure,)f(with)h(one)g(sublist)f(for)g(eac)m(h)i (instruction)f(line)150 4639 y(of)i(the)g(b)s(o)s(dy)-8 b(.)40 b(\(There)28 b(is)i(no)e(END)i(line)f(in)g(the)g(text)h (input.\))40 b(It)29 b(is)g(an)g(error)g(to)g(rede\014ne)g(a)g (primitiv)m(e)150 4749 y(pro)s(cedure)g(unless)h(the)g(v)-5 b(ariable)32 b Fn(REDEFP)j Fr(has)c(the)f(v)-5 b(alue)31 b(TR)m(UE.)275 4888 y(See)f([REDEFP],)i(page)f(90)g(.)150 5121 y Fk(text)390 5340 y Fm(TEXT)47 b(procname)p eop end %%Page: 51 52 TeXDict begin 51 51 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(51)275 299 y(outputs)33 b(the)h(text)h(of)f(the)g(pro)s(cedure)f(named)h Fm(procname)e Fr(in)h(the)h(form)g(exp)s(ected)g(b)m(y)g(DEFINE:)150 408 y(a)c(list)h(of)f(lists,)h(the)f(\014rst)f(of)h(whic)m(h)f(describ) s(es)h(the)g(inputs)e(to)j(the)f(pro)s(cedure)f(and)g(the)h(rest)g(of)g (whic)m(h)150 518 y(are)35 b(the)f(lines)g(of)h(its)f(b)s(o)s(dy)-8 b(.)51 b(The)34 b(text)h(do)s(es)f(not)g(re\015ect)h(formatting)g (information)f(used)g(when)f(the)150 628 y(pro)s(cedure)c(w)m(as)i (de\014ned,)e(suc)m(h)h(as)h(con)m(tin)m(uation)h(lines)f(and)f(extra)h (spaces.)150 875 y Fk(fulltext)390 1095 y Fm(FULLTEXT)46 b(procname)275 1241 y Fr(outputs)39 b(a)h(represen)m(tation)h(of)g(the) f(pro)s(cedure)f Fm(procname)e Fr(in)j(whic)m(h)g(formatting)h (information)150 1350 y(is)35 b(preserv)m(ed.)53 b(If)34 b(the)h(pro)s(cedure)f(w)m(as)h(de\014ned)f(with)g(TO,)g(EDIT,)h(or)g (LO)m(AD,)g(then)g(the)g(output)f(is)150 1460 y(a)i(list)g(of)f(w)m (ords.)56 b(Eac)m(h)36 b(w)m(ord)f(represen)m(ts)g(one)h(en)m(tire)g (line)g(of)f(the)h(de\014nition)f(in)g(the)g(form)g(output)150 1570 y(b)m(y)g(READ)m(W)m(ORD,)i(including)e(extra)h(spaces)f(and)g (con)m(tin)m(uation)h(lines.)56 b(The)34 b(last)i(mem)m(b)s(er)e(of)i (the)150 1679 y(output)42 b(represen)m(ts)f(the)h(END)h(line.)76 b(If)41 b(the)h(pro)s(cedure)f(w)m(as)h(de\014ned)f(with)g(DEFINE,)i (then)f(the)150 1789 y(output)36 b(is)h(a)g(list)h(of)f(lists.)60 b(If)37 b(these)g(lists)g(are)g(prin)m(ted,)h(one)g(p)s(er)d(line,)k (the)e(result)g(will)g(lo)s(ok)g(lik)m(e)i(a)150 1898 y(de\014nition)30 b(using)f(TO.)g(Note:)42 b(the)30 b(output)g(from)f (FULL)-8 b(TEXT)30 b(is)g(not)g(suitable)h(for)e(use)h(as)g(input)f(to) 150 2008 y(DEFINE!)275 2154 y(See)h([TO],)h(page)g(49)g(,)f([EDIT],)h (page)g(61)h(,)e([LO)m(AD],)i(page)f(63)g(,)g([DEFINE],)g(page)h(50)f (.)150 2402 y Fk(cop)m(ydef)390 2621 y Fm(COPYDEF)46 b(newname)g(oldname)275 2767 y Fr(command.)78 b(Mak)m(es)45 b Fm(newname)c Fr(a)j(pro)s(cedure)e(iden)m(tical)j(to)f Fm(oldname)p Fr(.)77 b(The)43 b(latter)h(ma)m(y)g(b)s(e)f(a)150 2877 y(primitiv)m(e.)58 b(If)35 b Fm(newname)f Fr(w)m(as)i(already)h (de\014ned,)f(its)g(previous)g(de\014nition)f(is)h(lost.)58 b(If)36 b Fm(newname)e Fr(w)m(as)150 2986 y(already)d(a)h(primitiv)m (e,)f(the)g(rede\014nition)g(is)g(not)g(p)s(ermitted)f(unless)g(the)h (v)-5 b(ariable)32 b Fn(REDEFP)k Fr(has)31 b(the)150 3096 y(v)-5 b(alue)31 b(TR)m(UE.)275 3242 y(Note:)47 b(dialects)35 b(of)e(Logo)h(di\013er)f(as)g(to)h(the)f(order)g(of)g (inputs)f(to)i(COPYDEF.)f(This)g(dialect)h(uses)150 3352 y Fm(")p Fr(MAKE)c(order,)p Fm(")g Fr(not)h Fm(")p Fr(NAME)f(order.)p Fm(")275 3498 y Fr(See)g([REDEFP],)i(page)f(90)g(,)f([SA)-10 b(VE],)31 b(page)g(63)g(,)g([PO],)g(page)g(56)g(,)g([POT],)f(page)h(58) g(.)150 3785 y Fq(7.2)68 b(V)-11 b(ariable)46 b(De\014nition)150 4142 y Fk(mak)m(e)390 4361 y Fm(MAKE)h(varname)e(value)275 4508 y Fr(command.)58 b(Assigns)37 b(the)f(v)-5 b(alue)37 b Fm(value)e Fr(to)i(the)g(v)-5 b(ariable)37 b(named)f Fm(varname)p Fr(,)g(whic)m(h)g(m)m(ust)h(b)s(e)f(a)150 4617 y(w)m(ord.)k(V)-8 b(ariable)29 b(names)f(are)h(case-insensitiv)m (e.)42 b(If)28 b(a)g(v)-5 b(ariable)29 b(with)f(the)h(same)f(name)g (already)h(exists,)150 4727 y(the)i(v)-5 b(alue)30 b(of)h(that)g(v)-5 b(ariable)31 b(is)f(c)m(hanged.)42 b(If)30 b(not,)h(a)f(new)g(global)i (v)-5 b(ariable)31 b(is)g(created.)150 4975 y Fk(name)390 5194 y Fm(NAME)47 b(value)f(varname)g(\(library)f(procedure\))275 5340 y Fr(command.)40 b(Same)30 b(as)h(MAKE)f(but)g(with)g(the)h (inputs)e(in)h(rev)m(erse)h(order.)p eop end %%Page: 52 53 TeXDict begin 52 52 bop 150 -116 a Fr(52)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(lo)s(cal)390 518 y Fm(LOCAL)46 b(varname)390 628 y(LOCAL)g(varnamelist)390 737 y(\(LOCAL)g(varname1)g (varname2)f(...\))275 903 y Fr(command.)39 b(Accepts)27 b(as)g(inputs)f(one)h(or)f(more)h(w)m(ords,)g(or)f(a)h(list)h(of)e(w)m (ords.)39 b(A)27 b(v)-5 b(ariable)27 b(is)g(created)150 1013 y(for)f(eac)m(h)h(of)f(these)h(w)m(ords,)g(with)f(that)g(w)m(ord)g (as)g(its)h(name.)39 b(The)26 b(v)-5 b(ariables)27 b(are)f(lo)s(cal)i (to)f(the)f(curren)m(tly)150 1123 y(running)34 b(pro)s(cedure.)56 b(Logo)37 b(v)-5 b(ariables)37 b(follo)m(w)g(dynamic)e(scop)s(e)h (rules;)j(a)d(v)-5 b(ariable)37 b(that)f(is)g(lo)s(cal)h(to)150 1232 y(a)k(pro)s(cedure)f(is)h(a)m(v)-5 b(ailable)44 b(to)e(an)m(y)f(subpro)s(cedure)e(in)m(v)m(ok)m(ed)j(b)m(y)f(that)h (pro)s(cedure.)72 b(The)40 b(v)-5 b(ariables)150 1342 y(created)29 b(b)m(y)g(LOCAL)e(ha)m(v)m(e)j(no)e(initial)i(v)-5 b(alue;)29 b(they)g(m)m(ust)f(b)s(e)g(assigned)g(a)h(v)-5 b(alue)29 b(\(e.g.,)i(with)d(MAKE\))150 1451 y(b)s(efore)i(the)h(pro)s (cedure)e(attempts)i(to)g(read)f(their)h(v)-5 b(alue.)275 1618 y(See)30 b([MAKE],)h(page)g(51)h(.)150 1905 y Fk(lo)s(calmak)m(e) 390 2124 y Fm(LOCALMAKE)45 b(varname)h(value)g(\(library)g(procedure\)) 275 2290 y Fr(command.)39 b(Mak)m(es)30 b(the)f(named)f(v)-5 b(ariable)30 b(lo)s(cal,)g(lik)m(e)g(LOCAL,)e(and)g(assigns)h(it)g(the) g(giv)m(en)g(v)-5 b(alue,)150 2400 y(lik)m(e)32 b(MAKE.)275 2566 y(See)e([LOCAL],)g(page)i(52)f(,)f(See)h([MAKE],)g(page)g(51)g(.) 150 2854 y Fk(thing)390 3073 y Fm(THING)46 b(varname)390 3182 y(:quoted.varname)275 3349 y Fr(outputs)36 b(the)h(v)-5 b(alue)38 b(of)f(the)h(v)-5 b(ariable)38 b(whose)f(name)g(is)g(the)g (input.)60 b(If)37 b(there)g(is)g(more)h(than)f(one)150 3458 y(suc)m(h)27 b(v)-5 b(ariable,)29 b(the)e(innermost)g(lo)s(cal)h (v)-5 b(ariable)28 b(of)g(that)g(name)f(is)g(c)m(hosen.)40 b(The)27 b(colon)h(notation)h(is)e(an)150 3568 y(abbreviation)k(not)g (for)f(THING)g(but)g(for)g(the)h(com)m(bination)390 3734 y Fm(thing)46 b(")275 3900 y Fr(so)30 b(that)h Fm(:FOO)e Fr(means)i Fm(THING)46 b("FOO)o Fr(.)150 4188 y Fk(global)390 4407 y Fm(GLOBAL)g(varname)390 4516 y(GLOBAL)g(varnamelist)390 4626 y(\(GLOBAL)g(varname1)f(varname2)h(...\))275 4792 y Fr(command.)54 b(Accepts)36 b(as)f(inputs)e(one)j(or)f(more)g(w)m (ords,)g(or)g(a)h(list)f(of)g(w)m(ords.)54 b(A)35 b(global)h(v)-5 b(ariable)150 4902 y(is)39 b(created)i(for)e(eac)m(h)h(of)f(these)h(w)m (ords,)h(with)e(that)h(w)m(ord)f(as)g(its)h(name.)67 b(The)39 b(only)g(reason)h(this)f(is)150 5011 y(necessary)29 b(is)f(that)h(y)m(ou)g(migh)m(t)g(w)m(an)m(t)g(to)g(use)f(the)h Fm(")p Fr(setter)p Fm(")f Fr(notation)i(SETXYZ)d(for)h(a)h(v)-5 b(ariable)29 b(XYZ)150 5121 y(that)38 b(do)s(es)e(not)i(already)f(ha)m (v)m(e)i(a)e(v)-5 b(alue;)41 b(GLOBAL)d Fm(")p Fr(XYZ)e(mak)m(es)i (that)g(legal.)63 b(Note:)55 b(If)37 b(there)g(is)150 5230 y(curren)m(tly)32 b(a)h(lo)s(cal)h(v)-5 b(ariable)33 b(of)f(the)h(same)g(name,)g(this)f(command)g(do)s(es)g(*not*)i(mak)m(e) f(Logo)h(use)e(the)150 5340 y(global)g(v)-5 b(alue)31 b(instead)f(of)h(the)f(lo)s(cal)i(one.)p eop end %%Page: 53 54 TeXDict begin 53 53 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(53)150 299 y Fq(7.3)68 b(Prop)t(ert)l(y)45 b(Lists)275 537 y Fr(Note:)38 b(Names)23 b(of)g(prop)s(ert)m(y)g(lists)g(are)g(alw)m(a)m(ys)i (case-insensitiv)m(e.)41 b(Names)23 b(of)g(individual)g(prop)s(erties) 150 647 y(are)k(case-sensitiv)m(e)j(or)d(case-insensitiv)m(e)i(dep)s (ending)d(on)h(the)g(v)-5 b(alue)27 b(of)h Fn(CASEIGNOREDP)p Fr(,)e(whic)m(h)h(is)150 756 y(TR)m(UE)j(b)m(y)h(default.)275 885 y(See)f([CASEIGNOREDP],)h(page)g(89)g(.)275 1014 y(In)c(principle,)h(ev)m(ery)h(p)s(ossible)f(name)g(is)g(the)g(name)h (of)f(a)g(prop)s(ert)m(y)g(list,)h(whic)m(h)f(is)g(initially)i(empt)m (y)-8 b(.)150 1123 y(So)37 b(Logo)h(nev)m(er)f(giv)m(es)h(a)f Fm(")p Fr(no)f(suc)m(h)h(prop)s(ert)m(y)f(list)p Fm(")h Fr(error,)h(as)f(it)g(w)m(ould)g(for)g(unde\014ned)d(pro)s(cedure)150 1233 y(or)c(v)-5 b(ariable)32 b(names.)41 b(But)31 b(the)f(primitiv)m (e)i(pro)s(cedures)d(that)i(deal)g(with)f Fm(")p Fr(all)p Fm(")h Fr(prop)s(ert)m(y)f(lists)h(\(CON-)150 1342 y(TENTS,)41 b(PLISTS,)f(etc.\))77 b(list)43 b(only)f(nonempt)m(y)g(ones.)76 b(T)-8 b(o)42 b Fm(")p Fr(erase)p Fm(")h Fr(a)f(prop)s(ert)m(y)f(list)i ([ERASE],)150 1452 y(page)31 b(58)g(means)g(to)g(mak)m(e)g(it)g(empt)m (y)-8 b(,)31 b(remo)m(ving)h(all)f(prop)s(erties)f(from)g(it.)150 1658 y Fk(pprop)390 1878 y Fm(PPROP)46 b(plistname)g(propname)f(value) 275 2006 y Fr(command.)58 b(Adds)35 b(a)i(prop)s(ert)m(y)f(to)h(the)f Fm(plistname)e Fr(prop)s(ert)m(y)i(list)h(with)f(name)g Fm(propname)f Fr(and)150 2116 y(v)-5 b(alue)31 b Fm(value)p Fr(.)150 2322 y Fk(gprop)390 2541 y Fm(GPROP)46 b(plistname)g(propname) 275 2670 y Fr(outputs)24 b(the)g(v)-5 b(alue)25 b(of)g(the)g Fm(propname)d Fr(prop)s(ert)m(y)i(in)g(the)h Fm(plistname)d Fr(prop)s(ert)m(y)i(list,)i(or)f(the)g(empt)m(y)150 2780 y(list)31 b(if)f(there)h(is)f(no)h(suc)m(h)f(prop)s(ert)m(y)-8 b(.)150 2986 y Fk(remprop)390 3205 y Fm(REMPROP)46 b(plistname)f (propname)275 3334 y Fr(command.)104 b(Remo)m(v)m(es)54 b(the)e(prop)s(ert)m(y)f(named)g Fm(propname)f Fr(from)h(the)h(prop)s (ert)m(y)f(list)h(named)150 3444 y Fm(plistname)p Fr(.)150 3650 y Fk(plist)390 3869 y Fm(PLIST)46 b(plistname)275 3998 y Fr(outputs)30 b(a)h(list)g(whose)g(o)s(dd-n)m(um)m(b)s(ered)d (mem)m(b)s(ers)i(are)i(the)f(names,)g(and)f(whose)g(ev)m(en-n)m(um)m(b) s(ered)150 4108 y(mem)m(b)s(ers)22 b(are)g(the)h(v)-5 b(alues,)24 b(of)f(the)f(prop)s(erties)g(in)g(the)h(prop)s(ert)m(y)e (list)i(named)f Fm(plistname)p Fr(.)36 b(The)21 b(output)150 4217 y(is)32 b(a)h(cop)m(y)g(of)g(the)g(actual)g(prop)s(ert)m(y)f (list;)i(c)m(hanging)g(prop)s(erties)e(later)h(will)g(not)f(magically)j (c)m(hange)f(a)150 4327 y(list)d(output)f(earlier)h(b)m(y)g(PLIST.)150 4566 y Fq(7.4)68 b(W)-11 b(orkspace)45 b(Predicates)150 4883 y Fk(pro)s(cedurep)390 5102 y Fm(PROCEDUREP)g(name)390 5211 y(PROCEDURE?)g(name)275 5340 y Fr(outputs)29 b(TR)m(UE)i(if)f(the) h(input)e(is)i(the)f(name)h(of)f(a)h(pro)s(cedure.)p eop end %%Page: 54 55 TeXDict begin 54 54 bop 150 -116 a Fr(54)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(primitiv)m(ep)390 518 y Fm(PRIMITIVEP)45 b(name)390 628 y(PRIMITIVE?)g(name)275 768 y Fr(outputs)31 b(TR)m(UE)i(if)f(the)h(input)e(is)i(the)f(name)h(of)f(a)h(primitiv)m(e) g(pro)s(cedure)f(\(one)h(built)f(in)m(to)h(Logo\).)150 878 y(Note)k(that)f(some)g(of)g(the)g(pro)s(cedures)e(describ)s(ed)h (in)g(this)h(do)s(cumen)m(t)f(are)h(library)g(pro)s(cedures,)g(not)150 988 y(primitiv)m(es.)150 1224 y Fk(de\014nedp)390 1444 y Fm(DEFINEDP)46 b(name)390 1553 y(DEFINED?)g(name)275 1694 y Fr(outputs)30 b(TR)m(UE)h(if)g(the)h(input)e(is)h(the)g(name)g (of)h(a)f(user-de\014ned)f(pro)s(cedure,)g(including)h(a)g(library)150 1803 y(pro)s(cedure.)46 b(\(Ho)m(w)m(ev)m(er,)36 b(Logo)d(do)s(es)f (not)h(kno)m(w)g(ab)s(out)f(a)h(library)f(pro)s(cedure)f(un)m(til)i (that)g(pro)s(cedure)150 1913 y(has)d(b)s(een)g(in)m(v)m(ok)m(ed.\))150 2150 y Fk(namep)390 2369 y Fm(NAMEP)46 b(name)390 2479 y(NAME?)g(name)275 2619 y Fr(outputs)29 b(TR)m(UE)i(if)f(the)h(input)e (is)i(the)f(name)h(of)f(a)h(v)-5 b(ariable.)150 2856 y Fk(plistp)390 3075 y Fm(PLISTP)46 b(name)390 3185 y(PLIST?)g(name)275 3326 y Fr(outputs)38 b(TR)m(UE)g(if)h(the)g(input)e(is)i(the)g(name)g (of)f(a)h(*nonempt)m(y*)h(prop)s(ert)m(y)e(list.)66 b(\(In)38 b(principle)150 3435 y(ev)m(ery)30 b(w)m(ord)f(is)g(the)h(name)f(of)g (a)h(prop)s(ert)m(y)f(list;)h(if)g(y)m(ou)f(ha)m(v)m(en't)i(put)d(an)m (y)i(prop)s(erties)f(in)g(it,)h(PLIST)e(of)150 3545 y(that)j(name)f (outputs)g(an)g(empt)m(y)h(list,)h(rather)e(than)g(giving)h(an)f(error) g(message.\))150 3818 y Fq(7.5)68 b(W)-11 b(orkspace)45 b(Queries)150 4164 y Fk(con)m(ten)m(ts)390 4383 y Fm(CONTENTS)275 4524 y Fr(outputs)24 b(a)h Fm(")p Fr(con)m(ten)m(ts)h(list,)p Fm(")f Fr(i.e.,)i(a)e(list)g(of)g(three)g(lists)g(con)m(taining)h (names)f(of)g(de\014ned)e(pro)s(cedures,)150 4634 y(v)-5 b(ariables,)28 b(and)e(prop)s(ert)m(y)g(lists)h(resp)s(ectiv)m(ely)-8 b(.)41 b(This)26 b(list)h(includes)f(all)i(un)m(buried)c(named)i(items) i(in)e(the)150 4743 y(w)m(orkspace.)150 4980 y Fk(buried)390 5199 y Fm(BURIED)275 5340 y Fr(outputs)j(a)i(con)m(ten)m(ts)h(list)f (including)f(all)h(buried)f(named)f(items)i(in)f(the)h(w)m(orkspace.)p eop end %%Page: 55 56 TeXDict begin 55 55 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(55)150 299 y Fk(traced)390 518 y Fm(TRACED)275 665 y Fr(outputs)29 b(a)i(con)m(ten)m(ts)h(list)f(including)f(all)h(traced)g(named)f(items) h(in)f(the)h(w)m(orkspace.)150 914 y Fk(stepp)s(ed)390 1133 y Fm(STEPPED)275 1280 y Fr(outputs)e(a)i(con)m(ten)m(ts)h(list)f (including)f(all)h(stepp)s(ed)f(named)g(items)h(in)f(the)g(w)m (orkspace.)150 1528 y Fk(pro)s(cedures)390 1748 y Fm(PROCEDURES)275 1894 y Fr(outputs)38 b(a)h(list)g(of)g(the)g(names)f(of)h(all)h(un)m (buried)c(user-de\014ned)h(pro)s(cedures)h(in)g(the)h(w)m(orkspace.)150 2004 y(Note)c(that)f(this)g(is)g(a)g(list)g(of)g(names,)h(not)f(a)g (con)m(ten)m(ts)i(list.)51 b(\(Ho)m(w)m(ev)m(er,)37 b(pro)s(cedures)c (that)h(require)g(a)150 2114 y(con)m(ten)m(ts)e(list)f(as)g(input)e (will)i(accept)h(this)e(list.\))150 2362 y Fk(primitiv)m(es)390 2582 y Fm(PRIMITIVES)275 2728 y Fr(outputs)f(a)i(list)g(of)g(the)g (names)f(of)h(all)g(primitiv)m(e)g(pro)s(cedures)f(in)g(the)g(w)m (orkspace.)42 b(Note)32 b(that)f(this)150 2838 y(is)h(a)h(list)g(of)f (names,)h(not)f(a)h(con)m(ten)m(ts)h(list.)47 b(\(Ho)m(w)m(ev)m(er,)35 b(pro)s(cedures)c(that)h(require)g(a)h(con)m(ten)m(ts)h(list)f(as)150 2948 y(input)c(will)i(accept)h(this)e(list.\))150 3196 y Fk(names)390 3416 y Fm(NAMES)275 3562 y Fr(outputs)h(a)i(con)m(ten)m (ts)h(list)f(consisting)g(of)f(an)g(empt)m(y)h(list)g(\(indicating)g (no)g(pro)s(cedure)e(names\))h(fol-)150 3672 y(lo)m(w)m(ed)g(b)m(y)e(a) h(list)g(of)f(all)h(un)m(buried)e(v)-5 b(ariable)31 b(names)f(in)g(the) h(w)m(orkspace.)150 3921 y Fk(plists)390 4140 y Fm(PLISTS)275 4287 y Fr(outputs)j(a)h(con)m(ten)m(ts)i(list)e(consisting)h(of)f(t)m (w)m(o)h(empt)m(y)g(lists)f(\(indicating)h(no)f(pro)s(cedures)f(or)g(v) -5 b(ari-)150 4396 y(ables\))31 b(follo)m(w)m(ed)h(b)m(y)e(a)h(list)g (of)g(all)g(un)m(buried)e(nonempt)m(y)h(prop)s(ert)m(y)g(lists)g(in)g (the)h(w)m(orkspace.)150 4645 y Fk(namelist)390 4864 y Fm(NAMELIST)46 b(varname)f(\(library)h(procedure\))390 4974 y(NAMELIST)g(varnamelist)275 5121 y Fr(outputs)24 b(a)h(con)m(ten)m(ts)i(list)f(consisting)f(of)h(an)e(empt)m(y)i(list)f (follo)m(w)m(ed)i(b)m(y)e(a)g(list)h(of)f(the)g(name)g(or)g(names)150 5230 y(giv)m(en)h(as)g(input.)38 b(This)24 b(is)h(useful)g(in)g (conjunction)g(with)g(w)m(orkspace)h(con)m(trol)h(pro)s(cedures)c(that) j(require)150 5340 y(a)31 b(con)m(ten)m(ts)h(list)f(as)f(input.)p eop end %%Page: 56 57 TeXDict begin 56 56 bop 150 -116 a Fr(56)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(pllist)390 518 y Fm(PLLIST)46 b(plname)g(\(library)g(procedure\))390 628 y(PLLIST)g(plnamelist)275 763 y Fr(outputs)36 b(a)h(con)m(ten)m(ts)i(list)e(consisting)h(of)f(t)m (w)m(o)i(empt)m(y)e(lists)g(follo)m(w)m(ed)i(b)m(y)e(a)g(list)h(of)f (the)g(name)g(or)150 872 y(names)27 b(giv)m(en)i(as)f(input.)38 b(This)27 b(is)h(useful)e(in)h(conjunction)h(with)f(w)m(orkspace)h(con) m(trol)h(pro)s(cedures)d(that)150 982 y(require)k(a)h(con)m(ten)m(ts)h (list)f(as)g(input.)275 1117 y(Note:)39 b(All)25 b(pro)s(cedures)e (whose)h(input)f(is)i(indicated)f(as)h Fm(contentslist)c Fr(will)k(accept)h(a)e(single)h(w)m(ord)150 1227 y(\(tak)m(en)38 b(as)e(a)h(pro)s(cedure)e(name\),)k(a)e(list)g(of)f(w)m(ords)g(\(tak)m (en)i(as)f(names)f(of)g(pro)s(cedures\),)i(or)e(a)h(list)g(of)150 1336 y(three)31 b(lists)f(as)h(describ)s(ed)e(under)g(the)i(CONTENTS)d (command)j(ab)s(o)m(v)m(e.)275 1472 y(See)f([CONTENTS],)g(page)h(54)g (.)150 1697 y Fk(arit)m(y)390 1916 y Fm(ARITY)46 b(procedurename)275 2052 y Fr(outputs)27 b(a)i(list)f(of)h(three)f(n)m(um)m(b)s(ers:)38 b(the)28 b(minim)m(um,)g(default,)h(and)f(maxim)m(um)g(n)m(um)m(b)s(er) f(of)h(inputs)150 2161 y(for)k(the)h(pro)s(cedure)e(whose)h(name)g(is)g (the)h(input.)45 b(It)33 b(is)f(an)g(error)g(if)h(there)f(is)g(no)h (suc)m(h)e(pro)s(cedure.)46 b(A)150 2271 y(maxim)m(um)30 b(of)h(-1)g(means)f(that)h(the)g(n)m(um)m(b)s(er)e(of)h(inputs)g(is)g (unlimited.)150 2496 y Fk(no)s(des)390 2715 y Fm(NODES)275 2851 y Fr(outputs)40 b(a)g(list)i(of)e(t)m(w)m(o)i(n)m(um)m(b)s(ers.)70 b(The)40 b(\014rst)g(represen)m(ts)g(the)h(n)m(um)m(b)s(er)e(of)i(no)s (des)e(of)i(memory)150 2960 y(curren)m(tly)26 b(in)g(use.)39 b(The)26 b(second)g(sho)m(ws)g(the)g(maxim)m(um)g(n)m(um)m(b)s(er)f(of) h(no)s(des)f(that)i(ha)m(v)m(e)g(b)s(een)f(in)f(use)h(at)150 3070 y(an)m(y)g(time)g(since)g(the)g(last)g(in)m(v)m(o)s(cation)i(of)e (NODES.)f(\(A)h(no)s(de)f(is)h(a)g(small)g(blo)s(c)m(k)g(of)g(computer) f(memory)150 3179 y(as)k(used)g(b)m(y)g(Logo.)41 b(Eac)m(h)30 b(n)m(um)m(b)s(er)e(uses)g(one)i(no)s(de.)40 b(Eac)m(h)29 b(non-n)m(umeric)g(w)m(ord)g(uses)f(one)i(no)s(de,)f(plus)150 3289 y(some)37 b(non-no)s(de)f(memory)g(for)h(the)g(c)m(haracters)h(in) e(the)h(w)m(ord.)59 b(Eac)m(h)38 b(arra)m(y)f(tak)m(es)h(one)f(no)s (de,)h(plus)150 3399 y(some)30 b(non-no)s(de)e(memory)-8 b(,)30 b(as)f(w)m(ell)i(as)e(the)h(memory)f(required)f(b)m(y)h(its)h (elemen)m(ts.)42 b(Eac)m(h)29 b(list)h(requires)150 3508 y(one)d(no)s(de)f(p)s(er)g(elemen)m(t,)j(as)e(w)m(ell)h(as)f(the)g (memory)f(within)g(the)h(elemen)m(ts.\))41 b(If)27 b(y)m(ou)g(w)m(an)m (t)g(to)h(trac)m(k)g(the)150 3618 y(memory)h(use)h(of)f(an)h (algorithm,)h(it)f(is)f(b)s(est)h(if)f(y)m(ou)h(in)m(v)m(ok)m(e)h(GC)f (at)g(the)g(b)s(eginning)f(of)g(eac)m(h)i(iteration,)150 3727 y(since)g(otherwise)g(the)f(maxim)m(um)g(will)h(include)f(storage) i(that)f(is)f(un)m(used)g(but)f(not)i(y)m(et)g(collected.)150 3987 y Fq(7.6)68 b(W)-11 b(orkspace)45 b(Insp)t(ection)150 4322 y Fk(p)s(o)390 4541 y Fm(PRINTOUT)h(contentslist)390 4650 y(PO)h(contentslist)275 4786 y Fr(command.)60 b(Prin)m(ts)37 b(to)h(the)f(write)g(stream)g(the)h(de\014nitions)e(of)h(all)h(pro)s (cedures,)g(v)-5 b(ariables,)40 b(and)150 4895 y(prop)s(ert)m(y)30 b(lists)h(named)f(in)g(the)g(input)g(con)m(ten)m(ts)i(list.)150 5121 y Fk(p)s(oall)390 5340 y Fm(POALL)46 b(\(library)g(procedure\))p eop end %%Page: 57 58 TeXDict begin 57 57 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(57)275 299 y(command.)40 b(Prin)m(ts)30 b(all)i(un)m(buried)c(de\014nitions)i(in)g (the)h(w)m(orkspace.)41 b(Abbreviates)31 b Fm(PO)47 b(CONTENTS)n Fr(.)275 461 y(See)30 b([CONTENTS],)g(page)h(54)g(.)150 740 y Fk(p)s(ops)390 959 y Fm(POPS)47 b(\(library)e(procedure\))275 1121 y Fr(command.)c(Prin)m(ts)31 b(the)g(de\014nitions)f(of)h(all)h (un)m(buried)d(pro)s(cedures)g(in)i(the)g(w)m(orkspace.)42 b(Abbrevi-)150 1231 y(ates)31 b Fm(PO)48 b(PROCEDURES)m Fr(.)275 1393 y(See)30 b([PO],)h(page)g(56)g(,)g([PR)m(OCEDURES],)f (page)h(55)g(.)150 1672 y Fk(p)s(ons)390 1891 y Fm(PONS)47 b(\(library)e(procedure\))275 2053 y Fr(command.)39 b(Prin)m(ts)26 b(the)g(de\014nitions)g(of)g(all)i(un)m(buried)c(v)-5 b(ariables)27 b(in)f(the)g(w)m(orkspace.)40 b(Abbreviates)150 2163 y Fm(PO)47 b(NAMES)o Fr(.)275 2325 y(See)30 b([PO],)h(page)g(56)g (,)g([NAMES],)g(page)g(55)g(.)150 2604 y Fk(p)s(opls)390 2823 y Fm(POPLS)46 b(\(library)g(procedure\))275 2985 y Fr(command.)39 b(Prin)m(ts)25 b(the)i(con)m(ten)m(ts)g(of)f(all)h(un) m(buried)d(nonempt)m(y)i(prop)s(ert)m(y)g(lists)g(in)g(the)g(w)m (orkspace.)150 3095 y(Abbreviates)31 b Fm(PO)47 b(PLISTS)n Fr(.)275 3257 y(See)30 b([PO],)h(page)g(56)g(,)g([PLISTS],)e(page)i(55) g(.)150 3536 y Fk(p)s(on)390 3755 y Fm(PON)47 b(varname)f(\(library)f (procedure\))390 3865 y(PON)i(varnamelist)275 4027 y Fr(command.)40 b(Prin)m(ts)30 b(the)h(de\014nitions)f(of)g(the)h(named) f(v)-5 b(ariable\(s\).)150 4136 y(Abbreviates)31 b Fm(PO)47 b(NAMELIST)f(varname\(list\))l Fr(.)275 4298 y(See)30 b([PO],)h(page)g(56)g(,)g([NAMELIST],)f(page)h(55)g(.)150 4578 y Fk(p)s(opl)390 4797 y Fm(POPL)47 b(plname)f(\(library)f (procedure\))390 4906 y(POPL)i(plnamelist)275 5068 y Fr(command.)40 b(Prin)m(ts)30 b(the)h(de\014nitions)f(of)g(the)h(named) f(prop)s(ert)m(y)f(list\(s\).)150 5178 y(Abbreviates)i Fm(PO)47 b(PLLIST)f(plname\(list\))m Fr(.)275 5340 y(See)30 b([PO],)h(page)g(56)g(,)g([PLLIST],)e(page)i(56)h(.)p eop end %%Page: 58 59 TeXDict begin 58 58 bop 150 -116 a Fr(58)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(p)s(ot)390 518 y Fm(POT)47 b(contentslist)275 675 y Fr(command.)77 b(Prin)m(ts)42 b(the)h(title)h(lines)f(of)g(the)g(named)f(pro)s(cedures)f(and)h(the)h (de\014nitions)f(of)h(the)150 785 y(named)33 b(v)-5 b(ariables)33 b(and)g(prop)s(ert)m(y)f(lists.)49 b(F)-8 b(or)34 b(prop)s(ert)m(y)e (lists,)i(the)g(en)m(tire)f(list)h(is)f(sho)m(wn)f(on)h(one)h(line)150 894 y(instead)d(of)f(as)h(a)g(series)f(of)h(PPR)m(OP)f(instructions)g (as)h(in)f(PO.)275 1051 y(See)g([PPR)m(OP],)h(page)g(53)g(,)g([PO],)f (page)i(56)f(.)150 1320 y Fk(p)s(ots)390 1539 y Fm(POTS)47 b(\(library)e(procedure\))275 1696 y Fr(command.)38 b(Prin)m(ts)22 b(the)h(title)i(lines)e(of)g(all)g(un)m(buried)e(pro)s(cedures)h(in)h (the)g(w)m(orkspace.)38 b(Abbreviates)150 1806 y Fm(POT)47 b(PROCEDURES)m Fr(.)275 1963 y(See)30 b([PR)m(OCEDURES],)h(page)g(55)g (.)150 2276 y Fq(7.7)68 b(W)-11 b(orkspace)45 b(Con)l(trol)150 2655 y Fk(erase)390 2874 y Fm(ERASE)h(contentslist)390 2984 y(ER)h(contentslist)275 3141 y Fr(command.)85 b(Erases)45 b(from)g(the)g(w)m(orkspace)h(the)f(pro)s(cedures,)j(v)-5 b(ariables,)50 b(and)45 b(prop)s(ert)m(y)f(lists)150 3250 y(named)30 b(in)g(the)g(input.)40 b(Primitiv)m(e)32 b(pro)s(cedures)d(ma)m(y)i(not)f(b)s(e)g(erased)g(unless)g(the)h(v)-5 b(ariable)31 b Fn(REDEFP)150 3360 y Fr(has)f(the)h(v)-5 b(alue)31 b(TR)m(UE.)275 3517 y(See)f([REDEFP],)i(page)f(90)g(.)150 3786 y Fk(erall)390 4005 y Fm(ERALL)275 4162 y Fr(command.)105 b(Erases)52 b(all)h(un)m(buried)d(pro)s(cedures,)56 b(v)-5 b(ariables,)58 b(and)52 b(prop)s(ert)m(y)f(lists)h(from)g(the)150 4271 y(w)m(orkspace.)41 b(Abbreviates)31 b Fm(ERASE)47 b(CONTENTS)m Fr(.)275 4428 y(See)30 b([CONTENTS],)g(page)h(54)g(.)150 4697 y Fk(erps)390 4917 y Fm(ERPS)275 5073 y Fr(command.)40 b(Erases)30 b(all)i(un)m(buried)c(pro)s(cedures)h(from)h(the)h(w)m (orkspace.)150 5183 y(Abbreviates)g Fm(ERASE)46 b(PROCEDURES)m Fr(.)275 5340 y(See)30 b([ERASE],)h(page)g(58)g(,)f([PR)m(OCEDURES],)h (page)g(55)g(.)p eop end %%Page: 59 60 TeXDict begin 59 59 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(59)150 299 y Fk(erns)390 518 y Fm(ERNS)275 653 y Fr(command.)38 b(Erases)25 b(all)h(un)m(buried)d(v)-5 b(ariables)25 b(from)g(the)g(w)m(orkspace.)39 b(Abbreviates)26 b Fm(ERASE)46 b(NAMES)o Fr(.)275 788 y(See)30 b([ERASE],)h(page)g(58)g(,)f([NAMES],)i (page)f(55)g(.)150 1012 y Fk(erpls)390 1231 y Fm(ERPLS)275 1366 y Fr(command.)40 b(Erases)30 b(all)i(un)m(buried)c(prop)s(ert)m(y) i(lists)h(from)f(the)g(w)m(orkspace.)150 1476 y(Abbreviates)h Fm(ERASE)46 b(PLISTS)o Fr(.)275 1610 y(See)30 b([ERASE],)h(page)g(58)g (,)f([PLISTS],)g(page)h(55)g(.)150 1835 y Fk(ern)390 2054 y Fm(ERN)47 b(varname)f(\(library)f(procedure\))390 2164 y(ERN)i(varnamelist)275 2298 y Fr(command.)d(Erases)32 b(from)f(the)h(w)m(orkspace)h(the)f(v)-5 b(ariable\(s\))33 b(named)e(in)h(the)g(input.)43 b(Abbreviates)150 2408 y Fm(ERASE)j(NAMELIST)g(varname\(list\))l Fr(.)275 2543 y(See)30 b([ERASE],)h(page)g(58)g(,)f([NAMELIST],)h(page)g(55)g(.)150 2767 y Fk(erpl)390 2987 y Fm(ERPL)47 b(plname)f(\(library)f (procedure\))390 3096 y(ERPL)i(plnamelist)275 3231 y Fr(command.)g(Erases)33 b(from)f(the)h(w)m(orkspace)h(the)f(prop)s(ert) m(y)f(list\(s\))i(named)e(in)h(the)g(input.)46 b(Abbre-)150 3340 y(viates)32 b Fm(ERASE)46 b(PLLIST)g(plname\(list\))m Fr(.)275 3475 y(See)30 b([ERASE],)h(page)g(58)g(,)f([PLLIST],)g(page)h (56)g(.)150 3700 y Fk(bury)390 3919 y Fm(BURY)47 b(contentslist)275 4054 y Fr(command.)78 b(Buries)43 b(the)h(pro)s(cedures,)h(v)-5 b(ariables,)47 b(and)c(prop)s(ert)m(y)f(lists)i(named)e(in)h(the)h (input.)150 4163 y(A)30 b(buried)f(item)h(is)g(not)h(included)e(in)h (the)g(lists)g(output)g(b)m(y)g(CONTENTS,)e(PR)m(OCEDURES,)i(V)-10 b(ARI-)150 4273 y(ABLES,)24 b(and)g(PLISTS,)f(but)g(is)i(included)e(in) h(the)h(list)g(output)f(b)m(y)g(BURIED.)h(By)g(implication,)i(buried) 150 4382 y(things)j(are)h(not)g(prin)m(ted)f(b)m(y)g(PO)m(ALL)g(or)g (sa)m(v)m(ed)i(b)m(y)e(SA)-10 b(VE.)275 4517 y(See)32 b([CONTENTS],)f(page)i(54)h(,)e([PR)m(OCEDURES],)h(page)g(55)g(,)g ([PONS],)f(page)h(57)g(,)g([PLISTS],)150 4627 y(page)e(55)g(,)g([PO)m (ALL],)g(page)g(56)g(,)g([SA)-10 b(VE],)30 b(page)i(63)f(.)150 4851 y Fk(bury)m(all)390 5071 y Fm(BURYALL)1955 b(\(library)45 b(procedure\))275 5205 y Fr(command.)40 b(Abbreviates)31 b Fm(BURY)46 b(CONTENTS)p Fr(.)275 5340 y(See)30 b([CONTENTS],)g(page)h (54)g(.)p eop end %%Page: 60 61 TeXDict begin 60 60 bop 150 -116 a Fr(60)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(buryname)390 518 y Fm(BURYNAME)46 b(varname)f(\(library)h(procedure\))390 628 y(BURYNAME)g(varnamelist) 275 759 y Fr(command.)40 b(Abbreviates)31 b Fm(BURY)46 b(NAMELIST)g(varname\(list\))p Fr(.)275 891 y(See)30 b([BUR)-8 b(Y],)32 b(page)f(59)h(,)e([NAMELIST],)h(page)g(55)g(.)150 1105 y Fk(un)m(bury)390 1325 y Fm(UNBURY)46 b(contentslist)275 1456 y Fr(command.)56 b(Un)m(buries)34 b(the)i(pro)s(cedures,)g(v)-5 b(ariables,)38 b(and)d(prop)s(ert)m(y)f(lists)j(named)e(in)g(the)h (input.)150 1566 y(That)30 b(is,)h(the)g(named)e(items)i(will)g(b)s(e)f (returned)f(to)i(view)g(in)f(CONTENTS,)f(etc.)275 1697 y(See)h([CONTENTS],)g(page)h(54)g(.)150 1912 y Fk(un)m(bury)m(all)390 2131 y Fm(UNBURYALL)45 b(\(library)h(procedure\))275 2263 y Fr(command.)40 b(Abbreviates)31 b Fm(UNBURY)46 b(BURIED)p Fr(.)275 2394 y(See)30 b([BURIED],)i(page)f(54)g(.)150 2609 y Fk(un)m(buryname)390 2828 y Fm(UNBURYNAME)45 b(varname)h (\(library)f(procedure\))390 2938 y(UNBURYNAME)g(varnamelist)275 3069 y Fr(command.)40 b(Abbreviates)31 b Fm(UNBURY)46 b(NAMELIST)f(varname\(list\))p Fr(.)275 3201 y(See)30 b([UNBUR)-8 b(Y],)33 b(page)e(60)g(,)g([NAMELIST],)f(page)h(55)g(.)150 3416 y Fk(buriedp)390 3635 y Fm(BURIEDP)46 b(contentslist)390 3744 y(BURIED?)g(contentslist)275 3876 y Fr(outputs)36 b(TR)m(UE)h(if)g(the)g(\014rst)g(pro)s(cedure,)h(v)-5 b(ariable,)39 b(or)e(prop)s(ert)m(y)g(list)h(named)e(in)h(the)g(con)m (ten)m(ts)150 3985 y(list)30 b(is)f(buried,)f(F)-10 b(ALSE)28 b(if)h(not.)41 b(Only)28 b(the)h(\014rst)f(thing)h(in)g(the)g(list)g (is)g(tested;)i(the)e(most)g(common)g(use)150 4095 y(will)f(b)s(e)f (with)g(a)i(w)m(ord)e(as)h(input,)f(naming)h(a)g(pro)s(cedure,)f(but)g (a)h(con)m(ten)m(ts)i(list)e(is)g(allo)m(w)m(ed)h(so)f(that)h(y)m(ou) 150 4205 y(can)i Fm(BURIEDP)d([[])i([VARIABLE]])d Fr(or)j Fm(BURIEDP)f([[])g([])h([PROPLIST]])p Fr(.)150 4420 y Fk(trace)390 4639 y Fm(TRACE)46 b(contentslist)275 4770 y Fr(command.)40 b(Marks)30 b(the)g(named)f(items)i(for)e(tracing.)42 b(A)30 b(message)h(is)f(prin)m(ted)f(whenev)m(er)h(a)g(traced)150 4880 y(pro)s(cedure)43 b(is)h(in)m(v)m(ok)m(ed,)49 b(giving)c(the)f (actual)i(input)d(v)-5 b(alues,)48 b(and)43 b(whenev)m(er)h(a)g(traced) h(pro)s(cedure)150 4989 y(STOPs)31 b(or)h(OUTPUTs.)46 b(A)33 b(message)g(is)g(prin)m(ted)f(whenev)m(er)g(a)h(new)e(v)-5 b(alue)33 b(is)g(assigned)f(to)h(a)g(traced)150 5099 y(v)-5 b(ariable)33 b(using)f(MAKE.)g(A)h(message)g(is)g(prin)m(ted)f (whenev)m(er)g(a)g(new)g(prop)s(ert)m(y)g(is)g(giv)m(en)i(to)f(a)f (traced)150 5209 y(prop)s(ert)m(y)e(list)h(using)f(PPR)m(OP)-8 b(.)275 5340 y(See)30 b([STOP],)g(page)h(69)g(,)g([OUTPUT],)f(page)h (69)g(,)g([MAKE],)g(page)g(51)h(,)e([PPR)m(OP],)h(page)g(53)g(.)p eop end %%Page: 61 62 TeXDict begin 61 61 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(61)150 299 y Fk(un)m(trace)390 518 y Fm(UNTRACE)46 b(contentslist)275 648 y Fr(command.)40 b(T)-8 b(urns)29 b(o\013)i(tracing)g(for)f(the)h (named)f(items.)150 860 y Fk(tracedp)390 1080 y Fm(TRACEDP)46 b(contentslist)390 1189 y(TRACED?)g(contentslist)275 1320 y Fr(outputs)25 b(TR)m(UE)h(if)g(the)g(\014rst)f(pro)s(cedure,)g (v)-5 b(ariable,)28 b(or)e(prop)s(ert)m(y)f(list)i(named)e(in)h(the)g (con)m(ten)m(ts)h(list)150 1429 y(is)h(traced,)i(F)-10 b(ALSE)27 b(if)h(not.)40 b(Only)28 b(the)g(\014rst)f(thing)h(in)g(the)g (list)h(is)f(tested;)i(the)e(most)h(common)f(use)g(will)150 1539 y(b)s(e)f(with)h(a)g(w)m(ord)g(as)g(input,)g(naming)g(a)g(pro)s (cedure,)g(but)f(a)h(con)m(ten)m(ts)i(list)f(is)f(allo)m(w)m(ed)i(so)e (that)g(y)m(ou)h(can)150 1648 y Fm(TRACEDP)f([[])i([VARIABLE]])d Fr(or)k Fm(TRACEDP)d([[])h([])h([PROPLIST]])p Fr(.)150 1860 y Fk(step)390 2079 y Fm(STEP)47 b(contentslist)275 2210 y Fr(command.)79 b(Marks)43 b(the)h(named)f(items)g(for)h (stepping.)79 b(Whenev)m(er)44 b(a)f(stepp)s(ed)g(pro)s(cedure)f(is)150 2319 y(in)m(v)m(ok)m(ed,)34 b(eac)m(h)f(instruction)f(line)g(in)f(the)h (pro)s(cedure)f(b)s(o)s(dy)f(is)i(prin)m(ted)f(b)s(efore)h(b)s(eing)f (executed,)j(and)150 2429 y(Logo)g(w)m(aits)f(for)g(the)g(user)f(to)h (t)m(yp)s(e)g(a)g(newline)g(at)g(the)g(terminal.)48 b(A)33 b(message)h(is)f(prin)m(ted)f(whenev)m(er)150 2539 y(a)d(stepp)s(ed)e (v)-5 b(ariable)30 b(name)e(is)h(`)p Fm(shadowed)p Fr(')e(b)s(ecause)h (a)h(lo)s(cal)h(v)-5 b(ariable)29 b(of)g(the)g(same)g(name)f(is)h (created)150 2648 y(either)i(as)f(a)h(pro)s(cedure)e(input)h(or)g(b)m (y)g(the)h(LOCAL)f(command.)275 2779 y(See)g([LOCAL],)g(page)i(52)f(.) 150 2991 y Fk(unstep)390 3210 y Fm(UNSTEP)46 b(contentslist)275 3340 y Fr(command.)40 b(T)-8 b(urns)29 b(o\013)i(stepping)f(for)g(the)h (named)e(items.)150 3552 y Fk(stepp)s(edp)390 3771 y Fm(STEPPEDP)46 b(contentslist)390 3881 y(STEPPED?)g(contentslist)275 4011 y Fr(outputs)25 b(TR)m(UE)h(if)g(the)g(\014rst)f(pro)s(cedure,)g (v)-5 b(ariable,)28 b(or)e(prop)s(ert)m(y)f(list)i(named)e(in)h(the)g (con)m(ten)m(ts)h(list)150 4121 y(is)34 b(stepp)s(ed,)g(F)-10 b(ALSE)34 b(if)g(not.)53 b(Only)33 b(the)h(\014rst)g(thing)g(in)g(the)g (list)h(is)f(tested;)j(the)d(most)h(common)f(use)150 4230 y(will)28 b(b)s(e)f(with)g(a)i(w)m(ord)e(as)h(input,)f(naming)h(a) g(pro)s(cedure,)f(but)g(a)h(con)m(ten)m(ts)i(list)e(is)g(allo)m(w)m(ed) h(so)f(that)h(y)m(ou)150 4340 y(can)i Fm(STEPPEDP)d([[])h([VARIABLE]])f Fr(or)i Fm(STEPPEDP)e([[])i([])f([PROPLIST]])p Fr(.)150 4552 y Fk(edit)390 4771 y Fm(EDIT)47 b(contentslist)390 4881 y(ED)g(contentslist)390 4990 y(\(EDIT\))390 5100 y(\(ED\))275 5230 y Fr(command.)38 b(If)25 b(in)m(v)m(ok)m(ed)h(with)f (an)f(input,)i(EDIT)e(writes)h(the)g(de\014nitions)g(of)g(the)g(named)f (items)i(in)m(to)150 5340 y(a)e(temp)s(orary)f(\014le)g(and)g(edits)h (that)g(\014le,)h(using)d(y)m(our)i(fa)m(v)m(orite)h(editor)f(as)g (determined)f(b)m(y)g(the)h Fn(EDITOR)p eop end %%Page: 62 63 TeXDict begin 62 62 bop 150 -116 a Fr(62)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y(en)m(vironmen)m(t)37 b(v)-5 b(ariable.)58 b(If)35 b(y)m(ou)h(don't)g(ha)m(v)m(e)h(an)f Fn(EDITOR)f Fr(v)-5 b(ariable,)39 b(edits)d(the)g(de\014nitions)f(using)150 408 y(jo)m(v)m(e.)42 b(If)28 b(in)m(v)m(ok)m(ed)j(without)e(an)g (input,)f(EDIT)h(edits)g(the)g(same)h(\014le)f(left)h(o)m(v)m(er)g (from)e(a)i(previous)e(EDIT)150 518 y(or)36 b(EDITFILE)g(instruction.) 58 b(When)36 b(y)m(ou)g(lea)m(v)m(e)i(the)f(editor,)h(Logo)f(reads)f (the)g(revised)g(de\014nitions)150 628 y(and)c(mo)s(di\014es)h(the)g(w) m(orkspace)h(accordingly)-8 b(.)50 b(It)33 b(is)g(not)h(an)f(error)f (if)h(the)g(input)g(includes)f(names)h(for)150 737 y(whic)m(h)d(there)h (is)f(no)g(previous)g(de\014nition.)275 878 y(If)21 b(there)h(is)h(a)f (v)-5 b(ariable)23 b Fn(LO)m(ADNOISIL)-8 b(Y)35 b Fr(whose)22 b(v)-5 b(alue)22 b(is)g(TR)m(UE,)h(then,)g(after)g(lea)m(ving)h(the)e (editor,)150 987 y(TO)29 b(commands)f(in)h(the)h(temp)s(orary)f(\014le) g(prin)m(t)g Fm(")p Fr(PR)m(OCNAME)g(de\014ned)p Fm(")e Fr(\(where)j(PR)m(OCNAME)f(is)150 1097 y(the)34 b(name)f(of)h(the)g (pro)s(cedure)e(b)s(eing)h(de\014ned\);)i(if)e Fn(LO)m(ADNOISIL)-8 b(Y)46 b Fr(is)34 b(F)-10 b(ALSE)33 b(or)g(unde\014ned,)g(TO)150 1206 y(commands)d(in)g(the)h(\014le)f(are)h(carried)f(out)h(silen)m (tly)-8 b(.)275 1347 y(If)21 b(there)h(is)g(an)g(en)m(vironmen)m(t)h(v) -5 b(ariable)23 b(called)g Fn(TEMP)p Fr(,)f(then)f(Logo)j(uses)d(its)i (v)-5 b(alue)22 b(as)g(the)g(directory)150 1457 y(in)30 b(whic)m(h)g(to)h(write)g(the)f(temp)s(orary)g(\014le)h(used)e(for)i (editing.)275 1597 y(Exceptionally)-8 b(,)38 b(the)e(EDIT)f(command)f (can)i(b)s(e)f(used)f(without)h(its)h(default)f(input)f(and)h(without) 150 1707 y(paren)m(theses)c(pro)m(vided)f(that)h(nothing)f(follo)m(ws)h (it)g(on)g(the)f(instruction)h(line.)275 1847 y(See)f([LO)m(ADNOISIL)-8 b(Y],)31 b(page)g(89)h(,)e(See)h([EDITFILE],)g(page)g(62)g(.)150 2083 y Fk(edit\014le)390 2302 y Fm(EDITFILE)46 b(filename)275 2443 y Fr(command.)e(Starts)32 b(the)g(Logo)h(editor,)g(lik)m(e)g (EDIT,)f(but)f(instead)h(of)g(editing)g(a)g(temp)s(orary)g(\014le)f(it) 150 2552 y(edits)e(the)h(\014le)f(sp)s(eci\014ed)f(b)m(y)h(the)g (input.)40 b(When)28 b(y)m(ou)i(lea)m(v)m(e)h(the)e(editor,)h(Logo)h (reads)d(the)i(revised)f(\014le,)150 2662 y(as)24 b(for)g(EDIT.)f (EDITFILE)h(also)g(remem)m(b)s(ers)f(the)h(\014lename,)i(so)e(that)g(a) h(subsequen)m(t)e(EDIT)g(command)150 2772 y(with)30 b(no)g(input)g (will)g(re-edit)i(the)e(same)h(\014le.)275 2912 y(EDITFILE)44 b(is)i(in)m(tended)f(as)g(an)h(alternativ)m(e)h(to)f(LO)m(AD)g(and)f (SA)-10 b(VE.)45 b(Y)-8 b(ou)46 b(can)f(main)m(tain)i(a)150 3022 y(w)m(orkspace)30 b(\014le)e(y)m(ourself,)i(con)m(trolling)h(the)e (order)f(in)h(whic)m(h)f(de\014nitions)g(app)s(ear,)h(main)m(taining)h (com-)150 3131 y(men)m(ts)h(in)f(the)g(\014le,)h(and)f(so)g(on.)150 3367 y Fk(edall)390 3587 y Fm(EDALL)46 b(\(library)g(procedure\))275 3727 y Fr(command.)40 b(Abbreviates)31 b Fm(EDIT)46 b(CONTENTS)p Fr(.)275 3867 y(See)30 b([CONTENTS],)g(page)h(54)g(.)150 4104 y Fk(edps)390 4323 y Fm(EDPS)47 b(\(library)e(procedure\))275 4463 y Fr(command.)40 b(Abbreviates)31 b Fm(EDIT)46 b(PROCEDURES)p Fr(.)275 4604 y(See)30 b([EDIT],)h(page)g(61)g(,)g([PR)m(OCEDURES],)f (page)h(55)h(.)150 4840 y Fk(edns)390 5059 y Fm(EDNS)47 b(\(library)e(procedure\))275 5200 y Fr(command.)40 b(Abbreviates)31 b Fm(EDIT)46 b(NAMES)p Fr(.)275 5340 y(See)30 b([EDIT],)h(page)g(61)g (,)g([NAMES],)g(page)g(55)g(.)p eop end %%Page: 63 64 TeXDict begin 63 63 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(63)150 299 y Fk(edpls)390 518 y Fm(EDPLS)46 b(\(library)g(procedure\))275 657 y Fr(command.)40 b(Abbreviates)31 b Fm(EDIT)46 b(PLISTS)p Fr(.)275 795 y(See)30 b([EDIT],)h(page)g(61)g(,)g([PLISTS],)e(page)i (55)g(.)150 1028 y Fk(edn)390 1247 y Fm(EDN)47 b(varname)f(\(library)f (procedure\))390 1357 y(EDN)i(varnamelist)275 1495 y Fr(command.)40 b(Abbreviates)31 b Fm(EDIT)46 b(NAMELIST)g (varname\(list\))p Fr(.)275 1634 y(See)30 b([EDIT],)h(page)g(61)g(,)g ([NAMELIST],)f(page)h(55)h(.)150 1867 y Fk(edpl)390 2086 y Fm(EDPL)47 b(plname)f(\(library)f(procedure\))390 2195 y(EDPL)i(plnamelist)275 2334 y Fr(command.)40 b(Abbreviates)31 b Fm(EDIT)46 b(PLLIST)h(plname\(list\))p Fr(.)275 2473 y(See)30 b([EDIT],)h(page)g(61)g(,)g([PLLIST],)e(page)j(56)f(.)150 2705 y Fk(sa)m(v)m(e)390 2925 y Fm(SAVE)47 b(filename)275 3063 y Fr(command.)68 b(Sa)m(v)m(es)41 b(the)f(de\014nitions)f(of)h (all)g(un)m(buried)e(pro)s(cedures,)j(v)-5 b(ariables,)43 b(and)c(nonempt)m(y)150 3173 y(prop)s(ert)m(y)30 b(lists)h(in)f(the)g (named)g(\014le.)41 b(Equiv)-5 b(alen)m(t)31 b(to)390 3312 y Fm(to)47 b(save)g(:filename)390 3421 y(local)f("oldwriter)390 3531 y(make)h("oldwriter)e(writer)390 3640 y(openwrite)g(:filename)390 3750 y(setwrite)h(:filename)390 3859 y(poall)390 3969 y(setwrite)g(:oldwriter)390 4079 y(close)g(:filename)390 4188 y(end)150 4421 y Fk(sa)m(v)m(el)390 4640 y Fm(SAVEL)g (contentslist)f(filename)g(\(library)h(procedure\))275 4779 y Fr(command.)39 b(Sa)m(v)m(es)28 b(the)f(de\014nitions)f(of)h (the)h(pro)s(cedures,)e(v)-5 b(ariables,)29 b(and)d(prop)s(ert)m(y)g (lists)i(sp)s(eci\014ed)150 4888 y(b)m(y)i Fm(contentslist)d Fr(to)k(the)g(\014le)f(named)g Fm(filename)p Fr(.)150 5121 y Fk(load)390 5340 y Fm(LOAD)47 b(filename)p eop end %%Page: 64 65 TeXDict begin 64 64 bop 150 -116 a Fr(64)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(command.)47 b(Reads)32 b(instructions)h(from)f (the)h(named)f(\014le)g(and)g(executes)i(them.)47 b(The)32 b(\014le)h(can)g(in-)150 408 y(clude)24 b(pro)s(cedure)e(de\014nitions) h(with)g(TO,)g(and)g(these)h(are)g(accepted)h(ev)m(en)f(if)g(a)g(pro)s (cedure)e(b)m(y)i(the)g(same)150 518 y(name)g(already)h(exists.)40 b(If)23 b(the)i(\014le)f(assigns)h(a)g(list)g(v)-5 b(alue)24 b(to)h(a)g(v)-5 b(ariable)25 b(named)f Fn(ST)-8 b(AR)g(TUP)p Fr(,)24 b(then)g(that)150 628 y(list)29 b(is)g(run)e(as)h(an)h (instructionlist)g(after)g(the)f(\014le)h(is)f(loaded.)41 b(If)28 b(there)g(is)h(a)g(v)-5 b(ariable)29 b Fn(LO)m(ADNOISIL)-8 b(Y)150 737 y Fr(whose)29 b(v)-5 b(alue)29 b(is)g(TR)m(UE,)g(then)g(TO) f(commands)h(in)f(the)h(\014le)g(prin)m(t)g Fm(")p Fr(PR)m(OCNAME)g (de\014ned)p Fm(")e Fr(\(where)150 847 y(PR)m(OCNAME)i(is)g(the)h(name) f(of)g(the)g(pro)s(cedure)f(b)s(eing)h(de\014ned\);)g(if)g Fn(LO)m(ADNOISIL)-8 b(Y)41 b Fr(is)29 b(F)-10 b(ALSE)29 b(or)150 956 y(unde\014ned,)f(TO)i(commands)g(in)g(the)h(\014le)f(are)h (carried)f(out)h(silen)m(tly)-8 b(.)275 1105 y(See)30 b([ST)-8 b(AR)g(TUP],)31 b(page)g(90)g(,)g(See)g([LO)m(ADNOISIL)-8 b(Y],)31 b(page)g(89)g(.)150 1356 y Fk(cslsload)390 1575 y Fm(CSLSLOAD)46 b(name)275 1724 y Fr(command.)74 b(Loads)42 b(the)g(named)f(\014le,)k(lik)m(e)e(LO)m(AD,)g(but)e(from)g(the)h (directory)g(con)m(taining)i(the)150 1833 y(Computer)30 b(Science)h(Logo)g(St)m(yle)g(programs)f(instead)h(of)g(the)f(curren)m (t)g(user's)g(directory)-8 b(.)275 1981 y(See)30 b([LO)m(AD],)i(page)f (63)g(.)150 2233 y Fk(help)390 2452 y Fm(HELP)47 b(name)390 2562 y(\(HELP\))275 2710 y Fr(command.)40 b(Prin)m(ts)29 b(information)g(from)g(the)g(reference)h(man)m(ual)g(ab)s(out)f(the)g (primitiv)m(e)h(pro)s(cedure)150 2819 y(named)j(b)m(y)f(the)i(input.)47 b(With)34 b(no)e(input,)h(lists)h(all)g(the)f(primitiv)m(es)g(ab)s(out) g(whic)m(h)g(help)f(is)h(a)m(v)-5 b(ailable.)150 2929 y(If)29 b(there)g(is)g(an)g(en)m(vironmen)m(t)h(v)-5 b(ariable)30 b Fn(LOGOHELP)p Fr(,)f(then)g(its)g(v)-5 b(alue)30 b(is)f(tak)m(en)i(as)e(the)h(directory)f(in)150 3039 y(whic)m(h)h(to)h(lo)s(ok)g(for)f(help)g(\014les,)h(instead)g(of)f (the)h(default)f(help)g(directory)-8 b(.)275 3187 y(If)32 b(HELP)h(is)g(called)i(with)e(the)g(name)g(of)h(a)f(de\014ned)f(pro)s (cedure)g(for)h(whic)m(h)g(there)g(is)h(no)f(help)g(\014le,)150 3296 y(it)g(will)g(prin)m(t)f(the)h(title)h(line)f(of)g(the)f(pro)s (cedure)g(follo)m(w)m(ed)i(b)m(y)e(lines)h(from)f(the)h(pro)s(cedure)e (b)s(o)s(dy)g(that)150 3406 y(start)g(with)f(semicolon,)i(stopping)e (when)f(a)i(non-semicolon)h(line)e(is)h(seen.)275 3554 y(Exceptionally)-8 b(,)36 b(the)e(HELP)f(command)h(can)g(b)s(e)f(used)g (without)g(its)h(default)g(input)f(and)g(without)150 3664 y(paren)m(theses)e(pro)m(vided)f(that)h(nothing)f(follo)m(ws)h(it) g(on)g(the)f(instruction)h(line.)150 3915 y Fk(seteditor)390 4134 y Fm(SETEDITOR)45 b(path)275 4283 y Fr(command.)55 b(T)-8 b(ells)37 b(Logo)f(to)g(use)g(the)f(sp)s(eci\014ed)g(program)g (as)h(its)g(editor)g(instead)f(of)h(the)g(default)150 4392 y(editor.)41 b(The)30 b(format)h(of)f(a)h(path)f(dep)s(ends)f(on)h (y)m(our)g(op)s(erating)h(system.)150 4644 y Fk(setliblo)s(c)390 4863 y Fm(SETLIBLOC)45 b(path)275 5011 y Fr(command.)40 b(T)-8 b(ells)31 b(Logo)h(to)f(use)f(the)h(sp)s(eci\014ed)e(directory)i (as)g(its)g(library)f(instead)g(of)h(the)f(default.)150 5121 y(\(Note)41 b(that)f(man)m(y)g(Logo)g Fm(")p Fr(primitiv)m(e)p Fm(")g Fr(pro)s(cedures)e(are)i(actually)h(found)d(in)h(the)g(library) -8 b(,)42 b(so)e(they)150 5230 y(ma)m(y)31 b(b)s(ecome)g(una)m(v)-5 b(ailable)32 b(if)e(y)m(our)h(new)f(library)g(do)s(es)g(not)h(include)f (them!\))42 b(The)30 b(format)h(of)f(a)h(path)150 5340 y(dep)s(ends)e(on)h(y)m(our)g(op)s(erating)h(system.)p eop end %%Page: 65 66 TeXDict begin 65 65 bop 150 -116 a Fr(Chapter)30 b(7:)41 b(W)-8 b(orkspace)32 b(Managemen)m(t)2078 b(65)150 299 y Fk(setcslslo)s(c)390 518 y Fm(SETCSLSLOC)45 b(path)275 648 y Fr(command.)83 b(T)-8 b(ells)46 b(Logo)g(to)f(use)g(the)g(sp)s (eci\014ed)f(directory)h(for)g(the)g(CSLSLO)m(AD)f(command,)150 758 y(instead)31 b(of)f(the)h(default)f(directory)-8 b(.)42 b(The)30 b(format)h(of)f(a)h(path)f(dep)s(ends)e(on)j(y)m(our)f (op)s(erating)h(system.)275 888 y(See)f([CSLSLO)m(AD],)g(page)h(64)h(.) 150 1099 y Fk(sethelplo)s(c)390 1318 y Fm(SETHELPLOC)45 b(path)275 1449 y Fr(command.)c(T)-8 b(ells)31 b(Logo)h(to)g(lo)s(ok)f (in)f(the)h(sp)s(eci\014ed)f(directory)h(for)g(the)g(information)g(pro) m(vided)f(b)m(y)150 1558 y(the)37 b(HELP)g(command,)i(instead)e(of)h (the)f(default)g(directory)-8 b(.)62 b(The)37 b(format)g(of)g(a)h(path) f(dep)s(ends)e(on)150 1668 y(y)m(our)30 b(op)s(erating)h(system.)150 1879 y Fk(settemplo)s(c)390 2098 y Fm(SETTEMPLOC)45 b(path)275 2228 y Fr(command.)60 b(T)-8 b(ells)38 b(Logo)g(to)g(write)g(editor)f (temp)s(orary)g(\014les)g(in)g(the)g(sp)s(eci\014ed)f(directory)i (rather)150 2338 y(than)23 b(in)h(the)f(default)h(directory)-8 b(.)40 b(Y)-8 b(ou)24 b(m)m(ust)f(ha)m(v)m(e)i(write)f(p)s(ermission)e (for)i(this)f(directory)-8 b(.)40 b(The)23 b(format)150 2448 y(of)31 b(a)f(path)g(dep)s(ends)f(on)h(y)m(our)h(op)s(erating)f (system.)150 2659 y Fk(gc)390 2878 y Fm(GC)390 2988 y(\(GC)47 b(anything\))275 3118 y Fr(command.)k(Runs)33 b(the)i(garbage)g (collector,)j(reclaiming)e(un)m(used)c(no)s(des.)52 b(Logo)35 b(do)s(es)f(this)g(when)150 3227 y(necessary)22 b(an)m(yw)m(a)m(y)-8 b(,)26 b(but)20 b(y)m(ou)i(ma)m(y)h(w)m(an)m(t)f(to)h(use)e(this)h (command)f(to)h(con)m(trol)h(exactly)h(when)c(Logo)j(do)s(es)150 3337 y(it.)40 b(In)27 b(particular,)h(the)g(n)m(um)m(b)s(ers)e(output)g (b)m(y)i(the)f(NODES)g(op)s(eration)h(will)f(not)h(b)s(e)e(v)m(ery)i (meaningful)150 3447 y(unless)33 b(garbage)i(has)f(b)s(een)f (collected.)53 b(Another)34 b(reason)g(to)h(use)e(GC)h(is)g(that)g(a)g (garbage)h(collection)150 3556 y(tak)m(es)d(a)e(noticeable)i(fraction)f (of)f(a)h(second,)f(and)g(y)m(ou)g(ma)m(y)h(w)m(an)m(t)g(to)g(sc)m (hedule)f(collections)j(for)c(times)150 3666 y(b)s(efore)34 b(or)g(after)h(some)g(time-critical)i(animation.)54 b(If)34 b(in)m(v)m(ok)m(ed)i(with)e(an)g(argumen)m(t)h(\(of)g(an)m(y)g(v)-5 b(alue\),)150 3775 y(GC)39 b(runs)f(a)i(full)g(garbage)g(collection,)45 b(including)39 b(GCTW)-10 b(A)40 b(\(Garbage)h(Collect)g(T)-8 b(ruly)39 b(W)-8 b(orthless)150 3885 y(A)m(toms,)30 b(whic)m(h)e(means) g(that)h(it)g(remo)m(v)m(es)g(from)f(Logo's)h(memory)g(w)m(ords)e(that) i(used)f(to)g(b)s(e)g(pro)s(cedure)150 3995 y(or)41 b(v)-5 b(ariable)42 b(names)g(but)e(aren't)i(an)m(y)f(more\);)48 b(without)41 b(an)g(argumen)m(t,)k(GC)c(do)s(es)g(a)h(generational)150 4104 y(garbage)27 b(collection,)i(whic)m(h)d(means)f(that)h(only)g (recen)m(tly)h(created)f(no)s(des)f(are)h(examined.)39 b(\(The)26 b(latter)150 4214 y(is)k(usually)h(go)s(o)s(d)f(enough.\)) 150 4425 y Fk(.setsegmen)m(tsize)390 4644 y Fm(.SETSEGMENTSIZE)44 b(num)275 4774 y Fr(command.)j(Sets)33 b(the)f(n)m(um)m(b)s(er)g(of)h (no)s(des)e(that)j(Logo)f(allo)s(cates)i(from)d(the)h(op)s(erating)g (system)g(at)150 4884 y(once)27 b(to)h(n)m(um,)e(whic)m(h)h(m)m(ush)e (b)s(e)h(a)h(p)s(ositiv)m(e)h(in)m(teger.)41 b(The)26 b(name)h(is)f(dotted)h(b)s(ecause)g(bad)f(things)h(will)150 4994 y(happ)s(en)35 b(if)h(y)m(ou)h(use)f(a)g(n)m(um)m(b)s(er)f(that's) i(to)s(o)g(small)g(or)g(to)s(o)g(large)g(for)f(y)m(our)g(computer.)59 b(The)36 b(initial)150 5103 y(v)-5 b(alue)39 b(is)f(16,000)j(for)c (most)i(systems,)h(but)e(is)g(smaller)h(for)f(68000-based)i(Macs.)65 b(Making)39 b(it)g(larger)150 5213 y(will)32 b(sp)s(eed)f(up)f (computations)i(\(b)m(y)g(reducing)f(the)h(n)m(um)m(b)s(er)e(of)i (garbage)h(collections\))h(at)e(the)g(cost)h(of)150 5322 y(allo)s(cating)g(more)d(memory)g(than)h(necessary)-8 b(.)p eop end %%Page: 66 67 TeXDict begin 66 66 bop 150 -116 a Fr(66)2551 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 67 68 TeXDict begin 67 67 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(67)150 299 y Fp(8)80 b(Con)l(trol)52 b(Structures)150 714 y Fq(8.1)68 b(Con)l(trol)275 970 y Fr(Note:)40 b(in)28 b(the)h(follo)m(wing)g(descriptions,)g(an)f Fm(instructionlist)c Fr(can)k(b)s(e)g(a)g(list)h(or)f(a)h(w)m(ord.)39 b(In)28 b(the)150 1080 y(latter)34 b(case,)i(the)d(w)m(ord)g(is)g (parsed)f(in)m(to)i(list)g(form)f(b)s(efore)g(it)g(is)g(run.)48 b(Th)m(us,)33 b Fm(RUN)47 b(READWORD)31 b Fr(or)i Fm(RUN)150 1190 y(READLIST)27 b Fr(will)i(w)m(ork.)40 b(The)28 b(former)h(is)g (sligh)m(tly)h(preferable)f(b)s(ecause)g(it)g(allo)m(ws)h(for)f(a)g (con)m(tin)m(ued)h(line)150 1299 y(\(with)g Fm(~)p Fr(\))h(that)g (includes)f(a)h(commen)m(t)g(\(with)f(;\))h(on)g(the)f(\014rst)g(line.) 275 1447 y(A)35 b Fm(tf)f Fr(input)g(m)m(ust)h(b)s(e)g(the)g(w)m(ord)g (TR)m(UE,)g(the)h(w)m(ord)e(F)-10 b(ALSE,)35 b(or)g(a)h(list.)55 b(If)35 b(it's)h(a)f(list,)j(then)c(it)150 1556 y(m)m(ust)27 b(b)s(e)g(a)h(Logo)g(expression,)g(whic)m(h)f(will)h(b)s(e)f(ev)-5 b(aluated)28 b(to)g(pro)s(duce)e(a)i(v)-5 b(alue)28 b(that)g(m)m(ust)f (b)s(e)g(TR)m(UE)150 1666 y(or)j(F)-10 b(ALSE.)31 b(The)e(comparisons)i (with)f(TR)m(UE)g(and)g(F)-10 b(ALSE)30 b(are)h(alw)m(a)m(ys)h (case-insensitiv)m(e.)150 1916 y Fk(run)390 2135 y Fm(RUN)47 b(instructionlist)275 2282 y Fr(command)31 b(or)g(op)s(eration.)45 b(Runs)30 b(the)i(Logo)h(instructions)e(in)h(the)f(input)g(list;)i (outputs)e(if)h(the)f(list)150 2392 y(con)m(tains)h(an)e(expression)g (that)h(outputs.)275 2539 y(See)f([READ)m(W)m(ORD],)j(page)e(20)g(,)g ([READLIST],)f(page)h(20)h(.)150 2789 y Fk(runresult)390 3008 y Fm(RUNRESULT)45 b(instructionlist)275 3155 y Fr(runs)24 b(the)i(instructions)g(in)g(the)g(input;)h(outputs)e(an)h(empt)m(y)g (list)h(if)f(those)g(instructions)g(pro)s(duce)f(no)150 3265 y(output,)34 b(or)g(a)g(list)g(whose)f(only)h(mem)m(b)s(er)f(is)h (the)f(output)h(from)f(running)f(the)h(input)g(instructionlist.)150 3374 y(Useful)d(for)g(in)m(v)m(en)m(ting)i(command-or-op)s(eration)g (con)m(trol)f(structures:)390 3522 y Fm(local)46 b("result)390 3631 y(make)h("result)e(runresult)h([something])390 3741 y(if)h(emptyp)f(:result)g([stop])390 3850 y(output)g(first)g(:result) 150 4100 y Fk(rep)s(eat)390 4319 y Fm(REPEAT)g(num)h(instructionlist) 275 4467 y Fr(command.)40 b(Runs)29 b(the)i Fm(instructionlist)26 b Fr(rep)s(eatedly)-8 b(,)31 b Fm(num)f Fr(times.)150 4717 y Fk(forev)m(er)390 4936 y Fm(FOREVER)46 b(instructionlist)275 5083 y Fr(command.)39 b(Runs)25 b(the)i Fm(")p Fr(instructionlist)p Fm(")g Fr(rep)s(eatedly)-8 b(,)29 b(un)m(til)e(something)g(inside)g (the)g(instruction-)150 5193 y(list)k(\(suc)m(h)f(as)h(STOP)e(or)h(THR) m(O)m(W\))i(mak)m(es)f(it)g(stop.)275 5340 y(See)f([STOP],)g(page)h(69) g(,)g(See)f([THR)m(O)m(W],)i(page)f(69)h(.)p eop end %%Page: 68 69 TeXDict begin 68 68 bop 150 -116 a Fr(68)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(rep)s(coun)m(t)390 518 y Fm(REPCOUNT)275 654 y Fr(outputs)d(the)i(rep)s(etition)g(coun)m(t)g(of)g(the)f (innermost)g(curren)m(t)h(REPEA)-8 b(T)28 b(or)g(F)m(OREVER,)h (starting)150 763 y(from)h(1.)41 b(If)30 b(no)g(REPEA)-8 b(T)30 b(or)h(F)m(OREVER)f(is)h(activ)m(e,)i(outputs)c({1.)150 990 y Fk(if)390 1209 y Fm(IF)47 b(tf)g(instructionlist)390 1319 y(\(IF)g(tf)g(instructionlist1)c(instructionlist2\))275 1454 y Fr(command.)d(If)30 b(the)h(\014rst)f(input)f(has)h(the)h(v)-5 b(alue)31 b(TR)m(UE,)g(then)f(IF)h(runs)d(the)j(second)g(input.)40 b(If)30 b(the)150 1564 y(\014rst)f(input)g(has)g(the)h(v)-5 b(alue)31 b(F)-10 b(ALSE,)29 b(then)h(IF)f(do)s(es)h(nothing.)40 b(\(If)30 b(giv)m(en)h(a)f(third)f(input,)g(IF)h(acts)h(lik)m(e)150 1673 y(IFELSE,)26 b(as)i(describ)s(ed)e(b)s(elo)m(w.\))40 b(It)27 b(is)g(an)g(error)g(if)g(the)g(\014rst)f(input)g(is)h(not)h (either)f(TR)m(UE)g(or)g(F)-10 b(ALSE.)275 1809 y(F)i(or)37 b(compatibilit)m(y)i(with)e(earlier)h(v)m(ersions)f(of)g(Logo,)j(if)d (an)g(IF)g(instruction)g(is)g(not)h(enclosed)f(in)150 1919 y(paren)m(theses,)32 b(but)f(the)h(\014rst)f(thing)g(on)h(the)f (instruction)h(line)g(after)g(the)f(second)h(input)f(expression)g(is) 150 2028 y(a)36 b(literal)g(list)g(\(i.e.,)i(a)e(list)g(in)f(square)g (brac)m(k)m(ets\),)j(the)e(IF)f(is)g(treated)h(as)g(if)f(it)h(w)m(ere)f (IFELSE,)g(but)g(a)150 2138 y(w)m(arning)d(message)h(is)f(giv)m(en.)47 b(If)31 b(this)h(ab)s(erran)m(t)g(IF)g(app)s(ears)f(in)h(a)g(pro)s (cedure)f(b)s(o)s(dy)-8 b(,)32 b(the)g(w)m(arning)g(is)150 2247 y(giv)m(en)f(only)g(the)f(\014rst)g(time)h(the)g(pro)s(cedure)e (is)h(in)m(v)m(ok)m(ed)i(in)e(eac)m(h)i(Logo)f(session.)150 2474 y Fk(ifelse)390 2693 y Fm(IFELSE)46 b(tf)h(instructionlist1)d (instructionlist2)275 2829 y Fr(command)34 b(or)h(op)s(eration.)55 b(If)34 b(the)h(\014rst)f(input)g(has)h(the)g(v)-5 b(alue)35 b(TR)m(UE,)g(then)f(IFELSE)g(runs)g(the)150 2938 y(second)h(input.)52 b(If)34 b(the)h(\014rst)e(input)h(has)g(the)h(v)-5 b(alue)35 b(F)-10 b(ALSE,)34 b(then)h(IFELSE)e(runs)g(the)i(third)f(input.)150 3048 y(IFELSE)c(outputs)f(a)i(v)-5 b(alue)31 b(if)f(the)h (instructionlist)g(con)m(tains)h(an)e(expression)g(that)h(outputs)f(a)g (v)-5 b(alue.)150 3274 y Fk(test)390 3494 y Fm(TEST)47 b(tf)275 3629 y Fr(command.)76 b(Remem)m(b)s(ers)42 b(its)g(input,)j (whic)m(h)d(m)m(ust)g(b)s(e)g(TR)m(UE)g(or)h(F)-10 b(ALSE,)42 b(for)g(use)g(b)m(y)g(later)150 3739 y(IFTR)m(UE)32 b(or)h(IFF)-10 b(ALSE)32 b(instructions.)46 b(The)31 b(e\013ect)j(of)e(TEST)f(is)h(lo) s(cal)i(to)f(the)f(pro)s(cedure)f(in)h(whic)m(h)150 3849 y(it)38 b(is)f(used;)j(an)m(y)e(corresp)s(onding)e(IFTR)m(UE)i(or)f (IFF)-10 b(ALSE)37 b(m)m(ust)g(b)s(e)g(in)g(the)g(same)h(pro)s(cedure)e (or)i(a)150 3958 y(subpro)s(cedure.)275 4094 y(See)30 b([IFF)-10 b(ALSE],)31 b(page)g(68)g(.)150 4320 y Fk(iftrue)390 4539 y Fm(IFTRUE)46 b(instructionlist)390 4649 y(IFT)h(instructionlist) 275 4785 y Fr(command.)39 b(Runs)28 b(its)h(input)f(if)g(the)h(most)g (recen)m(t)h(TEST)d(instruction)i(had)f(a)h(TR)m(UE)f(input.)39 b(The)150 4894 y(TEST)29 b(m)m(ust)h(ha)m(v)m(e)i(b)s(een)d(in)i(the)f (same)h(pro)s(cedure)e(or)h(a)h(sup)s(erpro)s(cedure.)150 5121 y Fk(i\013alse)390 5340 y Fm(IFFALSE)46 b(instructionlist)p eop end %%Page: 69 70 TeXDict begin 69 69 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(69)390 299 y Fm(IFF)47 b(instructionlist)275 433 y Fr(command.)39 b(Runs)25 b(its)i(input)f(if)g(the)h(most)g(recen)m(t)g(TEST)e(instruction)i(had) f(a)h(F)-10 b(ALSE)26 b(input.)38 b(The)150 543 y(TEST)29 b(m)m(ust)h(ha)m(v)m(e)i(b)s(een)d(in)i(the)f(same)h(pro)s(cedure)e(or) h(a)h(sup)s(erpro)s(cedure.)275 677 y(See)f([TEST],)g(page)h(68)g(.)150 902 y Fk(stop)390 1121 y Fm(STOP)275 1255 y Fr(command.)38 b(Ends)22 b(the)j(running)d(of)i(the)g(pro)s(cedure)f(in)g(whic)m(h)h (it)g(app)s(ears.)38 b(Con)m(trol)25 b(is)e(returned)g(to)150 1365 y(the)31 b(con)m(text)i(in)e(whic)m(h)f(that)i(pro)s(cedure)e(w)m (as)h(in)m(v)m(ok)m(ed.)44 b(The)31 b(stopp)s(ed)f(pro)s(cedure)f(do)s (es)i(not)g(output)150 1474 y(a)g(v)-5 b(alue.)150 1699 y Fk(output)390 1918 y Fm(OUTPUT)46 b(value)390 2027 y(OP)h(value)275 2162 y Fr(command.)39 b(Ends)28 b(the)g(running)f(of)i (the)g(pro)s(cedure)e(in)i(whic)m(h)f(it)h(app)s(ears.)39 b(That)29 b(pro)s(cedure)e(out-)150 2271 y(puts)g(the)g(v)-5 b(alue)28 b Fm(value)f Fr(to)h(the)g(con)m(text)h(in)e(whic)m(h)g(it)i (w)m(as)e(in)m(v)m(ok)m(ed.)42 b(Don't)28 b(b)s(e)f(confused:)39 b(OUTPUT)150 2381 y(itself)31 b(is)g(a)f(command,)h(but)e(the)i(pro)s (cedure)e(that)i(in)m(v)m(ok)m(es)h(OUTPUT)e(is)g(an)h(op)s(eration.) 150 2605 y Fk(catc)m(h)390 2824 y Fm(CATCH)46 b(tag)h(instructionlist) 275 2959 y Fr(command)31 b(or)h(op)s(eration.)47 b(Runs)30 b(its)j(second)f(input.)45 b(Outputs)31 b(if)h(that)g(instructionlist)h (outputs.)150 3068 y(If,)40 b(while)d(running)f(the)j(instructionlist,) h(a)e(THR)m(O)m(W)h(instruction)f(is)g(executed)h(with)e(a)h(tag)h (equal)150 3178 y(to)f(the)g(\014rst)f(input)f(\(case-insensitiv)m(e)41 b(comparison\),)f(then)d(the)h(running)d(of)j(the)g(instructionlist)g (is)150 3288 y(terminated)44 b(immediately)-8 b(.)83 b(In)43 b(this)g(case)i(the)f(CA)-8 b(TCH)44 b(outputs)f(if)h(a)g(v)-5 b(alue)44 b(input)f(is)g(giv)m(en)i(to)150 3397 y(THR)m(O)m(W.)31 b(The)f Fm(tag)g Fr(m)m(ust)g(b)s(e)g(a)h(w)m(ord.)275 3532 y(If)24 b(the)h(tag)h(is)e(the)h(w)m(ord)f(ERR)m(OR,)h(then)g(an)m (y)g(error)f(condition)h(that)g(arises)g(during)f(the)h(running)e(of) 150 3641 y(the)28 b(instructionlist)h(has)e(the)i(e\013ect)g(of)f(THR)m (O)m(W)h Fm(")p Fr(ERR)m(OR)e(instead)i(of)f(prin)m(ting)f(an)h(error)g (message)150 3751 y(and)h(returning)g(to)h(toplev)m(el.)42 b(The)29 b(CA)-8 b(TCH)29 b(do)s(es)h(not)f(output)g(if)h(an)f(error)g (is)h(caugh)m(t.)42 b(Also,)30 b(during)150 3861 y(the)f(running)e(of)h (the)h(instructionlist,)h(the)f(v)-5 b(ariable)29 b Fn(ERRA)m(CT)35 b Fr(is)29 b(temp)s(orarily)g(un)m(b)s(ound.)37 b(\(If)29 b(there)150 3970 y(is)43 b(an)f(error)g(while)h Fn(ERRA)m(CT)49 b Fr(has)42 b(a)h(v)-5 b(alue,)47 b(that)c(v)-5 b(alue)43 b(is)g(tak)m(en)g(as)g(an)g(instructionlist)g(to)h(b)s(e)150 4080 y(run)36 b(after)i(prin)m(ting)f(the)h(error)e(message.)63 b(T)m(ypically)39 b(the)e(v)-5 b(alue)38 b(of)g Fn(ERRA)m(CT)p Fr(,)f(if)g(an)m(y)-8 b(,)40 b(is)e(the)f(list)150 4189 y([P)-8 b(A)m(USE].\))275 4324 y(See)30 b([ERR)m(OR],)h(page)g(70)g(,)g ([ERRA)m(CT],)g(page)g(89)g(,)g([P)-8 b(A)m(USE],)31 b(page)g(70)g(.)150 4548 y Fk(thro)m(w)390 4767 y Fm(THROW)46 b(tag)390 4877 y(\(THROW)g(tag)h(value\))275 5011 y Fr(command.)59 b(Must)36 b(b)s(e)g(used)g(within)g(the)h(scop)s(e)g(of)g(a)g(CA)-8 b(TCH)36 b(with)g(an)h(equal)g(tag.)60 b(Ends)36 b(the)150 5121 y(running)31 b(of)h(the)h(instructionlist)g(of)f(the)h(CA)-8 b(TCH.)32 b(If)g(THR)m(O)m(W)h(is)g(used)e(with)h(only)h(one)g(input,)f (the)150 5230 y(corresp)s(onding)h(CA)-8 b(TCH)34 b(do)s(es)g(not)g (output)g(a)g(v)-5 b(alue.)52 b(If)34 b(THR)m(O)m(W)h(is)f(used)f(with) h(t)m(w)m(o)i(inputs,)e(the)150 5340 y(second)c(pro)m(vides)h(an)f (output)g(for)g(the)h(CA)-8 b(TCH.)p eop end %%Page: 70 71 TeXDict begin 70 70 bop 150 -116 a Fr(70)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y Fm(THROW)46 b("TOPLEVEL)h Fr(can)i(b)s(e)g(used) f(to)i(terminate)h(all)f(running)d(pro)s(cedures)h(and)h(in)m(teractiv) m(e)150 408 y(pauses,)34 b(and)f(return)g(to)i(the)e(toplev)m(el)j (instruction)e(prompt.)50 b(T)m(yping)33 b(the)h(system)g(in)m(terrupt) f(c)m(har-)150 518 y(acter)k(\(normally)805 515 y Fj(h)p 829 462 289 4 v 829 518 a Fi(con)n(trol-C)p 829 533 V 1113 515 a Fj(i)1179 518 y Fr(for)f(Unix,)1578 515 y Fj(h)p 1602 462 293 4 v 1602 518 a Fi(con)n(trol-Q)p 1602 533 V 1890 515 a Fj(i)1955 518 y Fr(for)g(DOS,)g(or)2468 515 y Fj(h)p 2493 462 518 4 v 2493 518 a Fi(command-p)r(erio)r(d)p 2493 533 V 3006 515 a Fj(i)3071 518 y Fr(for)g(Mac\))h(has)f(the)150 628 y(same)31 b(e\013ect.)275 762 y Fm(THROW)46 b("ERROR)29 b Fr(can)j(b)s(e)e(used)g(to)i(generate)g(an)f(error)g(condition.)43 b(If)31 b(the)g(error)g(is)g(not)g(caugh)m(t,)h(it)150 872 y(prin)m(ts)d(a)g(message)i(\(THR)m(O)m(W)f Fm(")p Fr(ERR)m(OR\))f(with)g(the)g(usual)g(indication)h(of)g(where)e(the)i (error)f(\(in)g(this)150 982 y(case)36 b(the)f(THR)m(O)m(W\))h(o)s (ccurred.)53 b(If)34 b(a)h(second)g(input)f(is)g(used)g(along)i(with)f (a)g(tag)h(of)f(ERR)m(OR,)f(that)150 1091 y(second)26 b(input)g(is)g(used)f(as)i(the)f(text)i(of)e(the)g(error)g(message)i (instead)e(of)h(the)f(standard)g(message.)40 b(Also,)150 1201 y(in)33 b(this)h(case,)i(the)d(lo)s(cation)j(indicated)e(for)f (the)h(error)f(will)h(b)s(e,)g(not)g(the)g(lo)s(cation)h(of)f(the)g (THR)m(O)m(W,)150 1310 y(but)k(the)g(lo)s(cation)i(where)e(the)h(pro)s (cedure)e(con)m(taining)j(the)e(THR)m(O)m(W)h(w)m(as)g(in)m(v)m(ok)m (ed.)66 b(This)38 b(allo)m(ws)150 1420 y(user-de\014ned)27 b(pro)s(cedures)g(to)i(generate)g(error)f(messages)i(as)e(if)g(they)h (w)m(ere)f(primitiv)m(es.)41 b(Note:)g(in)28 b(this)150 1530 y(case)37 b(the)g(corresp)s(onding)e Fm(CATCH)46 b("ERROR)n Fr(,)38 b(if)e(an)m(y)-8 b(,)39 b(do)s(es)d(not)g(output,)i (since)e(the)h(second)f(input)f(to)150 1639 y(THR)m(O)m(W)c(is)g(not)f (considered)g(a)h(return)e(v)-5 b(alue.)275 1774 y Fm(THROW)46 b("SYSTEM)38 b Fr(immediately)j(lea)m(v)m(es)h(Logo,)h(returning)c(to)h (the)g(op)s(erating)g(system,)j(without)150 1884 y(prin)m(ting)32 b(the)g(usual)f(parting)h(message)h(and)f(without)g(deleting)h(an)m(y)f (editor)g(temp)s(orary)g(\014le)g(written)150 1993 y(b)m(y)e(EDIT.)275 2128 y(See)g([EDIT],)h(page)g(61)g(.)150 2353 y Fk(error)390 2572 y Fm(ERROR)275 2707 y Fr(outputs)h(a)h(list)h(describing)e(the)i (error)e(just)g(caugh)m(t,)j(if)e(an)m(y)-8 b(.)49 b(If)33 b(there)g(w)m(as)g(not)g(an)g(error)g(caugh)m(t)150 2817 y(since)k(the)f(last)i(use)e(of)g(ERR)m(OR,)h(the)f(empt)m(y)h(list)g (will)g(b)s(e)f(output.)58 b(The)36 b(error)g(list)h(con)m(tains)h (four)150 2926 y(mem)m(b)s(ers:)h(an)27 b(in)m(teger)i(co)s(de)f (corresp)s(onding)f(to)h(the)g(t)m(yp)s(e)g(of)g(error,)g(the)g(text)h (of)e(the)h(error)g(message,)150 3036 y(the)34 b(name)g(of)g(the)g(pro) s(cedure)f(in)h(whic)m(h)g(the)g(error)f(o)s(ccurred,)i(and)e(the)h (instruction)g(line)g(on)g(whic)m(h)150 3145 y(the)d(error)f(o)s (ccurred.)150 3370 y Fk(pause)390 3589 y Fm(PAUSE)275 3724 y Fr(command)i(or)g(op)s(eration.)47 b(En)m(ters)32 b(an)g(in)m(teractiv)m(e)j(pause.)46 b(The)32 b(user)g(is)g(prompted)f (for)h(instruc-)150 3834 y(tions,)h(as)g(at)g(toplev)m(el,)h(but)e (with)g(a)g(prompt)g(that)g(includes)g(the)g(name)h(of)f(the)g(pro)s (cedure)f(in)h(whic)m(h)150 3943 y(P)-8 b(A)m(USE)43 b(w)m(as)f(in)m(v)m(ok)m(ed.)77 b(Lo)s(cal)43 b(v)-5 b(ariables)43 b(of)f(that)h(pro)s(cedure)e(are)h(a)m(v)-5 b(ailable)45 b(during)c(the)h(pause.)150 4053 y(P)-8 b(A)m(USE)31 b(outputs)f(if)g(the)h(pause)f(is)g(ended)g(b)m(y)g(a)h (CONTINUE)e(with)h(an)h(input.)275 4188 y(If)42 b(the)g(v)-5 b(ariable)44 b Fn(ERRA)m(CT)k Fr(exists,)f(and)42 b(an)g(error)g (condition)h(o)s(ccurs,)j(the)c(con)m(ten)m(ts)j(of)d(that)150 4297 y(v)-5 b(ariable)36 b(are)f(run)f(as)h(an)g(instructionlist.)56 b(T)m(ypically)36 b Fn(ERRA)m(CT)42 b Fr(is)35 b(giv)m(en)h(the)f(v)-5 b(alue)36 b([P)-8 b(A)m(USE])36 b(so)150 4407 y(that)d(an)g(in)m (teractiv)m(e)i(pause)d(will)h(b)s(e)f(en)m(tered)h(on)f(the)h(ev)m(en) m(t)h(of)f(an)f(error.)47 b(This)32 b(allo)m(ws)i(the)e(user)g(to)150 4517 y(c)m(hec)m(k)g(v)-5 b(alues)31 b(of)f(lo)s(cal)i(v)-5 b(ariables)31 b(at)g(the)g(time)g(of)f(the)h(error.)275 4651 y(T)m(yping)37 b(the)h(system)h(quit)e(c)m(haracter)j(\(normally) 2095 4648 y Fj(h)p 2119 4592 285 4 v 2119 4651 a Fi(con)n(trol-)p Fm(\\)p 2119 4667 V 2400 4648 a Fj(i)2467 4651 y Fr(for)e(Unix,)2871 4648 y Fj(h)p 2895 4595 310 4 v 2895 4651 a Fi(con)n(trol-W)p 2895 4667 V 3201 4648 a Fj(i)3268 4651 y Fr(for)g(DOS,)g(or)150 4758 y Fj(h)p 174 4705 542 4 v 174 4761 a Fi(command-comma)p 174 4776 V 711 4758 a Fj(i)771 4761 y Fr(for)30 b(Mac\))i(will)f(also)g (en)m(ter)g(a)g(pause.)275 4896 y(See)f([ERRA)m(CT],)h(page)g(89)g(.) 150 5121 y Fk(con)m(tin)m(ue)390 5340 y Fm(CONTINUE)46 b(value)p eop end %%Page: 71 72 TeXDict begin 71 71 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(71)390 299 y Fm(CO)47 b(value)390 408 y(\(CONTINUE\))390 518 y(\(CO\))275 659 y Fr(command.)j(Ends)32 b(the)i(curren)m(t)g(in)m(teractiv)m(e)i (pause,)f(returning)e(to)h(the)g(con)m(text)i(of)e(the)f(P)-8 b(A)m(USE)150 769 y(in)m(v)m(o)s(cation)30 b(that)e(b)s(egan)g(it.)40 b(If)27 b(CONTINUE)g(is)h(giv)m(en)h(an)e(input,)h(that)g(v)-5 b(alue)29 b(is)e(used)g(as)h(the)g(output)150 879 y(from)i(the)g(P)-8 b(A)m(USE.)32 b(If)d(not,)i(the)g(P)-8 b(A)m(USE)31 b(do)s(es)f(not)g (output.)275 1020 y(Exceptionally)-8 b(,)46 b(the)c(CONTINUE)f(command) g(can)h(b)s(e)f(used)g(without)g(its)h(default)g(input)f(and)150 1130 y(without)30 b(paren)m(theses)h(pro)m(vided)f(that)h(nothing)f (follo)m(ws)i(it)f(on)f(the)h(instruction)f(line.)150 1367 y Fk(w)m(ait)390 1587 y Fm(WAIT)47 b(time)275 1728 y Fr(command.)38 b(Dela)m(ys)27 b(further)c(execution)j(for)e Fm(time)g Fr(60ths)h(of)g(a)g(second.)39 b(Also)25 b(causes)g(an)m(y)g (bu\013ered)150 1837 y(c)m(haracters)42 b(destined)f(for)f(the)h (terminal)h(to)f(b)s(e)g(prin)m(ted)f(immediately)-8 b(.)74 b Fm(WAIT)46 b(0)41 b Fr(can)g(b)s(e)f(used)g(to)150 1947 y(ac)m(hiev)m(e)33 b(this)d(bu\013er)f(\015ushing)g(without)i (actually)h(w)m(aiting.)150 2185 y Fk(b)m(y)m(e)390 2404 y Fm(BYE)275 2545 y Fr(command.)40 b(Exits)31 b(from)f(Logo;)h(returns) e(to)j(the)e(op)s(erating)h(system.)150 2783 y Fk(.ma)m(yb)s(eoutput) 390 3002 y Fm(.MAYBEOUTPUT)44 b(value)j(\(special)e(form\))275 3144 y Fr(w)m(orks)40 b(lik)m(e)i(OUTPUT)e(except)h(that)h(the)e (expression)h(that)g(pro)m(vides)g(the)f(input)g(v)-5 b(alue)41 b(migh)m(t)150 3253 y(not,)32 b(in)g(fact,)h(output)e(a)h(v) -5 b(alue,)32 b(in)g(whic)m(h)f(case)i(the)e(e\013ect)j(is)d(lik)m(e)i (STOP)-8 b(.)31 b(This)g(is)g(in)m(tended)h(for)f(use)150 3363 y(in)39 b(con)m(trol)j(structure)d(de\014nitions,)j(for)d(cases)i (in)e(whic)m(h)h(y)m(ou)g(don't)g(kno)m(w)g(whether)f(or)h(not)g(some) 150 3473 y(expression)30 b(pro)s(duces)f(a)i(v)-5 b(alue.)41 b(Example:)390 3614 y Fm(to)47 b(invoke)f(:function)g([:inputs])f(2)390 3724 y(.maybeoutput)f(apply)j(:function)e(:inputs)390 3833 y(end)390 4052 y(?)i(\(invoke)f("print)g("a)i("b)f("c\))390 4162 y(a)g(b)h(c)390 4271 y(?)f(print)g(\(invoke)f("word)g("a)h("b)g ("c\))390 4381 y(abc)275 4522 y Fr(This)35 b(is)g(an)h(alternativ)m(e)i (to)f(R)m(UNRESUL)-8 b(T.)36 b(It's)g(fast)g(and)f(easy)i(to)f(use,)h (at)g(the)f(cost)g(of)g(b)s(eing)150 4632 y(an)29 b(exception)i(to)f (Logo's)g(ev)-5 b(aluation)31 b(rules.)40 b(\(Ordinarily)-8 b(,)30 b(it)f(should)g(b)s(e)f(an)i(error)e(if)i(the)f(expression)150 4742 y(that's)i(supp)s(osed)e(to)i(pro)m(vide)f(an)g(input)g(to)h (something)g(do)s(esn't)f(ha)m(v)m(e)i(a)e(v)-5 b(alue.\))275 4883 y(See)30 b([OUTPUT],)g(page)i(69)f(,)f([STOP],)g(page)h(69)g(,)g ([R)m(UNRESUL)-8 b(T],)31 b(page)g(67)h(.)150 5121 y Fk(goto)390 5340 y Fm(GOTO)47 b(word)p eop end %%Page: 72 73 TeXDict begin 72 72 bop 150 -116 a Fr(72)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(command.)40 b(Lo)s(oks)29 b(for)h(a)g(T)-8 b(A)m(G)30 b(command)f(with)h(the)f(same)h(input)f(in)g(the)h(same)g (pro)s(cedure,)f(and)150 408 y(con)m(tin)m(ues)38 b(running)c(the)j (pro)s(cedure)e(from)h(the)h(lo)s(cation)h(of)f(that)g(T)-8 b(A)m(G.)38 b(It)e(is)h(meaningless)g(to)g(use)150 518 y(GOTO)30 b(outside)g(of)h(a)g(pro)s(cedure.)150 778 y Fk(tag)390 997 y Fm(TAG)47 b(quoted.word)275 1149 y Fr(command.)c(Do)s(es)32 b(nothing.)43 b(The)31 b(input)f(m)m(ust)h(b)s (e)g(a)h(literal)g(w)m(ord)f(follo)m(wing)i(a)f(quotation)g(mark)150 1259 y(\()p Fm(")p Fr(\),)f(not)g(the)f(result)g(of)h(a)g(computation.) 41 b(T)-8 b(ags)32 b(are)e(used)g(b)m(y)g(the)h(GOTO)e(command.)150 1518 y Fk(ignore)390 1738 y Fm(IGNORE)46 b(value)g(\(library)g (procedure\))275 1890 y Fr(command.)40 b(Do)s(es)31 b(nothing.)40 b(Used)31 b(when)e(an)h(expression)g(is)g(ev)-5 b(aluated)31 b(for)f(a)h(side)f(e\013ect)i(and)e(its)150 1999 y(actual)i(v)-5 b(alue)31 b(is)f(unimp)s(ortan)m(t.)150 2259 y Fk(`)390 2478 y Fm(`)47 b(list)g(\(library)f(procedure\))275 2630 y Fr(outputs)26 b(a)i(list)g(equal)f(to)h(its)g(input)e(but)h(with)g (certain)h(substitutions.)39 b(If)27 b(a)g(mem)m(b)s(er)g(of)g(the)h (input)150 2740 y(list)37 b(is)f(the)g(w)m(ord)g(`)p Fm(,)p Fr(')g(\(comma\))h(then)f(the)g(follo)m(wing)i(mem)m(b)s(er)d (should)g(b)s(e)h(an)g(instructionlist)g(that)150 2850 y(pro)s(duces)j(an)g(output)h(when)f(run.)68 b(That)39 b(output)h(v)-5 b(alue)40 b(replaces)h(the)f(comma)h(and)e(the)h (instruc-)150 2959 y(tionlist.)53 b(If)34 b(a)g(mem)m(b)s(er)g(of)g (the)h(input)e(list)h(is)h(the)f(w)m(ord)g(`)p Fm(,@)p Fr(')g(\(comma)h(atsign\))g(then)f(the)g(follo)m(wing)150 3069 y(mem)m(b)s(er)h(should)g(b)s(e)h(an)g(instructionlist)h(that)f (outputs)g(a)g(list)h(when)e(run.)56 b(The)36 b(mem)m(b)s(ers)f(of)h (that)150 3178 y(list)31 b(replace)g(the)g(`)p Fm(,@)p Fr(')f(and)g(the)h(instructionlist.)41 b(Example:)390 3331 y Fm(show)47 b(`[foo)f(baz)h(,[bf)g([a)g(b)g(c]])g(garply)f(,@[bf) h([a)g(b)g(c]]])275 3483 y Fr(will)30 b(prin)m(t)390 3635 y Fm([foo)47 b(baz)g([b)g(c])g(garply)f(b)h(c])275 3787 y Fr(A)27 b(w)m(ord)g(starting)i(with)e(`)p Fm(,)p Fr(')h(or)f(`)p Fm(,@)p Fr(')h(is)f(treated)i(as)f(if)f(the)h(rest)g (of)f(the)h(w)m(ord)f(w)m(ere)h(a)g(one-w)m(ord)g(list,)150 3897 y(e.g.,)k(`)p Fm(,:foo)p Fr(')d(is)i(equiv)-5 b(alen)m(t)32 b(to)f(`)p Fm(,[:Foo])p Fr('.)275 4049 y(A)24 b(w)m(ord)g(starting)h (with)f(`)p Fm(",)p Fr(')g(\(quote)i(comma\))f(or)f(`)p Fm(:,)p Fr(')h(\(colon)g(comma\))h(b)s(ecomes)e(a)h(w)m(ord)f(starting) 150 4159 y(with)k(`)p Fm(")p Fr(')g(or)h(`)p Fm(:)p Fr(')f(but)f(with)h (the)h(result)f(of)g(running)f(the)h(substitution)g(\(or)h(its)f (\014rst)g(w)m(ord,)g(if)h(the)f(result)150 4268 y(is)i(a)h(list\))h (replacing)f(what)f(comes)h(after)g(the)g(comma.)275 4421 y(Bac)m(kquotes)j(can)f(b)s(e)f(nested.)47 b(Substitution)32 b(is)g(done)g(only)h(for)f(commas)h(at)g(the)g(same)g(depth)f(as)150 4530 y(the)f(bac)m(kquote)g(in)f(whic)m(h)h(they)f(are)h(found:)390 4682 y Fm(?)47 b(show)g(`[a)g(`[b)g(,[1+2])f(,[foo)g(,[1+3])g(d])i(e])f (f])390 4792 y([a)g(`)h([b)f(,)g([1+2])g(,)g([foo)g(4)g(d])g(e])h(f]) 390 5011 y(?make)e("name1)g("x)390 5121 y(?make)g("name2)g("y)390 5230 y(?)h(show)g(`[a)g(`[b)g(,:,:name1)e(,",:name2)g(d])j(e])390 5340 y([a)f(`)h([b)f(,)g([:x])g(,)g(["y])g(d])g(e])p eop end %%Page: 73 74 TeXDict begin 73 73 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(73)150 299 y Fk(for)390 518 y Fm(FOR)47 b(forcontrol)e(instructionlist)f(\(library)h (procedure\))275 657 y Fr(command.)40 b(The)29 b(\014rst)h(input)f(m)m (ust)h(b)s(e)f(a)h(list)h(con)m(taining)g(three)g(or)f(four)f(mem)m(b)s (ers:)40 b(\(1\))31 b(a)f(w)m(ord,)150 767 y(whic)m(h)f(will)h(b)s(e)f (used)g(as)h(the)g(name)g(of)g(a)g(lo)s(cal)h(v)-5 b(ariable;)30 b(\(2\))h(a)f(w)m(ord)g(or)f(list)h(that)h(will)f(b)s(e)f(ev)-5 b(aluated)150 876 y(as)27 b(b)m(y)f(R)m(UN)h(to)g(determine)f(a)h(n)m (um)m(b)s(er,)f(the)g(starting)i(v)-5 b(alue)26 b(of)h(the)f(v)-5 b(ariable;)29 b(\(3\))e(a)g(w)m(ord)f(or)g(list)h(that)150 986 y(will)37 b(b)s(e)f(ev)-5 b(aluated)38 b(to)f(determine)g(a)g(n)m (um)m(b)s(er,)g(the)g(limit)h(v)-5 b(alue)37 b(of)g(the)g(v)-5 b(ariable;)40 b(\(4\))e(an)f(optional)150 1095 y(w)m(ord)j(or)h(list)h (that)f(will)g(b)s(e)f(ev)-5 b(aluated)42 b(to)g(determine)f(the)g (step)g(size.)72 b(If)41 b(the)g(fourth)f(mem)m(b)s(er)g(is)150 1205 y(missing,)32 b(the)g(step)g(size)g(will)g(b)s(e)g(1)g(or)f({1)i (dep)s(ending)d(on)i(whether)f(the)h(limit)g(v)-5 b(alue)32 b(is)g(greater)h(than)150 1315 y(or)d(less)h(than)f(the)h(starting)g(v) -5 b(alue,)31 b(resp)s(ectiv)m(ely)-8 b(.)275 1454 y(The)32 b(second)h(input)g(is)g(an)g(instructionlist.)50 b(The)32 b(e\013ect)j(of)e(F)m(OR)h(is)f(to)h(run)d(that)j(instructionlist)150 1563 y(rep)s(eatedly)-8 b(,)26 b(assigning)e(a)f(new)g(v)-5 b(alue)24 b(to)g(the)f(con)m(trol)i(v)-5 b(ariable)24 b(\(the)g(one)g(named)e(b)m(y)i(the)f(\014rst)g(mem)m(b)s(er)150 1673 y(of)29 b(the)g(forcon)m(trol)h(list\))g(eac)m(h)g(time.)41 b(First)29 b(the)g(starting)h(v)-5 b(alue)29 b(is)g(assigned)g(to)h (the)f(con)m(trol)h(v)-5 b(ariable.)150 1782 y(Then)28 b(the)h(v)-5 b(alue)29 b(is)f(compared)h(to)h(the)e(limit)i(v)-5 b(alue.)41 b(F)m(OR)29 b(is)f(complete)i(when)e(the)h(sign)g(of)f (\(curren)m(t-)150 1892 y(limit\))41 b(is)g(the)f(same)h(as)g(the)f (sign)g(of)h(the)f(step)h(size.)71 b(\(If)40 b(no)h(explicit)g(step)g (size)g(is)f(pro)m(vided,)j(the)150 2002 y(instructionlist)27 b(is)f(alw)m(a)m(ys)h(run)e(at)i(least)g(once.)40 b(An)26 b(explicit)h(step)f(size)h(can)g(lead)f(to)h(a)f(zero-trip)h(F)m(OR,) 150 2111 y(e.g.,)34 b Fm(FOR)47 b([I)g(1)g(0)h(1])f(...)p Fr(\).)e(Otherwise,)32 b(the)g(instructionlist)h(is)e(run,)h(then)f (the)h(step)g(is)g(added)f(to)150 2221 y(the)g(curren)m(t)f(v)-5 b(alue)31 b(of)f(the)h(con)m(trol)g(v)-5 b(ariable)32 b(and)d(F)m(OR)i(returns)e(to)i(the)g(comparison)g(step.)390 2360 y Fm(?)47 b(for)g([i)h(2)f(7)g(1.5])g([print)f(:i])390 2469 y(2)390 2579 y(3.5)390 2689 y(5)390 2798 y(6.5)390 2908 y(?)275 3047 y Fr(See)30 b([R)m(UN],)i(page)f(67)g(.)150 3280 y Fk(do.while)390 3499 y Fm(DO.WHILE)46 b(instructionlist)d (tfexpression)i(\(library)g(procedure\))275 3638 y Fr(command.)122 b(Rep)s(eatedly)59 b(ev)-5 b(aluates)59 b(the)f Fm(instructionlist)c Fr(as)k(long)h(as)f(the)g(ev)-5 b(aluated)150 3748 y Fm(tfexpres-sion)27 b Fr(remains)k(TR)m(UE.)g(Ev)-5 b(aluates)32 b(the)f(\014rst)f(input)g(\014rst,)h(so)g(the)g Fm(instructionlist)c Fr(is)150 3858 y(alw)m(a)m(ys)35 b(run)c(at)j(least)g(once.)50 b(The)33 b Fm(tfexpression)c Fr(m)m(ust)k(b)s(e)g(an)g(expressionlist)g (whose)g(v)-5 b(alue)34 b(when)150 3967 y(ev)-5 b(aluated)32 b(is)e(TR)m(UE)g(or)h(F)-10 b(ALSE.)150 4200 y Fk(while)390 4420 y Fm(WHILE)46 b(tfexpression)f(instructionlist)e(\(library)j (procedure\))275 4559 y Fr(command.)122 b(Rep)s(eatedly)59 b(ev)-5 b(aluates)59 b(the)f Fm(instructionlist)c Fr(as)k(long)h(as)f (the)g(ev)-5 b(aluated)150 4668 y Fm(tfexpres-sion)36 b Fr(remains)k(TR)m(UE.)g(Ev)-5 b(aluates)41 b(the)f(\014rst)f(input)g (\014rst,)j(so)e(the)g Fm(instructionlist)150 4778 y Fr(ma)m(y)35 b(nev)m(er)f(b)s(e)g(run)f(at)i(all.)53 b(The)34 b Fm(tfexpression)d Fr(m)m(ust)j(b)s(e)f(an)h(expressionlist)h (whose)f(v)-5 b(alue)35 b(when)150 4888 y(ev)-5 b(aluated)32 b(is)e(TR)m(UE)g(or)h(F)-10 b(ALSE.)150 5121 y Fk(do.un)m(til)390 5340 y Fm(DO.UNTIL)46 b(instructionlist)d(tfexpression)i(\(library)g (procedure\))p eop end %%Page: 74 75 TeXDict begin 74 74 bop 150 -116 a Fr(74)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(command.)122 b(Rep)s(eatedly)59 b(ev)-5 b(aluates)59 b(the)f Fm(instructionlist)c Fr(as)k(long)h(as)f (the)g(ev)-5 b(aluated)150 408 y Fm(tfexpres-sion)25 b Fr(remains)j(F)-10 b(ALSE.)28 b(Ev)-5 b(aluates)30 b(the)f(\014rst)e(input)h(\014rst,)g(so)h(the)g Fm(instructionlist)24 b Fr(is)150 518 y(alw)m(a)m(ys)35 b(run)c(at)j(least)g(once.)50 b(The)33 b Fm(tfexpression)c Fr(m)m(ust)k(b)s(e)g(an)g(expressionlist)g (whose)g(v)-5 b(alue)34 b(when)150 628 y(ev)-5 b(aluated)32 b(is)e(TR)m(UE)g(or)h(F)-10 b(ALSE.)150 866 y Fk(un)m(til)390 1085 y Fm(UNTIL)46 b(tfexpression)f(instructionlist)e(\(library)j (procedure\))275 1227 y Fr(command.)122 b(Rep)s(eatedly)59 b(ev)-5 b(aluates)59 b(the)f Fm(instructionlist)c Fr(as)k(long)h(as)f (the)g(ev)-5 b(aluated)150 1337 y Fm(tfexpres-sion)34 b Fr(remains)j(F)-10 b(ALSE.)37 b(Ev)-5 b(aluates)38 b(the)g(\014rst)e(input)h(\014rst,)h(so)g(the)f Fm(instructionlist)150 1446 y Fr(ma)m(y)e(nev)m(er)f(b)s(e)g(run)f(at)i(all.)53 b(The)34 b Fm(tfexpression)d Fr(m)m(ust)j(b)s(e)f(an)h(expressionlist)h (whose)f(v)-5 b(alue)35 b(when)150 1556 y(ev)-5 b(aluated)32 b(is)e(TR)m(UE)g(or)h(F)-10 b(ALSE.)150 1795 y Fk(case)390 2014 y Fm(CASE)47 b(value)f(clauses)g(\(library)f(procedure\))275 2156 y Fr(command)30 b(or)h(op)s(eration.)44 b(The)30 b(second)h(input)f(is)i(a)f(list)h(of)f(lists)h(\(clauses\);)h(eac)m(h) f(clause)g(is)f(a)g(list)150 2265 y(whose)e(\014rst)f(elemen)m(t)i(is)f (either)h(a)f(list)g(of)g(v)-5 b(alues)30 b(or)f(the)g(w)m(ord)f(ELSE)g (and)g(whose)h(but\014rst)f(is)h(a)g(Logo)150 2375 y(expression)h(or)g (instruction.)41 b(CASE)29 b(examines)i(the)f(clauses)h(in)f(order.)40 b(If)30 b(a)g(clause)h(b)s(egins)f(with)g(the)150 2484 y(w)m(ord)j(ELSE)e(\(upp)s(er)h(or)h(lo)m(w)m(er)h(case\),)h(then)e (the)g(but\014rst)e(of)i(that)h(clause)f(is)g(ev)-5 b(aluated)34 b(and)f(CASE)150 2594 y(outputs)h(its)g(v)-5 b(alue,)36 b(if)f(an)m(y)-8 b(.)53 b(If)34 b(the)g(\014rst)g(input)f(to)i(CASE)e (is)i(a)f(mem)m(b)s(er)g(of)g(the)h(\014rst)e(elemen)m(t)j(of)f(a)150 2703 y(clause,)f(then)e(the)g(but\014rst)f(of)h(that)h(clause)g(is)g (ev)-5 b(aluated)33 b(and)f(CASE)f(outputs)h(its)h(v)-5 b(alue,)33 b(if)f(an)m(y)-8 b(.)47 b(If)150 2813 y(neither)35 b(of)g(these)h(conditions)f(is)g(met,)i(then)e(CASE)f(go)s(es)i(on)f (to)h(the)f(next)g(clause.)56 b(If)34 b(no)h(clause)h(is)150 2923 y(satis\014ed,)31 b(CASE)e(do)s(es)h(nothing.)41 b(Example:)390 3064 y Fm(to)47 b(vowelp)f(:letter)390 3174 y(output)g(case)h(:letter)f([)h([[a)g(e)g(i)h(o)f(u])g("true])g ([else)f("false])g(])390 3284 y(end)150 3522 y Fk(cond)390 3741 y Fm(COND)h(clauses)e(\(library)h(procedure\))275 3883 y Fr(command)32 b(or)g(op)s(eration.)48 b(The)31 b(input)h(is)g(a)h(list)g(of)g(lists)g(\(clauses\);)i(eac)m(h)f(clause) f(is)f(a)h(list)g(whose)150 3993 y(\014rst)23 b(elemen)m(t)j(is)e (either)g(an)g(expression)g(whose)g(v)-5 b(alue)24 b(is)g(TR)m(UE)h(or) f(F)-10 b(ALSE,)23 b(or)h(the)h(w)m(ord)e(ELSE,)h(and)150 4102 y(whose)k(but\014rst)f(is)i(a)g(Logo)g(expression)f(or)h (instruction.)40 b(COND)28 b(examines)h(the)g(clauses)g(in)f(order.)39 b(If)150 4212 y(a)31 b(clause)g(b)s(egins)f(with)g(the)h(w)m(ord)f (ELSE)f(\(upp)s(er)g(or)i(lo)m(w)m(er)g(case\),)i(then)d(the)g (but\014rst)f(of)i(that)g(clause)150 4322 y(is)g(ev)-5 b(aluated)32 b(and)f(CASE)f(outputs)g(its)i(v)-5 b(alue,)32 b(if)f(an)m(y)-8 b(.)43 b(Otherwise,)32 b(the)f(\014rst)f(elemen)m(t)j (of)e(the)g(clause)150 4431 y(is)g(ev)-5 b(aluated;)32 b(the)e(resulting)h(v)-5 b(alue)31 b(m)m(ust)f(b)s(e)g(TR)m(UE)h(or)f (F)-10 b(ALSE.)30 b(If)g(it's)i(TR)m(UE,)e(then)h(the)f(but\014rst)150 4541 y(of)e(that)g(clause)h(is)e(ev)-5 b(aluated)29 b(and)e(COND)h (outputs)f(its)h(v)-5 b(alue,)29 b(if)e(an)m(y)-8 b(.)41 b(If)27 b(the)h(v)-5 b(alue)28 b(is)g(F)-10 b(ALSE,)27 b(then)150 4650 y(COND)j(go)s(es)g(on)g(to)g(the)g(next)g(clause.)41 b(If)30 b(no)f(clause)i(is)f(satis\014ed,)g(COND)g(do)s(es)f(nothing.) 41 b(Example:)390 4792 y Fm(to)47 b(evens)g(:numbers)e(;)j(select)e (even)g(numbers)g(from)h(a)g(list)390 4902 y(op)g(cond)g([)g([[emptyp)f (:numbers])f([]])867 5011 y([[evenp)h(first)g(:numbers])g(;)h(assuming) f(EVENP)g(is)h(defined)915 5121 y(fput)g(first)f(:numbers)g(evens)g (butfirst)f(:numbers])867 5230 y([else)i(evens)f(butfirst)g(:numbers])f (])390 5340 y(end)p eop end %%Page: 75 76 TeXDict begin 75 75 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(75)150 299 y Fq(8.2)68 b(T)-11 b(emplate-based)46 b(Iteration)275 538 y Fr(The)27 b(pro)s(cedures)f(in)h(this)h(section)h(are)f(iteration)h(to)s(ols)f (based)f(on)h(the)g(idea)g(of)g(a)g Fm(template.)d Fr(This)150 648 y(is)34 b(a)g(generalization)i(of)e(an)g(instruction)g(list)g(or)g (an)g(expression)f(list)i(in)e(whic)m(h)h Fm(slots)e Fr(are)i(pro)m(vided)150 757 y(for)c(the)h(to)s(ol)g(to)g(insert)f(v)-5 b(arying)31 b(data.)41 b(F)-8 b(our)31 b(di\013eren)m(t)g(forms)f(of)g (template)i(can)f(b)s(e)e(used.)275 887 y(The)34 b(most)i(commonly)g (used)f(form)g(for)g(a)h(template)g(is)g(`)p Fm(explicit-slot)p Fr(')c(form,)37 b(or)e(`)p Fm(question)150 996 y(mark)p Fr(')29 b(form.)41 b(Example:)390 1126 y Fm(?)47 b(show)g(map)g([?)g(*) h(?])f([2)g(3)g(4)h(5])390 1235 y([4)f(9)h(16)f(25])390 1345 y(?)275 1474 y Fr(In)31 b(this)h(example,)i(the)e(MAP)h(to)s(ol)g (ev)-5 b(aluated)34 b(the)e(template)i([?)46 b(*)32 b(?])47 b(rep)s(eatedly)-8 b(,)33 b(with)f(eac)m(h)i(of)150 1584 y(the)28 b(mem)m(b)s(ers)f(of)h(the)g(data)g(list)g([2)h(3)f(4)g(5])g (substituted)f(in)h(turn)f(for)g(the)h(question)g(marks.)39 b(The)28 b(same)150 1694 y(v)-5 b(alue)36 b(w)m(as)f(used)g(for)g(ev)m (ery)g(question)h(mark)f(in)g(a)g(giv)m(en)h(ev)-5 b(aluation.)57 b(Some)35 b(to)s(ols)h(allo)m(w)h(for)e(more)150 1803 y(than)g(one)g(datum)f(to)i(b)s(e)e(substituted)h(in)f(parallel;)39 b(in)c(these)g(cases)h(the)f(slots)h(are)f(indicated)h(b)m(y)f(?1)150 1913 y(for)30 b(the)h(\014rst)e(datum,)h(?2)h(for)f(the)h(second,)g (and)e(so)i(on:)390 2042 y Fm(?)47 b(show)g(\(map)g([\(word)f(?1)h(?2)g (?1\)])g([a)g(b)g(c])h([d)f(e)g(f]\))390 2152 y([ada)g(beb)g(cfc])390 2262 y(?)275 2391 y Fr(If)25 b(the)h(template)i(wishes)e(to)g(compute)h (the)f(datum)g(n)m(um)m(b)s(er,)g(the)g(form)g(\(?)39 b(1\))27 b(is)f(equiv)-5 b(alen)m(t)28 b(to)e(?1,)150 2501 y(so)34 b(\(?)50 b(?1\))34 b(means)f(the)h(datum)f(whose)g(n)m(um) m(b)s(er)f(is)i(giv)m(en)g(in)f(datum)g(n)m(um)m(b)s(er)f(1.)51 b(Some)33 b(to)s(ols)h(allo)m(w)150 2610 y(additional)d(slot)h (designations,)f(as)g(sho)m(wn)e(in)h(the)h(individual)f(descriptions.) 275 2740 y(The)g(second)i(form)f(of)g(template)i(is)e(the)h(`)p Fm(named-procedure)p Fr(')27 b(form.)43 b(If)31 b(the)h(template)g(is)g (a)f(w)m(ord)150 2849 y(rather)39 b(than)g(a)g(list,)j(it)d(is)g(tak)m (en)i(as)e(the)g(name)g(of)g(a)h(pro)s(cedure.)65 b(That)39 b(pro)s(cedure)f(m)m(ust)g(accept)150 2959 y(a)h(n)m(um)m(b)s(er)f(of)g (inputs)g(equal)h(to)h(the)f(n)m(um)m(b)s(er)e(of)i(parallel)h(data)f (slots)h(pro)m(vided)e(b)m(y)h(the)g(to)s(ol;)44 b(the)150 3068 y(pro)s(cedure)28 b(is)h(applied)f(to)i(all)g(of)f(the)g(a)m(v)-5 b(ailable)31 b(data)e(in)g(order.)40 b(That)28 b(is,)i(if)f(data)g(?1)g (through)f(?3)i(are)150 3178 y(a)m(v)-5 b(ailable,)33 b(the)e(template)g Fm(")p Fr(PR)m(OC)f(is)g(equiv)-5 b(alen)m(t)32 b(to)f Fm([PROC)47 b(?1)g(?2)g(?3])o Fr(.)390 3308 y Fm(?)g(show)g(\(map)g("word)f([a)h(b)h(c])f([d)g(e)h(f]\))390 3417 y([ad)f(be)g(cf])390 3527 y(?)390 3746 y(to)g(dotprod)f(:a)h(:b)g (;)h(vector)e(dot)h(product)390 3856 y(op)g(apply)g("sum)f(\(map)h ("product)e(:a)j(:b\))390 3965 y(end)275 4095 y Fr(The)37 b(third)f(form)h(of)h(template)h(is)f(`)p Fm(named-slot)p Fr(')d(or)j(`)p Fm(lambda)p Fr(')e(form.)62 b(This)37 b(form)g(is)g(indicated)150 4204 y(b)m(y)g(a)h(template)h(list)f(con)m (taining)h(more)e(than)g(one)h(mem)m(b)s(er,)g(whose)g(\014rst)e(mem)m (b)s(er)h(is)g(itself)h(a)g(list.)150 4314 y(The)32 b(\014rst)g(mem)m (b)s(er)g(is)h(tak)m(en)g(as)g(a)g(list)g(of)g(names;)h(lo)s(cal)g(v)-5 b(ariables)33 b(are)g(created)h(with)e(those)h(names)150 4423 y(and)28 b(giv)m(en)i(the)f(a)m(v)-5 b(ailable)32 b(data)d(in)g(order)g(as)g(their)g(v)-5 b(alues.)40 b(The)29 b(n)m(um)m(b)s(er)e(of)j(names)e(m)m(ust)h(equal)h(the)150 4533 y(n)m(um)m(b)s(er)j(of)h(a)m(v)-5 b(ailable)36 b(data.)53 b(This)33 b(form)h(is)g(needed)g(primarily)f(when)h(one)g(iteration)i (to)s(ol)f(m)m(ust)f(b)s(e)150 4643 y(used)i(within)g(the)g(template)i (list)f(of)g(another,)i(and)d(the)g(?)59 b(notation)38 b(w)m(ould)e(b)s(e)g(am)m(biguous)h(in)f(the)150 4752 y(inner)30 b(template.)42 b(Example:)390 4882 y Fm(to)47 b(matmul)f(:m1)h(:m2)g([:tm2)f(transpose)g(:m2])g(;)i(multiply)d(two)i (matrices)390 4991 y(output)f(map)h([[row])f(map)h([[col])f(dotprod)g (:row)h(:col])f(:tm2])g(:m1)390 5101 y(end)275 5230 y Fr(The)30 b(fourth)h(form)g(is)g(`)p Fm(procedure)d(text)p Fr(')j(form,)g(a)h(v)-5 b(arian)m(t)32 b(of)g(lam)m(b)s(da)f(form.)43 b(In)31 b(this)g(form,)h(the)150 5340 y(template)37 b(list)f(con)m (tains)h(at)f(least)h(t)m(w)m(o)g(mem)m(b)s(ers,)f(all)h(of)e(whic)m(h) h(are)g(lists.)57 b(This)34 b(is)i(the)g(form)f(used)p eop end %%Page: 76 77 TeXDict begin 76 76 bop 150 -116 a Fr(76)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y(b)m(y)e(the)h(DEFINE)g(and)f(TEXT)g(primitiv)m (es,)i(and)e(APPL)-8 b(Y)29 b(accepts)h(it)f(so)g(that)g(the)g(text)g (of)g(a)g(de\014ned)150 408 y(pro)s(cedure)g(can)i(b)s(e)f(used)f(as)i (a)g(template.)275 553 y(Note:)59 b(The)39 b(fourth)g(form)f(of)i (template)g(is)g(in)m(terpreted)f(di\013eren)m(tly)h(from)f(the)h (others,)h(in)e(that)150 663 y(Logo)26 b(considers)g(it)g(to)g(b)s(e)e (an)i(indep)s(enden)m(t)e(de\014ned)g(pro)s(cedure)g(for)h(the)h(purp)s (oses)d(of)j(OUTPUT)f(and)150 772 y(STOP)-8 b(.)30 b(F)-8 b(or)31 b(example,)g(the)g(follo)m(wing)h(t)m(w)m(o)f(instructions)f (are)h(iden)m(tical:)390 917 y Fm(?)47 b(print)g(apply)f([[x])h(:x+3])f ([5])390 1027 y(8)390 1136 y(?)h(print)g(apply)f([[x])h([output)f (:x+3]])g([5])390 1246 y(8)275 1391 y Fr(although)31 b(the)g(\014rst)g(instruction)g(is)g(in)g(named-slot)g(form)g(and)f (the)i(second)f(is)g(in)g(pro)s(cedure-text)150 1500 y(form.)55 b(The)34 b(named-slot)i(form)f(can)h(b)s(e)e(understo)s(o)s (d)g(as)h(telling)i(Logo)f(to)g(ev)-5 b(aluate)37 b(the)e(expression) 150 1610 y Fm(:x+3)f Fr(in)h(place)h(of)f(the)g(en)m(tire)h(in)m(v)m(o) s(cation)i(of)d(apply)-8 b(,)36 b(with)f(the)h(v)-5 b(ariable)35 b(x)g(temp)s(orarily)h(giv)m(en)g(the)150 1720 y(v)-5 b(alue)31 b(5.)41 b(The)30 b(pro)s(cedure-text)g(form)g(can)h(b)s(e)f (understo)s(o)s(d)e(as)j(in)m(v)m(oking)h(the)e(pro)s(cedure)390 1864 y Fm(to)47 b(foo)g(:x)390 1974 y(output)f(:x+3)390 2084 y(end)275 2228 y Fr(with)27 b(input)g(5,)i(but)e(without)h (actually)h(giving)f(the)g(pro)s(cedure)f(a)h(name.)40 b(If)27 b(the)h(use)g(of)g(OUTPUT)150 2338 y(w)m(ere)j(in)m(terc)m (hanged)g(in)g(these)f(t)m(w)m(o)i(examples,)f(w)m(e'd)g(get)g(errors:) 390 2483 y Fm(?)47 b(print)g(apply)f([[x])h(output)f(:x+3])g([5])390 2592 y(Can)h(only)g(use)f(output)h(inside)f(a)h(procedure)390 2702 y(?)g(print)g(apply)f([[x])h([:x+3]])f([5])390 2811 y(You)h(don't)f(say)h(what)g(to)g(do)g(with)g(8)275 2956 y Fr(The)31 b(named-slot)i(form)e(can)i(b)s(e)e(used)g(with)h(STOP)e (or)i(OUTPUT)g(inside)f(a)i(pro)s(cedure,)e(to)i(stop)150 3066 y(the)e(enclosing)g(pro)s(cedure.)275 3211 y(The)38 b(follo)m(wing)j(iteration)g(to)s(ols)f(are)f(extended)g(v)m(ersions)h (of)f(the)g(ones)h(in)f(App)s(endix)e(B)i(of)h(the)150 3320 y(b)s(o)s(ok)p 406 3320 28 5 v 94 w Fl(Computer)p 850 3320 V 40 w(Science)p 1181 3320 V 41 w(Logo)p 1412 3320 V 41 w(St)m(yle,)p 1676 3320 V 41 w(V)-8 b(olume)p 2017 3320 V 41 w(3:)p 2219 3320 V 130 w(Adv)j(anced)p 2649 3320 V 39 w(T)d(opics)p 2940 3320 V 96 w(b)m(y)55 b(Brian)g(Harv)m(ey)150 3430 y([MIT)31 b(Press,)g(1987])p Fr(.)43 b(The)30 b(extensions)h(are)g(primarily)e(to)j(allo)m(w)f(for)g (v)-5 b(ariable)31 b(n)m(um)m(b)s(ers)e(of)h(inputs.)150 3675 y Fk(apply)390 3894 y Fm(APPLY)46 b(template)g(inputlist)275 4039 y Fr(command)f(or)g(op)s(eration.)86 b(Runs)44 b(the)h Fm(")p Fr(template,)p Fm(")i Fr(\014lling)e(its)h(slots)g(with)f(the)g (mem)m(b)s(ers)g(of)150 4148 y Fm(inputlist.)27 b Fr(The)i(n)m(um)m(b)s (er)f(of)h(mem)m(b)s(ers)g(in)g Fm(inputlist)e Fr(m)m(ust)j(b)s(e)e(an) i(acceptable)h(n)m(um)m(b)s(er)e(of)g(slots)150 4258 y(for)37 b Fm(template.)d Fr(It)j(is)g(illegal)i(to)e(apply)g(the)g (primitiv)m(e)g(TO)f(as)i(a)f(template,)j(but)c(an)m(ything)h(else)h (is)150 4367 y(ok)-5 b(a)m(y)d(.)42 b(APPL)-8 b(Y)31 b(outputs)f(what)g Fm(template)e Fr(outputs,)i(if)h(an)m(ything.)275 4512 y(See)f([TO],)h(page)g(49)g(.)150 4757 y Fk(in)m(v)m(ok)m(e)390 4976 y Fm(INVOKE)46 b(template)g(input)g(\(library)g(procedure\))390 5086 y(\(INVOKE)g(template)f(input1)h(input2)h(...\))275 5230 y Fr(command)40 b(or)g(op)s(eration.)72 b(Exactly)42 b(lik)m(e)g(APPL)-8 b(Y)41 b(except)g(that)g(the)g(inputs)f(are)h(pro)m (vided)f(as)150 5340 y(separate)31 b(expressions)f(rather)h(than)f(in)g (a)h(list.)p eop end %%Page: 77 78 TeXDict begin 77 77 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(77)150 299 y Fk(foreac)m(h)390 518 y Fm(FOREACH)46 b(data)g(template)g(\(library)g(procedure\))390 628 y(\(FOREACH)g(data1)g(data2)g(...)h(template\))275 763 y Fr(command.)39 b(Ev)-5 b(aluates)27 b(the)f(template)i(list)f (rep)s(eatedly)-8 b(,)28 b(once)f(for)f(eac)m(h)h(mem)m(b)s(er)e(of)i (the)f(data)h(list.)150 873 y(If)37 b(more)h(than)g(one)g(data)h(list)f (are)g(giv)m(en,)j(eac)m(h)e(of)f(them)g(m)m(ust)g(b)s(e)f(the)h(same)g (length.)64 b(\(The)37 b(data)150 982 y(inputs)29 b(can)i(b)s(e)f(w)m (ords,)g(in)g(whic)m(h)g(case)h(the)g(template)h(is)e(ev)-5 b(aluated)32 b(once)f(for)f(eac)m(h)h(c)m(haracter.)275 1117 y(In)g(a)h(template,)i(the)e(sym)m(b)s(ol)g(?REST)e(represen)m(ts) i(the)g(p)s(ortion)g(of)g(the)g(data)h(input)e(to)h(the)g(righ)m(t)150 1227 y(of)45 b(the)g(mem)m(b)s(er)f(curren)m(tly)g(b)s(eing)g(used)g (as)h(the)g(?)83 b(slot-\014ller.)i(That)44 b(is,)49 b(if)44 b(the)h(data)g(input)f(is)150 1337 y([A)31 b(B)f(C)g(D)h(E])c (and)g(the)g(template)i(is)e(b)s(eing)g(ev)-5 b(aluated)28 b(with)f(?)40 b(replaced)27 b(b)m(y)g(B,)h(then)f(?REST)f(w)m(ould)150 1446 y(b)s(e)34 b(replaced)h(b)m(y)f([C)c(D)h(E].)53 b(If)34 b(m)m(ultiple)h(parallel)h(slots)f(are)g(used,)g(then)f Fm(\(?REST)46 b(1\))34 b Fr(go)s(es)h(with)f(?1,)150 1556 y(etc.)275 1691 y(In)h(a)h(template,)j(the)e(sym)m(b)s(ol)e(#)h (represen)m(ts)g(the)g(p)s(osition)g(in)g(the)g(data)h(input)e(of)h (the)h(mem)m(b)s(er)150 1801 y(curren)m(tly)32 b(b)s(eing)g(used)f(as)h (the)g(?)45 b(slot-\014ller.)i(That)32 b(is,)g(if)g(the)h(data)f(input) f(is)h([A)f(B)g(C)f(D)g(E])i(and)g(the)150 1910 y(template)g(is)e(b)s (eing)g(ev)-5 b(aluated)32 b(with)e(?)40 b(replaced)31 b(b)m(y)f(B,)h(then)f(#)g(w)m(ould)g(b)s(e)g(replaced)h(b)m(y)f(2.)150 2136 y Fk(map)390 2355 y Fm(MAP)47 b(template)e(data)i(\(library)f (procedure\))390 2465 y(\(MAP)h(template)e(data1)i(data2)f(...\))275 2600 y Fr(outputs)32 b(a)h(w)m(ord)g(or)g(list,)i(dep)s(ending)c(on)i (the)g(t)m(yp)s(e)g(of)h(the)f(data)h(input,)e(of)i(the)f(same)g (length)h(as)150 2710 y(that)d(data)g(input.)40 b(\(If)31 b(more)f(than)h(one)f(data)h(input)f(are)h(giv)m(en,)h(the)e(output)g (is)h(of)f(the)h(same)g(t)m(yp)s(e)g(as)150 2819 y(data1.\))44 b(Eac)m(h)32 b(mem)m(b)s(er)e(of)h(the)g(output)g(is)g(the)g(result)g (of)g(ev)-5 b(aluating)33 b(the)e(template)i(list,)f(\014lling)f(the) 150 2929 y(slots)f(with)g(the)g(corresp)s(onding)f(mem)m(b)s(er\(s\))g (of)h(the)g(data)h(input\(s\).)40 b(\(All)31 b(data)f(inputs)f(m)m(ust) h(b)s(e)f(the)150 3039 y(same)h(length.\))42 b(In)29 b(the)h(case)h(of)f(a)g(w)m(ord)g(output,)g(the)g(results)g(of)g(the)g (template)h(ev)-5 b(aluation)32 b(m)m(ust)e(b)s(e)150 3148 y(w)m(ords,)g(and)g(they)g(are)h(concatenated)i(with)d(W)m(ORD.) 275 3284 y(In)h(a)h(template,)i(the)e(sym)m(b)s(ol)g(?REST)e(represen)m (ts)i(the)g(p)s(ortion)g(of)g(the)g(data)h(input)e(to)h(the)g(righ)m(t) 150 3393 y(of)45 b(the)g(mem)m(b)s(er)f(curren)m(tly)g(b)s(eing)g(used) g(as)h(the)g(?)83 b(slot-\014ller.)i(That)44 b(is,)49 b(if)44 b(the)h(data)g(input)f(is)150 3503 y([A)31 b(B)f(C)g(D)h(E])c (and)g(the)g(template)i(is)e(b)s(eing)g(ev)-5 b(aluated)28 b(with)f(?)40 b(replaced)27 b(b)m(y)g(B,)h(then)f(?REST)f(w)m(ould)150 3612 y(b)s(e)34 b(replaced)h(b)m(y)f([C)c(D)h(E].)53 b(If)34 b(m)m(ultiple)h(parallel)h(slots)f(are)g(used,)g(then)f Fm(\(?REST)46 b(1\))34 b Fr(go)s(es)h(with)f(?1,)150 3722 y(etc.)275 3857 y(In)h(a)h(template,)j(the)e(sym)m(b)s(ol)e(#)h (represen)m(ts)g(the)g(p)s(osition)g(in)g(the)g(data)h(input)e(of)h (the)h(mem)m(b)s(er)150 3967 y(curren)m(tly)32 b(b)s(eing)g(used)f(as)h (the)g(?)45 b(slot-\014ller.)i(That)32 b(is,)g(if)g(the)h(data)f(input) f(is)h([A)f(B)g(C)f(D)g(E])i(and)g(the)150 4076 y(template)g(is)e(b)s (eing)g(ev)-5 b(aluated)32 b(with)e(?)40 b(replaced)31 b(b)m(y)f(B,)h(then)f(#)g(w)m(ould)g(b)s(e)g(replaced)h(b)m(y)f(2.)275 4212 y(See)g([W)m(ORD],)i(page)f(9)g(.)150 4438 y Fk(map.se)390 4657 y Fm(MAP.SE)46 b(template)g(data)g(\(library)g(procedure\))390 4766 y(\(MAP.SE)g(template)f(data1)i(data2)f(...\))275 4902 y Fr(outputs)32 b(a)h(list)g(formed)g(b)m(y)f(ev)-5 b(aluating)35 b(the)e(template)h(list)f(rep)s(eatedly)g(and)g (concatenating)i(the)150 5011 y(results)41 b(using)f(SENTENCE.)f(That)i (is,)j(the)d(mem)m(b)s(ers)f(of)h(the)f(output)h(are)g(the)g(mem)m(b)s (ers)f(of)h(the)150 5121 y(results)36 b(of)f(the)h(ev)-5 b(aluations.)59 b(The)35 b(output)g(list)i(migh)m(t,)h(therefore,)g(b)s (e)d(of)h(a)g(di\013eren)m(t)g(length)g(from)150 5230 y(that)h(of)g(the)g(data)g(input\(s\).)58 b(\(If)37 b(the)g(result)f (of)h(an)f(ev)-5 b(aluation)38 b(is)f(the)f(empt)m(y)h(list,)i(it)e (con)m(tributes)150 5340 y(nothing)30 b(to)h(the)g(\014nal)f(output.\)) 41 b(The)30 b(data)h(inputs)e(ma)m(y)i(b)s(e)f(w)m(ords)g(or)g(lists.)p eop end %%Page: 78 79 TeXDict begin 78 78 bop 150 -116 a Fr(78)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(In)h(a)h(template,)i(the)e(sym)m(b)s(ol)g(?REST) e(represen)m(ts)i(the)g(p)s(ortion)g(of)g(the)g(data)h(input)e(to)h (the)g(righ)m(t)150 408 y(of)45 b(the)g(mem)m(b)s(er)f(curren)m(tly)g (b)s(eing)g(used)g(as)h(the)g(?)83 b(slot-\014ller.)i(That)44 b(is,)49 b(if)44 b(the)h(data)g(input)f(is)150 518 y([A)31 b(B)f(C)g(D)h(E])c(and)g(the)g(template)i(is)e(b)s(eing)g(ev)-5 b(aluated)28 b(with)f(?)40 b(replaced)27 b(b)m(y)g(B,)h(then)f(?REST)f (w)m(ould)150 628 y(b)s(e)34 b(replaced)h(b)m(y)f([C)c(D)h(E].)53 b(If)34 b(m)m(ultiple)h(parallel)h(slots)f(are)g(used,)g(then)f Fm(\(?REST)46 b(1\))34 b Fr(go)s(es)h(with)f(?1,)150 737 y(etc.)275 896 y(In)h(a)h(template,)j(the)e(sym)m(b)s(ol)e(#)h (represen)m(ts)g(the)g(p)s(osition)g(in)g(the)g(data)h(input)e(of)h (the)h(mem)m(b)s(er)150 1005 y(curren)m(tly)32 b(b)s(eing)g(used)f(as)h (the)g(?)45 b(slot-\014ller.)i(That)32 b(is,)g(if)g(the)h(data)f(input) f(is)h([A)f(B)g(C)f(D)g(E])i(and)g(the)150 1115 y(template)g(is)e(b)s (eing)g(ev)-5 b(aluated)32 b(with)e(?)40 b(replaced)31 b(b)m(y)f(B,)h(then)f(#)g(w)m(ould)g(b)s(e)g(replaced)h(b)m(y)f(2.)275 1274 y(See)g([SENTENCE],)g(page)h(9)g(.)150 1546 y Fk(\014lter)390 1765 y Fm(FILTER)46 b(tftemplate)f(data)i(\(library)e(procedure\))275 1924 y Fr(outputs)31 b(a)h(w)m(ord)f(or)h(list,)h(dep)s(ending)e(on)g (the)h(t)m(yp)s(e)g(of)g(the)g(data)h(input,)e(con)m(taining)i(a)g (subset)e(of)150 2034 y(the)f(mem)m(b)s(ers)g(\(for)g(a)g(list\))h(or)f (c)m(haracters)i(\(for)e(a)g(w)m(ord\))g(of)h(the)f(input.)40 b(The)29 b(template)j(is)e(ev)-5 b(aluated)150 2143 y(once)37 b(for)f(eac)m(h)i(mem)m(b)s(er)d(or)i(c)m(haracter)g(of)g(the)f(data,)j (and)d(it)h(m)m(ust)f(pro)s(duce)f(a)i(TR)m(UE)f(or)g(F)-10 b(ALSE)150 2253 y(v)-5 b(alue.)58 b(If)36 b(the)g(v)-5 b(alue)36 b(is)g(TR)m(UE,)h(then)e(the)h(corresp)s(onding)f(input)g (constituen)m(t)j(is)e(included)f(in)h(the)150 2362 y(output.)390 2521 y Fm(?)47 b(print)g(filter)f("vowelp)g("elephant)390 2631 y(eea)390 2740 y(?)275 2899 y Fr(In)31 b(a)h(template,)i(the)e (sym)m(b)s(ol)g(?REST)e(represen)m(ts)i(the)g(p)s(ortion)g(of)g(the)g (data)h(input)e(to)h(the)g(righ)m(t)150 3008 y(of)45 b(the)g(mem)m(b)s(er)f(curren)m(tly)g(b)s(eing)g(used)g(as)h(the)g(?)83 b(slot-\014ller.)i(That)44 b(is,)49 b(if)44 b(the)h(data)g(input)f(is) 150 3118 y([A)31 b(B)f(C)g(D)h(E])c(and)g(the)g(template)i(is)e(b)s (eing)g(ev)-5 b(aluated)28 b(with)f(?)40 b(replaced)27 b(b)m(y)g(B,)h(then)f(?REST)f(w)m(ould)150 3228 y(b)s(e)k(replaced)h(b) m(y)f([C)g(D)h(E].)275 3386 y(In)k(a)h(template,)j(the)e(sym)m(b)s(ol)e (#)h(represen)m(ts)g(the)g(p)s(osition)g(in)g(the)g(data)h(input)e(of)h (the)h(mem)m(b)s(er)150 3496 y(curren)m(tly)32 b(b)s(eing)g(used)f(as)h (the)g(?)45 b(slot-\014ller.)i(That)32 b(is,)g(if)g(the)h(data)f(input) f(is)h([A)f(B)g(C)f(D)g(E])i(and)g(the)150 3605 y(template)g(is)e(b)s (eing)g(ev)-5 b(aluated)32 b(with)e(?)40 b(replaced)31 b(b)m(y)f(B,)h(then)f(#)g(w)m(ould)g(b)s(e)g(replaced)h(b)m(y)f(2.)150 3878 y Fk(\014nd)390 4097 y Fm(FIND)47 b(tftemplate)e(data)h(\(library) g(procedure\))275 4256 y Fr(outputs)36 b(the)h(\014rst)f(constituen)m (t)i(of)f(the)g(data)h(input)e(\(the)h(\014rst)f(mem)m(b)s(er)g(of)h(a) g(list,)j(or)d(the)g(\014rst)150 4365 y(c)m(haracter)i(of)f(a)h(w)m (ord\))e(for)h(whic)m(h)f(the)h(v)-5 b(alue)39 b(pro)s(duced)d(b)m(y)h (ev)-5 b(aluating)40 b(the)e(template)h(with)e(that)150 4475 y(consituen)m(t)31 b(in)f(its)h(slot)g(is)g(TR)m(UE.)f(If)g(there) h(is)f(no)h(suc)m(h)f(constituen)m(t,)i(the)e(empt)m(y)h(list)g(is)f (output.)275 4633 y(In)h(a)h(template,)i(the)e(sym)m(b)s(ol)g(?REST)e (represen)m(ts)i(the)g(p)s(ortion)g(of)g(the)g(data)h(input)e(to)h(the) g(righ)m(t)150 4743 y(of)45 b(the)g(mem)m(b)s(er)f(curren)m(tly)g(b)s (eing)g(used)g(as)h(the)g(?)83 b(slot-\014ller.)i(That)44 b(is,)49 b(if)44 b(the)h(data)g(input)f(is)150 4853 y([A)31 b(B)f(C)g(D)h(E])c(and)g(the)g(template)i(is)e(b)s(eing)g(ev)-5 b(aluated)28 b(with)f(?)40 b(replaced)27 b(b)m(y)g(B,)h(then)f(?REST)f (w)m(ould)150 4962 y(b)s(e)k(replaced)h(b)m(y)f([C)g(D)h(E].)275 5121 y(In)k(a)h(template,)j(the)e(sym)m(b)s(ol)e(#)h(represen)m(ts)g (the)g(p)s(osition)g(in)g(the)g(data)h(input)e(of)h(the)h(mem)m(b)s(er) 150 5230 y(curren)m(tly)32 b(b)s(eing)g(used)f(as)h(the)g(?)45 b(slot-\014ller.)i(That)32 b(is,)g(if)g(the)h(data)f(input)f(is)h([A)f (B)g(C)f(D)g(E])i(and)g(the)150 5340 y(template)g(is)e(b)s(eing)g(ev)-5 b(aluated)32 b(with)e(?)40 b(replaced)31 b(b)m(y)f(B,)h(then)f(#)g(w)m (ould)g(b)s(e)g(replaced)h(b)m(y)f(2.)p eop end %%Page: 79 80 TeXDict begin 79 79 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(79)150 299 y Fk(reduce)390 518 y Fm(REDUCE)46 b(template)g(data)g(\(library)g(procedure\))275 650 y Fr(outputs)41 b(the)i(result)f(of)h(applying)f(the)g(template)i (to)f(accum)m(ulate)h(the)f(mem)m(b)s(ers)e(of)i(the)f(data)150 760 y(input.)59 b(The)36 b(template)i(m)m(ust)f(b)s(e)f(a)h(t)m(w)m (o-slot)i(function.)59 b(T)m(ypically)38 b(it)g(is)e(an)h(asso)s (ciativ)m(e)i(function)150 869 y(name)30 b(lik)m(e)h Fm(")p Fr(SUM.)f(If)f(the)h(data)h(input)e(has)g(only)h(one)g (constituen)m(t)i(\(mem)m(b)s(er)d(in)h(a)g(list)g(or)g(c)m(haracter) 150 979 y(in)i(a)h(w)m(ord\),)g(the)f(output)g(is)g(that)h(consituen)m (t.)48 b(Otherwise,)32 b(the)h(template)h(is)e(\014rst)g(applied)g (with)g(?1)150 1089 y(\014lled)j(with)f(the)i(next-to-last)h(consitien) m(t)g(and)d(?2)i(with)e(the)h(last)h(constituen)m(t.)56 b(Then,)35 b(if)g(there)h(are)150 1198 y(more)f(constituen)m(ts,)j(the) d(template)i(is)e(applied)g(with)g(?1)g(\014lled)g(with)g(the)g(next)g (constituen)m(t)i(to)f(the)150 1308 y(left)h(and)e(?2)h(with)g(the)g (result)g(from)f(the)h(previous)g(ev)-5 b(aluation.)58 b(This)35 b(pro)s(cess)h(con)m(tin)m(ues)h(un)m(til)f(all)150 1417 y(constituen)m(ts)c(ha)m(v)m(e)f(b)s(een)f(used.)40 b(The)30 b(data)h(input)e(ma)m(y)i(not)g(b)s(e)e(empt)m(y)-8 b(.)275 1550 y(Note:)40 b(If)27 b(the)h(template)h(is,)g(lik)m(e)g (SUM,)f(the)g(name)f(of)h(a)g(pro)s(cedure)f(that)h(is)g(capable)g(of)g (accepting)150 1659 y(arbitrarily)i(man)m(y)f(inputs,)g(it)h(is)f(more) h(e\016cien)m(t)h(to)f(use)f(APPL)-8 b(Y)30 b(instead)g(of)f(REDUCE.)h (The)f(latter)150 1769 y(is)h(go)s(o)s(d)h(for)f(asso)s(ciativ)m(e)j (pro)s(cedures)c(that)i(ha)m(v)m(e)g(b)s(een)f(written)h(to)g(accept)g (exactly)i(t)m(w)m(o)e(inputs:)390 1901 y Fm(to)47 b(max)g(:a)g(:b)390 2011 y(output)f(ifelse)g(:a)h(>)h(:b)f([:a])g([:b])390 2120 y(end)390 2253 y(print)f(reduce)g("max)h([...])275 2385 y Fr(Alternativ)m(ely)-8 b(,)45 b(REDUCE)39 b(can)h(b)s(e)g(used)f (to)h(write)g(MAX)g(as)g(a)h(pro)s(cedure)d(that)j(accepts)g(an)m(y)150 2494 y(n)m(um)m(b)s(er)29 b(of)i(inputs,)e(as)i(SUM)f(do)s(es:)390 2627 y Fm(to)47 b(max)g([:inputs])e(2)390 2736 y(if)i(emptyp)f(:inputs) g(~)533 2846 y([\(throw)g("error)g([not)h(enough)f(inputs)g(to)h (max]\)])390 2955 y(output)f(reduce)g([ifelse)g(?1)h(>)h(?2)f([?1])f ([?2]])h(:inputs)390 3065 y(end)275 3197 y Fr(See)30 b([SUM],)h(page)g(29)h(,)e([APPL)-8 b(Y],)32 b(page)f(76)g(.)150 3415 y Fk(crossmap)390 3634 y Fm(CROSSMAP)46 b(template)f(listlist)h (\(library)f(procedure\))390 3743 y(\(CROSSMAP)g(template)h(data1)g (data2)h(...\))275 3876 y Fr(outputs)30 b(a)h(list)h(con)m(taining)g (the)g(results)e(of)h(template)i(ev)-5 b(aluations.)43 b(Eac)m(h)32 b(data)g(list)f(con)m(tributes)150 3985 y(to)37 b(a)g(slot)g(in)f(the)g(template;)41 b(the)c(n)m(um)m(b)s(er)e (of)h(slots)h(is)f(equal)h(to)g(the)f(n)m(um)m(b)s(er)f(of)i(data)g (list)g(inputs.)150 4095 y(As)h(a)h(sp)s(ecial)g(case,)j(if)c(only)g (one)h(data)g(list)g(input)f(is)g(giv)m(en,)k(that)d(list)g(is)f(tak)m (en)h(as)g(a)g(list)g(of)f(data)150 4204 y(lists,)32 b(and)e(eac)m(h)i(of)f(its)g(mem)m(b)s(ers)f(con)m(tributes)i(v)-5 b(alues)31 b(to)h(a)f(slot.)43 b(CR)m(OSSMAP)30 b(di\013ers)g(from)h (MAP)150 4314 y(in)39 b(that)i(instead)f(of)f(taking)i(mem)m(b)s(ers)e (from)g(the)h(data)g(inputs)f(in)g(parallel,)44 b(it)c(tak)m(es)h(all)f (p)s(ossible)150 4424 y(com)m(binations)32 b(of)e(mem)m(b)s(ers)g(of)g (data)h(inputs,)f(whic)m(h)g(need)g(not)h(b)s(e)e(the)i(same)g(length.) 390 4556 y Fm(?)47 b(show)g(\(crossmap)e([word)i(?1)g(?2])g([a)g(b)g (c])h([1)f(2)g(3)h(4]\))390 4665 y([a1)f(a2)g(a3)g(a4)g(b1)h(b2)f(b3)g (b4)g(c1)g(c2)h(c3)f(c4])390 4775 y(?)275 4907 y Fr(F)-8 b(or)29 b(compatibilit)m(y)i(with)e(the)g(v)m(ersion)g(in)f(the)h (\014rst)g(edition)g(of)g(CSLS)2732 4874 y Fh(1)2768 4907 y Fr(,)g(CR)m(OSSMAP)f(templates)150 5017 y(ma)m(y)j(use)f(the)h (notation)g(:1)g(instead)g(of)f(?1)h(to)g(indicate)h(slots.)275 5149 y(See)e([MAP],)i(page)f(77)g(.)p 150 5241 1200 4 v 199 5308 a Fh(1)275 5340 y Fg(Computer)25 b(Science)h(Logo)h(St)n (yle)p eop end %%Page: 80 81 TeXDict begin 80 80 bop 150 -116 a Fr(80)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(cascade)390 518 y Fm(CASCADE)46 b(endtest)g(template)f(startvalue)g(\(library)h(procedure\))390 628 y(\(CASCADE)g(endtest)f(tmp1)i(sv1)g(tmp2)g(sv2)f(...\))390 737 y(\(CASCADE)g(endtest)f(tmp1)i(sv1)g(tmp2)g(sv2)f(...)h (finaltemplate\))275 878 y Fr(outputs)41 b(the)g(result)h(of)f (applying)h(a)f(template)i(\(or)f(sev)m(eral)h(templates,)j(as)c (explained)f(b)s(elo)m(w\))150 988 y(rep)s(eatedly)-8 b(,)26 b(with)d(a)h(giv)m(en)g(v)-5 b(alue)24 b(\014lling)f(the)h(slot) g(the)g(\014rst)e(time,)k(and)d(the)g(result)h(of)f(eac)m(h)i (application)150 1097 y(\014lling)31 b(the)f(slot)h(for)f(the)h(follo)m (wing)h(application.)275 1238 y(In)24 b(the)i(simplest)f(case,)j (CASCADE)d(has)g(three)h(inputs.)38 b(The)25 b(second)g(input)g(is)g(a) h(one-slot)h(expres-)150 1348 y(sion)35 b(template.)54 b(That)35 b(template)h(is)e(ev)-5 b(aluated)36 b(some)f(n)m(um)m(b)s (er)e(of)i(times)g(\(p)s(erhaps)f(zero\).)54 b(On)34 b(the)150 1457 y(\014rst)27 b(ev)-5 b(aluation,)31 b(the)d(slot)h(is)g (\014lled)f(with)g(the)g(third)f(input;)i(on)f(subsequen)m(t)f(ev)-5 b(aluations,)30 b(the)f(slot)g(is)150 1567 y(\014lled)k(with)f(the)h (result)g(of)g(the)g(previous)f(ev)-5 b(aluation.)50 b(The)32 b(n)m(um)m(b)s(er)f(of)i(ev)-5 b(aluations)34 b(is)f(determined)150 1677 y(b)m(y)f(the)h(\014rst)e(input.)45 b(This)32 b(can)g(b)s(e)g(either)h(a)f(nonnegativ)m(e)i(in)m(teger,)h (in)d(whic)m(h)g(case)h(the)f(template)i(is)150 1786 y(ev)-5 b(aluated)27 b(that)g(man)m(y)f(times,)h(or)f(a)h(predicate)g (expression)e(template,)k(in)c(whic)m(h)h(case)h(it)g(is)f(ev)-5 b(aluated)150 1896 y(\(with)24 b(the)g(same)h(slot)f(\014ller)g(that)h (will)f(b)s(e)g(used)f(for)h(the)g(ev)-5 b(aluation)25 b(of)f(the)g(second)h(input\))e(rep)s(eatedly)-8 b(,)150 2005 y(and)27 b(the)g(CASCADE)f(ev)-5 b(aluation)29 b(con)m(tin)m(ues)f (as)g(long)f(as)h(the)f(predicate)h(v)-5 b(alue)28 b(is)f(F)-10 b(ALSE.)27 b(\(In)g(other)150 2115 y(w)m(ords,)j(the)h(predicate)g (template)h(indicates)f(the)g(condition)g(for)f(stopping.\))275 2256 y(If)g(the)i(template)g(is)g(ev)-5 b(aluated)32 b(zero)g(times,)h(the)e(output)g(from)g(CASCADE)g(is)g(the)g(third)g (\(start-)150 2365 y(v)-5 b(alue\))31 b(input.)40 b(Otherwise,)30 b(the)g(output)g(is)g(the)g(v)-5 b(alue)31 b(pro)s(duced)d(b)m(y)i(the) h(last)g(template)g(ev)-5 b(aluation.)275 2506 y(CASCADE)32 b(templates)i(ma)m(y)g(include)e(the)h(sym)m(b)s(ol)g(#)g(to)g (represen)m(t)g(the)h(n)m(um)m(b)s(er)d(of)i(times)h(the)150 2616 y(template)39 b(has)f(b)s(een)g(ev)-5 b(aluated.)64 b(This)38 b(slot)g(is)h(\014lled)e(with)h(1)h(for)e(the)i(\014rst)e(ev) -5 b(aluation,)42 b(2)c(for)g(the)150 2725 y(second,)31 b(and)e(so)i(on.)390 2866 y Fm(?)47 b(show)g(cascade)f(5)h([lput)g(#)g (?])g([])390 2976 y([1)g(2)h(3)f(4)h(5])390 3086 y(?)f(show)g(cascade)f ([vowelp)g(first)g(?])h([bf)g(?])g("spring)390 3195 y(ing)390 3305 y(?)g(show)g(cascade)f(5)h([#)h(*)f(?])g(1)390 3414 y(120)390 3524 y(?)275 3665 y Fr(Sev)m(eral)32 b(cascaded)h(results)f (can)g(b)s(e)f(computed)h(in)f(parallel)i(b)m(y)f(pro)m(viding)f (additional)i(template-)150 3774 y(startv)-5 b(alue)33 b(pairs)f(as)h(inputs)e(to)i(CASCADE.)f(In)f(this)h(case,)i(all)g (templates)f(\(including)f(the)h(endtest)150 3884 y(template,)43 b(if)d(used\))f(are)g(m)m(ulti-slot,)44 b(with)39 b(the)h(n)m(um)m(b)s (er)e(of)h(slots)h(equal)g(to)g(the)g(n)m(um)m(b)s(er)e(of)h(pairs)150 3994 y(of)d(inputs.)55 b(In)34 b(eac)m(h)j(round)d(of)i(ev)-5 b(aluations,)38 b(?2)e(represen)m(ts)f(the)h(result)g(of)f(ev)-5 b(aluating)37 b(the)f(second)150 4103 y(template)f(in)f(the)g(previous) g(round.)50 b(If)34 b(the)g(total)i(n)m(um)m(b)s(er)d(of)h(inputs)f (\(including)h(the)g(\014rst)g(endtest)150 4213 y(input\))f(is)h(o)s (dd,)g(then)f(the)h(output)g(from)f(CASCADE)g(is)h(the)g(\014nal)g(v)-5 b(alue)34 b(of)g(the)g(\014rst)f(template.)52 b(If)150 4322 y(the)29 b(total)h(n)m(um)m(b)s(er)d(of)i(inputs)e(is)i(ev)m(en,)h (then)e(the)g(last)i(input)d(is)i(a)g(template)h(that)f(is)f(ev)-5 b(aluated)30 b(once,)150 4432 y(after)h(the)f(end)g(test)h(is)g (satis\014ed,)g(to)g(determine)f(the)h(output)f(from)g(CASCADE.)390 4573 y Fm(to)47 b(fibonacci)e(:n)390 4682 y(output)h(\(cascade)g(:n)h ([?1)g(+)g(?2])g(1)h([?1])e(0\))390 4792 y(end)390 5011 y(to)h(piglatin)f(:word)390 5121 y(output)g(\(cascade)g([vowelp)f (first)i(?])g(~)533 5230 y([word)g(bf)g(?)g(first)g(?])g(~)533 5340 y(:word)g(~)p eop end %%Page: 81 82 TeXDict begin 81 81 bop 150 -116 a Fr(Chapter)30 b(8:)41 b(Con)m(trol)31 b(Structures)2302 b(81)533 299 y Fm([word)47 b(?)g("ay]\))390 408 y(end)150 633 y Fk(cascade.2)390 852 y Fm(CASCADE.2)e(endtest)h(temp1)g(startval1)g(temp2)g(startval2)93 b(\(library)46 b(procedure\))275 986 y Fr(outputs)31 b(the)h(result)g(of)h(in)m(v)m(oking)g(CASCADE)e(with)h(the)g(same)h (inputs.)45 b(The)31 b(only)h(di\013erence)h(is)150 1096 y(that)e(the)g(default)f(n)m(um)m(b)s(er)f(of)i(inputs)e(is)h(\014v)m (e)h(instead)g(of)f(three.)150 1320 y Fk(transfer)390 1539 y Fm(TRANSFER)46 b(endtest)f(template)h(inbasket)f(\(library)h (procedure\))275 1674 y Fr(outputs)37 b(the)i(result)f(of)h(rep)s (eated)f(ev)-5 b(aluation)40 b(of)f(the)f(template.)67 b(The)37 b(template)j(is)f(ev)-5 b(aluated)150 1783 y(once)33 b(for)g(eac)m(h)h(mem)m(b)s(er)e(of)g(the)h(list)g Fm(inbasket.)d Fr(TRANSFER)j(main)m(tains)g(an)g Fm(outbasket)d Fr(that)j(is)150 1893 y(initially)f(the)f(empt)m(y)g(list.)41 b(After)31 b(eac)m(h)h(ev)-5 b(aluation)32 b(of)e(the)h(template,)h(the)f (resulting)g(v)-5 b(alue)31 b(b)s(ecomes)150 2002 y(the)g(new)e (outbask)m(et.)275 2137 y(In)i(the)i(template,)i(the)e(sym)m(b)s(ol)f (?IN)g(represen)m(ts)h(the)g(curren)m(t)f(mem)m(b)s(er)g(from)g(the)h (in)m(bask)m(et;)i(the)150 2247 y(sym)m(b)s(ol)h(?OUT)f(represen)m(ts)h (the)g(en)m(tire)h(curren)m(t)f(outbask)m(et.)59 b(Other)36 b(slot)h(sym)m(b)s(ols)e(should)g(not)i(b)s(e)150 2356 y(used.)275 2491 y(If)28 b(the)h(\014rst)f(\(endtest\))i(input)e(is)h (an)g(empt)m(y)g(list,)h(ev)-5 b(aluation)31 b(con)m(tin)m(ues)f(un)m (til)f(all)h(in)m(bask)m(et)g(mem-)150 2600 y(b)s(ers)j(ha)m(v)m(e)i(b) s(een)f(used.)51 b(If)34 b(not,)h(the)f(\014rst)g(input)f(m)m(ust)h(b)s (e)f(a)i(predicate)g(expression)f(template,)j(and)150 2710 y(ev)-5 b(aluation)31 b(con)m(tin)m(ues)g(un)m(til)e(either)h (that)g(template's)i(v)-5 b(alue)29 b(is)h(TR)m(UE)g(or)f(the)h(in)m (bask)m(et)g(is)g(used)f(up.)p eop end %%Page: 82 83 TeXDict begin 82 82 bop 150 -116 a Fr(82)2551 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 83 84 TeXDict begin 83 83 bop 150 -116 a Fr(Chapter)30 b(9:)41 b(Macros)2759 b(83)150 299 y Fp(9)80 b(Macros)150 588 y Fk(.macro)390 807 y Fm(.MACRO)46 b(procname)g(:input1)f(:input2)h (...)95 b(\(special)45 b(form\))390 917 y(.DEFMACRO)g(procname)h(text) 275 1046 y Fr(A)26 b(macro)h(is)f(a)h(sp)s(ecial)g(kind)e(of)i(pro)s (cedure)e(whose)h(output)g(is)h(ev)-5 b(aluated)27 b(as)g(Logo)g (instructions)f(in)150 1156 y(the)d(con)m(text)h(of)f(the)f(macro's)i (caller.)39 b(.MA)m(CR)m(O)23 b(is)g(exactly)h(lik)m(e)g(TO)e(except)h (that)g(the)g(new)f(pro)s(cedure)150 1265 y(b)s(ecomes)31 b(a)f(macro;)i(.DEFMA)m(CR)m(O)g(is)e(exactly)i(lik)m(e)g(DEFINE)f (with)f(the)g(same)h(exception.)275 1395 y(Macros)d(are)h(useful)e(for) h(in)m(v)m(en)m(ting)h(new)e(con)m(trol)j(structures)d(comparable)i(to) f(REPEA)-8 b(T,)28 b(IF,)h(and)150 1504 y(so)34 b(on.)50 b(Suc)m(h)33 b(con)m(trol)i(structures)e(can)h(almost,)h(but)e(not)h (quite,)h(b)s(e)e(duplicated)h(b)m(y)f(ordinary)g(Logo)150 1614 y(pro)s(cedures.)39 b(F)-8 b(or)32 b(example,)f(here)f(is)h(an)f (ordinary)f(pro)s(cedure)h(v)m(ersion)h(of)f(REPEA)-8 b(T:)390 1743 y Fm(to)47 b(my.repeat)e(:num)i(:instructions)390 1853 y(if)g(:num=0)f([stop])390 1963 y(run)h(:instructions)390 2072 y(my.repeat)e(:num-1)h(:instructions)390 2182 y(end)275 2311 y Fr(This)29 b(v)m(ersion)i(w)m(orks)f(\014ne)g(for)g(most)h(purp) s(oses,)e(e.g.,)390 2441 y Fm(my.repeat)45 b(5)j([print)e("hello])275 2570 y Fr(But)36 b(it)h(do)s(esn't)f(w)m(ork)g(if)g(the)h(instructions) f(to)h(b)s(e)f(carried)g(out)h(include)f(OUTPUT,)f(STOP)-8 b(,)36 b(or)150 2680 y(LOCAL.)30 b(F)-8 b(or)31 b(example,)g(consider)f (this)h(pro)s(cedure:)390 2809 y Fm(to)47 b(example)390 2919 y(print)f([Guess)g(my)i(secret)e(word.)94 b(You)47 b(get)g(three)f(guesses.])390 3029 y(repeat)g(3)i([type)e("|??)h(|)g(~) 533 3138 y(if)g(readword)f(=)h("secret)f([pr)h("Right!)f(stop]])390 3248 y(print)g([Sorry,)g(the)h(word)g(was)g("secret"!])390 3357 y(end)275 3487 y Fr(This)36 b(pro)s(cedure)f(w)m(orks)i(as)g (written,)i(but)d(if)h(MY.REPEA)-8 b(T)37 b(is)g(used)f(instead)h(of)g (REPEA)-8 b(T,)36 b(it)150 3597 y(w)m(on't)e(w)m(ork)g(b)s(ecause)g (the)g(STOP)e(will)i(stop)g(MY.REPEA)-8 b(T)34 b(instead)g(of)g (stopping)g(EXAMPLE)g(as)150 3706 y(desired.)275 3836 y(The)j(solution)i(is)g(to)g(mak)m(e)g(MY.REPEA)-8 b(T)39 b(a)g(macro.)65 b(Instead)38 b(of)h(actually)h(carrying)e(out)h(the)150 3945 y(computation,)28 b(a)f(macro)g(m)m(ust)f(return)g(a)g(list)h(con) m(taining)h(Logo)g(instructions.)39 b(The)26 b(con)m(ten)m(ts)i(of)e (that)150 4055 y(list)40 b(are)f(ev)-5 b(aluated)40 b(as)f(if)g(they)g (app)s(eared)g(in)f(place)i(of)f(the)g(call)i(to)e(the)g(macro.)67 b(Here's)40 b(a)f(macro)150 4164 y(v)m(ersion)31 b(of)f(REPEA)-8 b(T:)390 4294 y Fm(.macro)46 b(my.repeat)f(:num)i(:instructions)390 4403 y(if)g(:num=0)f([output)g([]])390 4513 y(output)g(sentence)g (:instructions)e(~)533 4623 y(\(list)j("my.repeat)e(:num-1)h (:instructions\))390 4732 y(end)275 4862 y Fr(Ev)m(ery)26 b(macro)h(is)f(an)g(op)s(eration)g(|)g(it)h(m)m(ust)f(alw)m(a)m(ys)i (output)d(something.)40 b(Ev)m(en)26 b(in)g(the)g(base)h(case,)150 4971 y(MY.REPEA)-8 b(T)35 b(outputs)e(an)h(empt)m(y)g(instruction)g (list.)53 b(T)-8 b(o)34 b(sho)m(w)g(ho)m(w)g(MY.REPEA)-8 b(T)35 b(w)m(orks,)g(let's)150 5081 y(tak)m(e)d(the)f(example)390 5210 y Fm(my.repeat)45 b(5)j([print)e("hello])275 5340 y Fr(F)-8 b(or)31 b(this)f(example,)h(MY.REPEA)-8 b(T)31 b(will)g(output)f(the)g(instruction)h(list)p eop end %%Page: 84 85 TeXDict begin 84 84 bop 150 -116 a Fr(84)2551 b(BERKELEY)30 b(LOGO)g(5.5)390 299 y Fm([print)46 b("hello)g(my.repeat)f(4)j([print)e ("hello]])275 430 y Fr(Logo)23 b(then)f(executes)i(these)e (instructions)h(in)f(place)h(of)f(the)h(original)g(in)m(v)m(o)s(cation) i(of)d(MY.REPEA)-8 b(T;)150 540 y(this)30 b(prin)m(ts)g Fm(hello)f Fr(once)i(and)f(in)m(v)m(ok)m(es)i(another)f(rep)s(etition.) 275 671 y(The)36 b(tec)m(hnique)h(just)f(sho)m(wn,)h(although)g(fairly) g(easy)g(to)h(understand,)e(has)g(the)h(defect)g(of)g(slo)m(w-)150 781 y(ness)g(b)s(ecause)h(eac)m(h)g(rep)s(etition)g(has)g(to)g (construct)g(an)f(instruction)h(list)g(for)f(ev)-5 b(aluation.)64 b(Another)150 891 y(approac)m(h)34 b(is)g(to)g(mak)m(e)g(m)m(y)-8 b(.rep)s(eat)35 b(a)f(macro)g(that)g(w)m(orks)g(just)f(lik)m(e)i(the)f (non-macro)g(v)m(ersion)g(unless)150 1000 y(the)d(instructions)f(to)h (b)s(e)f(rep)s(eated)g(include)g(OUTPUT)g(or)g(STOP:)390 1132 y Fm(.macro)46 b(my.repeat)f(:num)i(:instructions)390 1241 y(catch)f("repeat.catchtag)e(~)533 1351 y([op)j(repeat.done)e (runresult)g([repeat1)h(:num)g(:instructions]])390 1461 y(op)h([])390 1570 y(end)390 1789 y(to)g(repeat1)f(:num)h (:instructions)390 1899 y(if)g(:num=0)f([throw)g("repeat.catchtag])390 2008 y(run)h(:instructions)390 2118 y(.maybeoutput)d(repeat1)i(:num-1)g (:instructions)390 2228 y(end)390 2447 y(to)h(repeat.done)e (:repeat.result)390 2556 y(if)i(emptyp)f(:repeat.result)e([op)j ([stop]])390 2666 y(op)g(list)g("output)f(quoted)g(first)g (:repeat.result)390 2776 y(end)275 2907 y Fr(If)38 b(the)i (instructions)f(do)g(not)g(include)g(STOP)f(or)h(OUTPUT,)g(then)g (REPEA)-8 b(T1)39 b(will)h(reac)m(h)g(its)150 3017 y(base)30 b(case)h(and)e(in)m(v)m(ok)m(e)j(THR)m(O)m(W.)f(As)f(a)g(result,)g(m)m (y)-8 b(.rep)s(eat's)31 b(last)g(instruction)f(line)g(will)h(output)e (an)150 3126 y(empt)m(y)37 b(list,)h(so)e(the)h(second)f(ev)-5 b(aluation)38 b(of)e(the)g(macro)h(result)f(will)g(do)g(nothing.)58 b(But)37 b(if)f(a)g(STOP)150 3236 y(or)27 b(OUTPUT)g(happ)s(ens,)f (then)i(REPEA)-8 b(T.DONE)27 b(will)h(output)f(a)h(STOP)e(or)h(OUTPUT)g (instruction)150 3345 y(that)k(will)g(b)s(e)e(re-executed)j(in)e(the)h (caller's)g(con)m(text.)275 3477 y(The)j(macro-de\014ning)h(commands)g (ha)m(v)m(e)i(names)e(starting)h(with)f(a)g(dot)h(b)s(ecause)f(macros)g (are)h(an)150 3587 y(adv)-5 b(anced)44 b(feature)g(of)g(Logo;)53 b(it's)44 b(easy)h(to)f(get)h(in)f(trouble)g(b)m(y)g(de\014ning)f(a)h (macro)h(that)f(do)s(esn't)150 3696 y(terminate,)32 b(or)e(b)m(y)g (failing)i(to)f(construct)f(the)h(instruction)f(list)h(prop)s(erly)-8 b(.)275 3828 y(Lisp)29 b(users)h(should)f(note)i(that)g(Logo)h(macros)f (are)f(NOT)g(sp)s(ecial)h(forms.)40 b(That)31 b(is,)f(the)h(inputs)e (to)150 3937 y(the)e(macro)g(are)h(ev)-5 b(aluated)28 b(normally)-8 b(,)28 b(as)f(they)g(w)m(ould)g(b)s(e)f(for)g(an)m(y)h (other)g(Logo)h(pro)s(cedure.)39 b(It's)27 b(only)150 4047 y(the)k(output)f(from)f(the)i(macro)g(that's)g(handled)f(un)m (usually)-8 b(.)275 4178 y(Here's)31 b(another)f(example:)390 4310 y Fm(.macro)46 b(localmake)f(:name)i(:value)390 4419 y(output)f(\(list)g("local~)533 4529 y(word)h("")g(:name)142 b(~)533 4639 y("apply)476 b(~)533 4748 y(""make)g(~)533 4858 y(\(list)47 b(:name)f(:value\)\))390 4967 y(end)275 5099 y Fr(It's)30 b(used)g(this)g(w)m(a)m(y:)390 5230 y Fm(to)47 b(try)390 5340 y(localmake)e("garply)h("hello)p eop end %%Page: 85 86 TeXDict begin 85 85 bop 150 -116 a Fr(Chapter)30 b(9:)41 b(Macros)2759 b(85)390 299 y Fm(print)46 b(:garply)390 408 y(end)275 543 y Fr(LOCALMAKE)29 b(outputs)h(the)h(list)390 677 y([lo)s(cal)h Fm(")p Fr(garply)e(apply)g Fm(")p Fr(mak)m(e)h ([garply)g(hello]])275 812 y(The)26 b(reason)h(for)g(the)g(use)g(of)g (APPL)-8 b(Y)28 b(is)f(to)h(a)m(v)m(oid)g(ha)m(ving)g(to)f(decide)h (whether)e(or)h(not)h(the)f(second)150 922 y(input)41 b(to)h(MAKE)f(requires)g(a)h(quotation)h(mark)e(b)s(efore)g(it.)74 b(\(In)42 b(this)f(case)h(it)g(w)m(ould)g(|)f(MAKE)150 1031 y Fm(")p Fr(GARPL)-8 b(Y)31 b Fm(")p Fr(HELLO)e(|)h(but)g(the)h (quotation)g(mark)f(w)m(ould)h(b)s(e)e(wrong)h(if)h(the)f(v)-5 b(alue)31 b(w)m(ere)g(a)g(list.\))275 1166 y(It's)f(often)h(con)m(v)m (enien)m(t)h(to)g(use)e(the)g Fm(`)g Fr(function)g(to)h(construct)g (the)g(instruction)f(list:)390 1300 y Fm(.macro)46 b(localmake)f(:name) i(:value)390 1410 y(op)g(`[local)f(,[word)g("")h(:name])f(apply)h ("make)f([,[:name])f(,[:value]]])390 1519 y(end)275 1654 y Fr(On)29 b(the)i(other)f(hand,)g Fm(`)g Fr(is)g(prett)m(y)h(slo)m(w,) g(since)g(it's)g(tree)g(recursiv)m(e)g(and)f(written)g(in)g(Logo.)275 1788 y(See)i([TO],)f(page)i(49)g(,)f([DEFINE],)h(page)g(50)f(,)h([APPL) -8 b(Y],)33 b(page)f(76)h(,)f([STOP],)f(page)i(69)g(,)f([OUT-)150 1898 y(PUT],)f(page)g(69)g(.)150 2122 y Fk(.defmacro)275 2366 y Fr(See)f([dMA)m(CR)m(O],)h(page)h(83)f(.)150 2590 y Fk(macrop)390 2809 y Fm(MACROP)46 b(name)390 2919 y(MACRO?)g(name)275 3054 y Fr(outputs)29 b(TR)m(UE)i(if)f(its)h(input)e(is)i(the)f(name)h (of)f(a)h(macro.)150 3278 y Fk(macro)s(expand)390 3497 y Fm(MACROEXPAND)45 b(expr)h(\(library)g(procedure\))275 3631 y Fr(tak)m(es)31 b(as)f(its)g(input)f(a)i(Logo)g(expression)e (that)i(in)m(v)m(ok)m(es)g(a)g(macro)f(\(that)h(is,)f(one)g(that)h(b)s (egins)e(with)150 3741 y(the)39 b(name)f(of)g(a)h(macro\))g(and)f (outputs)g(the)g(the)h(Logo)g(expression)f(in)m(to)i(whic)m(h)e(the)g (macro)h(w)m(ould)150 3851 y(translate)32 b(the)e(input)g(expression.) 390 3985 y Fm(.macro)46 b(localmake)f(:name)i(:value)390 4095 y(op)g(`[local)f(,[word)g("")h(:name])f(apply)h("make)f([,[:name]) f(,[:value]]])390 4204 y(end)390 4423 y(?)i(show)g(macroexpand)e ([localmake)g("pi)i(3.14159])390 4533 y([local)f("pi)h(apply)f("make)h ([pi)g(3.14159]])p eop end %%Page: 86 87 TeXDict begin 86 86 bop 150 -116 a Fr(86)2551 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 87 88 TeXDict begin 87 87 bop 150 -116 a Fr(Chapter)30 b(10:)41 b(Error)30 b(Pro)s(cessing)2335 b(87)150 299 y Fp(10)80 b(Error)53 b(Pro)t(cessing)275 566 y Fr(If)30 b(an)g(error)g(o)s (ccurs,)h(Logo)h(tak)m(es)g(the)e(follo)m(wing)i(steps.)42 b(First,)31 b(if)f(there)h(is)g(an)f(a)m(v)-5 b(ailable)33 b(v)-5 b(ariable)150 676 y(named)30 b Fn(ERRA)m(CT)p Fr(,)g(Logo)h(tak)m(es)g(its)g(v)-5 b(alue)30 b(as)h(an)f (instructionlist)h(and)e(runs)g(the)h(instructions.)40 b(The)150 785 y(op)s(eration)31 b(ERR)m(OR)f(ma)m(y)h(b)s(e)f(used)g (within)g(the)g(instructions)h(\(once\))g(to)h(examine)f(the)f(error)h (condi-)150 895 y(tion.)59 b(If)35 b(the)i(instructionlist)g(in)m(v)m (ok)m(es)h(P)-8 b(A)m(USE,)37 b(the)f(error)g(message)h(is)f(prin)m (ted)g(b)s(efore)g(the)g(pause)150 1004 y(happ)s(ens.)i(Certain)27 b(errors)g(are)g Fm(")p Fr(reco)m(v)m(erable)p Fm(")p Fr(;)j(for)d(one)g(of)g(those)h(errors,)f(if)g(the)h(instructionlist)f (out-)150 1114 y(puts)21 b(a)i(v)-5 b(alue,)25 b(that)e(v)-5 b(alue)23 b(is)f(used)f(in)h(place)i(of)e(the)h(expression)f(that)h (caused)f(the)g(error.)38 b(\(If)22 b Fn(ERRA)m(CT)150 1223 y Fr(in)m(v)m(ok)m(es)32 b(P)-8 b(A)m(USE)31 b(and)f(the)g(user)g (then)g(in)m(v)m(ok)m(es)i(CONTINUE)e(with)g(an)g(input,)g(that)h (input)f(b)s(ecomes)150 1333 y(the)h(output)f(from)f(P)-8 b(A)m(USE)31 b(and)f(therefore)h(the)f(output)g(from)g(the)h Fn(ERRA)m(CT)36 b Fr(instructionlist.\))275 1479 y(It)g(is)g(p)s (ossible)g(for)f(an)h Fn(ERRA)m(CT)43 b Fr(instructionlist)37 b(to)f(pro)s(duce)f(an)h(inappropriate)g(v)-5 b(alue)37 b(or)f(no)150 1588 y(v)-5 b(alue)26 b(where)f(one)g(is)h(needed.)38 b(As)26 b(a)f(result,)i(the)e(same)h(error)f(condition)h(could)f(recur) g(forev)m(er)h(b)s(ecause)150 1698 y(of)k(this)g(mec)m(hanism.)40 b(T)-8 b(o)31 b(a)m(v)m(oid)g(that)f(danger,)g(if)g(the)g(same)g(error) f(condition)i(o)s(ccurs)e(t)m(wice)i(in)f(a)g(ro)m(w)150 1807 y(from)38 b(an)g Fn(ERRA)m(CT)44 b Fr(instructionlist)39 b(without)f(user)f(in)m(teraction,)42 b(the)d(message)g Fm(")p Fr(Erract)f(lo)s(op)p Fm(")g Fr(is)150 1917 y(prin)m(ted)25 b(and)f(con)m(trol)j(returns)c(to)j(toplev)m(el.)41 b Fm(")p Fr(Without)26 b(user)e(in)m(teraction)p Fm(")j Fr(means)e(that)g(if)g Fn(ERRA)m(CT)150 2026 y Fr(in)m(v)m(ok)m(es)35 b(P)-8 b(A)m(USE)35 b(and)e(the)h(user)f(pro)m(vides)g(an)h(incorrect)g (v)-5 b(alue,)36 b(this)d(lo)s(op)h(prev)m(en)m(tion)h(mec)m(hanism)150 2136 y(do)s(es)30 b(not)h(tak)m(e)h(e\013ect)g(and)d(the)i(user)f(gets) h(to)g(try)f(again.)275 2282 y(During)c(the)h(running)d(of)j(the)g Fn(ERRA)m(CT)33 b Fr(instructionlist,)28 b Fn(ERRA)m(CT)33 b Fr(is)26 b(lo)s(cally)i(un)m(b)s(ound,)d(so)i(an)150 2391 y(error)h(in)f(the)h Fn(ERRA)m(CT)35 b Fr(instructions)27 b(themselv)m(es)j(will)e(not)g(cause)h(a)f(lo)s(op.)40 b(In)27 b(particular,)i(an)f(error)150 2501 y(during)37 b(a)i(pause)g(will)g(not)f(cause)h(a)g(pause-within-a-pause)g(unless)f (the)h(user)f(reassigns)h(the)f(v)-5 b(alue)150 2610 y([P)d(A)m(USE])35 b(to)g Fn(ERRA)m(CT)40 b Fr(during)33 b(the)h(pause.)51 b(But)34 b(suc)m(h)g(an)g(error)f(will)i(not)f (return)f(to)h(toplev)m(el;)k(it)150 2720 y(will)31 b(remain)f(within)g (the)g(original)i(pause)e(lo)s(op.)275 2865 y(If)h(there)i(is)f(no)g(a) m(v)-5 b(ailable)35 b Fn(ERRA)m(CT)j Fr(v)-5 b(alue,)34 b(Logo)f(handles)f(the)g(error)g(b)m(y)g(generating)i(an)e(in)m(ter-) 150 2975 y(nal)j Fm(THROW)47 b("ERROR)n Fr(.)55 b(\(A)36 b(user)e(program)h(can)h(also)g(generate)g(an)f(error)g(condition)h (delib)s(erately)g(b)m(y)150 3085 y(in)m(v)m(oking)i(THR)m(O)m(W.\))g (If)e(this)h(thro)m(w)g(is)g(not)g(caugh)m(t)g(b)m(y)g(a)g Fm(CATCH)46 b("ERROR)36 b Fr(in)g(the)h(user)f(program,)150 3194 y(it)j(is)g(ev)m(en)m(tually)i(caugh)m(t)f(either)f(b)m(y)g(the)g (toplev)m(el)h(instruction)f(lo)s(op)g(or)g(b)m(y)f(a)i(pause)e(lo)s (op,)j(whic)m(h)150 3304 y(prin)m(ts)25 b(the)h(error)f(message.)41 b(An)25 b(in)m(v)m(o)s(cation)j(of)d Fm(CATCH)47 b("ERROR)24 b Fr(in)h(a)h(user)f(program)h(lo)s(cally)h(un)m(binds)150 3413 y Fn(ERRA)m(CT)p Fr(,)f(so)h(the)g(e\013ect)h(is)e(that)h(whic)m (hev)m(er)g(of)g Fn(ERRA)m(CT)33 b Fr(and)26 b Fm(CATCH)46 b("ERROR)25 b Fr(is)h(more)h(lo)s(cal)h(will)150 3523 y(tak)m(e)k(precedence.)275 3668 y(If)c(a)i(\015oating)g(p)s(oin)m(t)f (o)m(v)m(er\015o)m(w)h(o)s(ccurs)f(during)f(an)h(arithmetic)h(op)s (eration,)g(or)f(a)h(t)m(w)m(o-input)g(math-)150 3778 y(ematical)48 b(function)e(\(lik)m(e)i(PO)m(WER\))e(is)g(in)m(v)m(ok)m (ed)h(with)f(an)g(illegal)i(com)m(bination)g(of)e(inputs,)j(the)150 3888 y(`)p Fm(doesn't)29 b(like)p Fr(')42 b(message)j(refers)e(to)h (the)f(second)h(op)s(erand,)i(but)c(should)h(b)s(e)g(tak)m(en)h(as)g (meaning)150 3997 y(the)31 b(com)m(bination.)275 4143 y(See)g([ERRA)m(CT],)g(page)h(89)g(,)f([THR)m(O)m(W],)i(page)f(69)g(,)f ([ERR)m(OR],)h(page)f(70)h(,)g([CA)-8 b(TCH],)31 b(page)h(69)150 4252 y(,)f([P)-8 b(A)m(USE],)31 b(page)g(70)g(,)g([CONTINUE],)f(page)h (70)h(.)150 4537 y Fq(10.1)68 b(Error)46 b(Co)t(des)275 4792 y Fr(Here)24 b(are)g(the)f(n)m(umeric)h(co)s(des)f(that)i(app)s (ear)e(as)g(the)h(\014rst)f(mem)m(b)s(er)g(of)h(the)f(list)i(output)e (b)m(y)g(ERR)m(OR)150 4902 y(when)33 b(an)h(error)g(is)g(caugh)m(t,)i (with)e(the)g(corresp)s(onding)f(messages.)53 b(Some)34 b(messages)i(ma)m(y)e(ha)m(v)m(e)i(t)m(w)m(o)150 5011 y(di\013eren)m(t)e(co)s(des)g(dep)s(ending)e(on)i(whether)f(or)h(not)f (the)h(error)g(is)f(reco)m(v)m(erable)j(\(that)f(is,)g(a)f(substitute) 150 5121 y(v)-5 b(alue)39 b(can)g(b)s(e)g(pro)m(vided)f(through)g(the)h Fn(ERRA)m(CT)45 b Fr(mec)m(hanism\))40 b(in)e(the)h(sp)s(eci\014c)g (con)m(text.)68 b(Some)150 5230 y(messages)32 b(are)f(w)m(arnings)f (rather)g(than)h(errors;)f(these)h(will)g(not)g(b)s(e)f(caugh)m(t.)42 b(Errors)29 b(0)i(and)f(32)i(are)f(so)150 5340 y(bad)f(that)h(Logo)g (exits)g(immediately)-8 b(.)p eop end %%Page: 88 89 TeXDict begin 88 88 bop 150 -116 a Fr(88)2551 b(BERKELEY)30 b(LOGO)g(5.5)451 408 y(0)g(F)-8 b(atal)33 b(in)m(ternal)e(error)f (\(can't)i(b)s(e)d(caugh)m(t\))451 518 y(1)h(Out)g(of)h(memory)451 628 y(2)f(Stac)m(k)i(o)m(v)m(er\015o)m(w)451 737 y(3)e(T)-8 b(urtle)31 b(out)f(of)h(b)s(ounds)451 847 y(4)f(PR)m(OC)g(do)s(esn't)g (lik)m(e)i(D)m(A)-8 b(TUM)32 b(as)f(input)e(\(not)i(reco)m(v)m (erable\))451 956 y(5)f(PR)m(OC)g(didn't)g(output)g(to)h(PR)m(OC)451 1066 y(6)f(Not)i(enough)e(inputs)f(to)i(PR)m(OC)451 1176 y(7)f(PR)m(OC)g(do)s(esn't)g(lik)m(e)i(D)m(A)-8 b(TUM)32 b(as)f(input)e(\(reco)m(v)m(erable\))451 1285 y(8)h(T)-8 b(o)s(o)31 b(m)m(uc)m(h)g(inside)f(\(\)'s)451 1395 y(9)61 b(Y)-8 b(ou)31 b(don't)f(sa)m(y)h(what)f(to)h(do)g(with)f(D)m(A)-8 b(TUM)420 1504 y(10)32 b('\)')f(not)f(found)420 1614 y(11)i(V)-10 b(AR)30 b(has)g(no)g(v)-5 b(alue)420 1724 y(12)32 b(Unexp)s(ected)e('\)')420 1833 y(13)i(I)e(don't)g(kno)m(w)g (ho)m(w)h(to)g(PR)m(OC)f(\(reco)m(v)m(erable\))420 1943 y(14)i(Can't)e(\014nd)f(catc)m(h)j(tag)f(for)f(THR)m(O)m(WT)-8 b(A)m(G)420 2052 y(15)32 b(PR)m(OC)d(is)i(already)g(de\014ned)420 2162 y(16)h(Stopp)s(ed)420 2271 y(17)g(Already)e(dribbling)420 2381 y(18)i(File)f(system)g(error)420 2491 y(19)h(Assuming)d(y)m(ou)i (mean)f(IFELSE,)g(not)h(IF)f(\(w)m(arning)h(only\))420 2600 y(20)h(V)-10 b(AR)30 b(shado)m(w)m(ed)h(b)m(y)f(lo)s(cal)i(in)e (pro)s(cedure)f(call)i(\(w)m(arning)g(only\))420 2710 y(21)h(Thro)m(w)d Fm(")p Fr(Error)420 2819 y(22)j(PR)m(OC)d(is)i(a)g (primitiv)m(e)420 2929 y(23)h(Can't)e(use)g(TO)g(inside)g(a)h(pro)s (cedure)420 3039 y(24)h(I)e(don't)g(kno)m(w)g(ho)m(w)h(to)g(PR)m(OC)f (\(not)h(reco)m(v)m(erable\))420 3148 y(25)h(IFTR)m(UE/IFF)-10 b(ALSE)30 b(without)h(TEST)420 3258 y(26)h(Unexp)s(ected)e(']')420 3367 y(27)i(Unexp)s(ected)e(')p Fm(})p Fr(')420 3477 y(28)i(Couldn't)d(initialize)k(graphics)420 3587 y(29)f(Macro)f (returned)e(V)-10 b(ALUE)31 b(instead)f(of)h(a)g(list)420 3696 y(30)h(Y)-8 b(ou)30 b(don't)h(sa)m(y)g(what)f(to)h(do)f(with)h(V) -10 b(ALUE)420 3806 y(31)32 b(Can)d(only)i(use)f(STOP)f(or)h(OUTPUT)g (inside)g(a)h(pro)s(cedure)420 3915 y(32)h(APPL)-8 b(Y)30 b(do)s(esn't)g(lik)m(e)i(BADTHING)f(as)g(input)420 4025 y(33)h(END)e(inside)g(m)m(ulti-line)i(instruction)420 4134 y(34)g(Really)f(out)g(of)f(memory)g(\(can't)i(b)s(e)e(caugh)m(t\)) p eop end %%Page: 89 90 TeXDict begin 89 89 bop 150 -116 a Fr(Chapter)30 b(11:)41 b(Sp)s(ecial)31 b(V)-8 b(ariables)2325 b(89)150 299 y Fp(11)80 b(Sp)t(ecial)53 b(V)-13 b(ariables)275 546 y Fr(Logo)32 b(tak)m(es)i(sp)s(ecial)e(action)h(if)f(an)m(y)g(of)g(the)g (follo)m(wing)h(v)-5 b(ariable)32 b(names)g(exists.)46 b(They)31 b(follo)m(w)i(the)150 655 y(normal)i(scoping)h(rules,)g(so)g (a)g(pro)s(cedure)e(can)i(lo)s(cally)g(set)g(one)g(of)g(them)f(to)h (limit)g(the)g(scop)s(e)f(of)h(its)150 765 y(e\013ect.)68 b(Initially)-8 b(,)43 b(no)38 b(v)-5 b(ariables)40 b(exist)g(except)g (for)e Fn(ALLO)m(W)m(GETSET)p Fr(,)h Fn(CASEIGNOREDP)p Fr(,)g(and)150 875 y Fn(UNBUR)-8 b(YONEDIT)p Fr(,)32 b(whic)m(h)e(are)h(TR)m(UE)f(and)g(buried.)150 1107 y Fk(allo)m(wgetset)390 1326 y Fm(ALLOWGETSET)1286 b(\(variable\))275 1465 y Fr(if)41 b(TR)m(UE,)g(indicates)h(that)f(an)g(attempt)h(to)g (use)f(a)g(pro)s(cedure)f(that)i(do)s(esn't)f(exist)h(should)e(b)s(e) 150 1575 y(tak)m(en)33 b(as)g(an)f(implicit)i(getter)g(or)e(setter)h (pro)s(cedure)e(\(setter)j(if)e(the)h(\014rst)f(three)g(letters)i(of)e (the)h(name)150 1684 y(are)e(SET\))e(for)i(a)f(v)-5 b(ariable)32 b(of)e(the)h(same)f(name)h(\(without)g(the)f(SET)f(if)i(appropriate\).) 150 1917 y Fk(caseignoredp)390 2136 y Fm(CASEIGNOREDP)1524 b(\(variable\))275 2275 y Fr(if)37 b(TR)m(UE,)h(indicates)h(that)f(lo)m (w)m(er)h(case)g(and)e(upp)s(er)f(case)i(letters)h(should)e(b)s(e)g (considered)g(equal)150 2385 y(b)m(y)32 b(EQUALP)-8 b(,)32 b(BEF)m(OREP)-8 b(,)33 b(MEMBERP)-8 b(,)33 b(etc.)46 b(Logo)33 b(initially)g(mak)m(es)g(this)f(v)-5 b(ariable)32 b(TR)m(UE,)h(and)150 2494 y(buries)c(it.)275 2633 y(See)h([EQUALP],)h (page)g(15)g(,)g([BEF)m(OREP],)g(page)g(15)h(,)e([MEMBERP],)i(page)f (16)g(.)150 2866 y Fk(erract)390 3085 y Fm(ERRACT)1812 b(\(variable\))275 3224 y Fr(an)41 b(instructionlist)i(that)f(will)g(b) s(e)f(run)f(in)h(the)h(ev)m(en)m(t)i(of)d(an)h(error.)74 b(T)m(ypically)43 b(has)f(the)f(v)-5 b(alue)150 3333 y([P)d(A)m(USE])31 b(to)g(allo)m(w)h(in)m(teractiv)m(e)h(debugging.)275 3472 y(See)d([P)-8 b(A)m(USE],)32 b(page)f(70)g(.)150 3705 y Fk(fullprin)m(tp)390 3924 y Fm(FULLPRINTP)275 4063 y Fr(if)23 b(TR)m(UE,)g(then)g(w)m(ords)f(that)i(w)m(ere)g (created)g(using)f(bac)m(kslash)g(or)g(v)m(ertical)j(bar)c(\(to)j (include)d(c)m(harac-)150 4172 y(ters)k(that)g(w)m(ould)g(otherwise)g (not)g(b)s(e)f(treated)i(as)f(part)f(of)h(a)g(w)m(ord\))g(are)g(prin)m (ted)g(with)f(the)h(bac)m(kslashes)150 4282 y(or)32 b(v)m(ertical)i (bars)d(sho)m(wn,)h(so)g(that)g(the)g(prin)m(ted)g(result)g(could)f(b)s (e)h(re-read)g(b)m(y)f(Logo)i(to)g(pro)s(duce)e(the)150 4391 y(same)42 b(v)-5 b(alue.)73 b(If)41 b(FULLPRINTP)f(is)h(TR)m(UE)g (then)g(the)g(empt)m(y)h(w)m(ord)f(\(ho)m(w)m(ev)m(er)h(it)g(w)m(as)g (created\))150 4501 y(prin)m(ts)30 b(as)g Fm(||)p Fr(.)41 b(\(Otherwise)30 b(it)h(prin)m(ts)f(as)g(nothing)h(at)g(all.\))150 4734 y Fk(loadnoisily)390 4953 y Fm(LOADNOISILY)1572 b(\(variable\))275 5092 y Fr(if)27 b(TR)m(UE,)g(prin)m(ts)g(the)h (names)f(of)h(pro)s(cedures)e(de\014ned)g(when)g(loading)i(from)f(a)h (\014le)f(\(including)h(the)150 5201 y(temp)s(orary)i(\014le)g(made)h (b)m(y)f(EDIT\).)275 5340 y(See)g([EDIT],)h(page)g(61)g(.)p eop end %%Page: 90 91 TeXDict begin 90 90 bop 150 -116 a Fr(90)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fk(prin)m(tdepthlimit)390 518 y Fm(PRINTDEPTHLIMIT)1380 b(\(variable\))275 653 y Fr(if)32 b(a)g(nonnegativ)m(e)i(in)m(teger,)g(indicates)f(the)f(maxim)m(um)g (depth)g(of)g(sublist)g(structure)f(that)i(will)g(b)s(e)150 762 y(prin)m(ted)d(b)m(y)g(PRINT,)g(etc.)275 897 y(See)g([PRINT],)h (page)g(19)g(.)150 1121 y Fk(prin)m(t)m(widthlimit)390 1340 y Fm(PRINTWIDTHLIMIT)1380 b(\(variable\))275 1474 y Fr(if)26 b(a)g(nonnegativ)m(e)i(in)m(teger,)h(indicates)e(the)g (maxim)m(um)f(n)m(um)m(b)s(er)f(of)h(mem)m(b)s(ers)f(in)h(an)m(y)h(one) f(list)h(that)150 1584 y(will)k(b)s(e)e(prin)m(ted)h(b)m(y)h(PRINT,)f (etc.)275 1719 y(See)g([PRINT],)h(page)g(19)g(.)150 1943 y Fk(redefp)390 2162 y Fm(REDEFP)1812 b(\(variable\))275 2296 y Fr(if)30 b(TR)m(UE,)h(allo)m(ws)g(primitiv)m(es)g(to)g(b)s(e)f (erased)h(\(ERASE\))f(or)g(rede\014ned)f(\(COPYDEF\).)275 2431 y(See)h([ERASE],)h(page)g(58)g(,)f([COPYDEF],)i(page)f(51)g(.)150 2655 y Fk(startup)390 2874 y Fm(STARTUP)1764 b(\(variable\))275 3009 y Fr(if)32 b(assigned)g(a)g(list)h(v)-5 b(alue)33 b(in)f(a)g(\014le)g(loaded)h(b)m(y)f(LO)m(AD,)h(that)f(v)-5 b(alue)33 b(is)f(run)f(as)h(an)g(instructionlist)150 3118 y(after)f(the)f(loading.)275 3253 y(See)g([LO)m(AD],)i(page)f(63)g (.)150 3477 y Fk(un)m(bury)m(onedit)390 3696 y Fm(UNBURYONEDIT)1333 b(\(variable\))275 3831 y Fr(if)31 b(TR)m(UE,)h(causes)g(an)m(y)g(pro)s (cedure)f(de\014ned)f(during)g(EDIT)i(or)f(LO)m(AD)i(to)f(b)s(e)f(un)m (buried,)f(so)i(that)150 3940 y(it)e(will)g(b)s(e)f(sa)m(v)m(ed)i(b)m (y)f(a)g(later)h(SA)-10 b(VE.)29 b(Files)i(that)f(w)m(an)m(t)h(to)f (de\014ne)f(and)g(bury)g(pro)s(cedures)f(m)m(ust)i(do)f(it)150 4050 y(in)h(that)h(order.)275 4184 y(See)f([EDIT],)h(page)g(61)g(,)g (See)g([LO)m(AD],)g(page)g(63)h(,)e(See)h([SA)-10 b(VE],)30 b(page)i(63)f(.)150 4408 y Fk(usealternatenames)390 4628 y Fm(USEALTERNATENAMES)43 b(\(variable\))275 4762 y Fr(if)27 b(TR)m(UE,)i(causes)f(Logo)h(to)g(generate)g(non-English)e(w)m(ords)h (\(from)g(the)g(Messages)h(\014le\))g(instead)f(of)150 4872 y(TR)m(UE,)j(F)-10 b(ALSE,)30 b(END,)h(etc.)p eop end %%Page: 91 92 TeXDict begin 91 91 bop 150 -116 a Fr(Chapter)30 b(12:)41 b(In)m(ternationalization)2219 b(91)150 299 y Fp(12)80 b(In)l(ternationalization)275 552 y Fr(Berk)m(eley)43 b(Logo)f(has)f(limited)h(supp)s(ort)e(for)h(non-English-sp)s(eaking)g (users.)73 b(Alas,)45 b(there)d(is)f(no)150 661 y(Unico)s(de)31 b(supp)s(ort,)d(and)i(high-bit-on)h(ASCI)s(I)e(co)s(des)h(w)m(ork)h(in) f(some)g(con)m(texts)j(but)c(not)i(others.)275 802 y(If)k(y)m(ou)h(w)m (an)m(t)h(to)g(translate)g(Berk)m(eley)g(Logo)g(for)f(use)g(with)f (another)h(language,)j(there)d(are)h(three)150 912 y(main)30 b(things)h(y)m(ou)f(ha)m(v)m(e)i(to)f(do:)390 1052 y Fm(1.)47 b(Primitive)e(names)390 1162 y(2.)i(Error)g(\(and)f(other\))g (messages)390 1271 y(3.)h(Documentation)275 1412 y Fr(F)-8 b(or)29 b(primitiv)m(e)h(names,)g(the)f(easiest)i(thing)e(is)g(to)h (pro)m(vide)f(a)h(startup)e(\014le)i(that)f(de\014nes)g(aliases)h(for) 150 1522 y(the)h(English)f(primitiv)m(e)h(names,)f(using)g(COPYDEF:)390 1663 y Fm(COPYDEF)46 b("AVANT)g("FORWARD)275 1803 y Fr(This)28 b(should)h(tak)m(e)i(care)g(of)e(it,)i(unless)e(y)m(our)g(language's)i (name)f(for)f(one)h(primitiv)m(e)h(is)e(sp)s(elled)h(lik)m(e)150 1913 y(the)i(English)g(name)g(of)g(a)h(di\013eren)m(t)g(primitiv)m(e.) 46 b(In)32 b(that)g(case)i(y)m(ou)e(ha)m(v)m(e)h(to)g(turn)e(REDEFP)i (on)f(and)150 2022 y(b)s(e)e(sure)f(to)j(cop)m(y)f(the)f (non-con\015icting)h(name)g(b)s(efore)f(o)m(v)m(erwriting)i(the)e (con\015icting)i(one!)275 2163 y Fm(")p Fr(Primitiv)m(es)p Fm(")39 b Fr(that)h(are)g(actually)h(in)f(the)f(Logo)i(library)-8 b(,)42 b(of)d(course,)k(can)c(just)g(b)s(e)g(replaced)h(or)150 2273 y(augmen)m(ted)31 b(with)f(nativ)m(e-language-named)k(Logo)d(pro)s (cedures)e(and)h(\014lenames.)275 2413 y(Of)i(course)h(Logo)h(programs) f(will)g(still)h(not)f(lo)s(ok)h(lik)m(e)g(y)m(our)f(nativ)m(e)h (language)h(if)e(the)g(w)m(ord)f(order)150 2523 y(is)e(dramatically)i (di\013eren)m(t,)g(esp)s(ecially)f(if)f(y)m(ou)h(don't)g(put)e(v)m (erbs)h(b)s(efore)g(their)h(ob)5 b(jects.)275 2664 y(F)-8 b(or)31 b(error)e(messages,)j(there)e(is)h(a)f(\014le)h(named)f (Messages)i(in)e(the)g(logolib)i(directory)f(with)f(texts)h(of)150 2773 y(messages,)f(one)e(p)s(er)e(line.)40 b(Y)-8 b(ou)29 b(can)f(replace)g(this)g(with)g(a)g(\014le)f(for)h(y)m(our)g(o)m(wn)f (language.)42 b(Do)28 b(not)g(add,)150 2883 y(delete,)40 b(or)d(reorder)g(lines;)k(Logo)d(\014nds)d(messages)j(b)m(y)f(line)h(n) m(um)m(b)s(er.)59 b(The)37 b(sequences)g Fm(\045p)p Fr(,)h Fm(\045s)p Fr(,)h(and)150 2993 y Fm(\045t)30 b Fr(in)g(these)g (messages)h(represen)m(t)g(v)-5 b(ariable)31 b(parts)f(of)g(the)h (message)g(and)f(should)f(not)h(b)s(e)g(translated.)150 3102 y(\(\045p)i Fm(PRINT)p Fr(s)f(the)h(v)-5 b(ariable)33 b(part,)g(while)g(\045s)f Fm(SHOW)p Fr(s)f(it)i({)f(that)h(is,)h(the)e (di\013erence)h(is)f(ab)s(out)h(whether)150 3212 y(or)f(not)h(brac)m(k) m(ets)h(are)f(sho)m(wn)f(surrounding)e(a)j(list.)47 b(\045t)33 b(means)f(that)h(the)g(v)-5 b(ariable)33 b(part)g(is)f(a)h(C)f(text)150 3321 y(string)27 b(rather)f(than)h(a)g(Logo)g(ob)5 b(ject.\))41 b(If)26 b(y)m(ou)h(w)m(an)m(t)h(to)f(c)m(hange)h(the)f(order)f(of)h(t)m (w)m(o)h(v)-5 b(ariable)27 b(parts)g(\(no)150 3431 y(reorderable)k (message)g(has)f(more)h(than)f(t)m(w)m(o\),)i(y)m(ou)f(w)m(ould)f(for)g (example)h(replace)g(the)g(line)390 3572 y Fm(\045p)47 b(doesn't)f(like)h(\045s)g(as)g(input)275 3712 y Fr(with)390 3853 y Fm(\045+s)g(is)g(a)h(lousy)e(input)g(to)h(\045p)275 3994 y Fr(The)30 b(plus)g(sign)h(tells)h(the)f(message)h(prin)m(ter)f (to)h(rev)m(erse)f(the)g(order;)g(y)m(ou)h(m)m(ust)f(rev)m(erse)g(the)g (order)150 4103 y(of)k(\045p)f(and)g(\045s,)i(if)f(b)s(oth)f(are)i (used,)f(to)h(matc)m(h.)55 b(The)34 b(plus)g(sign)h(go)s(es)h(just)e (after)i(the)f(\014rst)f(p)s(ercen)m(t)150 4213 y(sign)f(in)g(the)g (message,)i(whic)m(h)e(migh)m(t)h(not)g(b)s(e)e(at)i(the)f(b)s (eginning)g(of)g(the)g(line.)50 b(The)32 b(sequence)i Fm(\\n)e Fr(in)150 4323 y(a)k(message)i(represen)m(ts)e(a)g(newline;)j (don't)e(b)s(e)e(fo)s(oled)h(in)m(to)h(thinking)f(that)h(the)f Fm(")p Fr(n)p Fm(")f Fr(is)i(part)e(of)i(the)150 4432 y(follo)m(wing)32 b(w)m(ord.)275 4573 y(Some)40 b(messages)i(app)s(ear) f(t)m(wice)h(in)e(the)h(\014le;)47 b(this)41 b(isn't)g(a)g(mistak)m(e.) 74 b(The)40 b(t)m(w)m(o)i(spaces)f(b)s(efore)150 4682 y Fm(")p Fr(to)p Fm(")31 b Fr(in)g Fm(")p Fr(I)f(don't)h(kno)m(w)g(ho)m (w)f(to)p Fm(")i Fr(aren't)f(a)g(mistak)m(e)i(either.)42 b(The)31 b(message)h(con)m(taining)g(just)e Fm(")p Fr(\045p)p Fm(")150 4792 y Fr(is)37 b(for)f(user-pro)m(vided)g(error)h(messages)h (in)e(THR)m(O)m(W)i Fm(")p Fr(ERR)m(OR.)e(The)g(message)i Fm(")f Fr(in)f(\045s)p Fm(\\)p Fr(n\045s)p Fm(")f Fr(is)150 4902 y(the)41 b(part)f(of)h(all)h(error)e(messages)i(that)f(indicates)h (where)e(the)h(error)f(o)s(ccurred)g(if)h(it)g(w)m(as)g(inside)g(a)150 5011 y(pro)s(cedure;)35 b(y)m(ou)f(migh)m(t)h(w)m(an)m(t)g(to)g(c)m (hange)g(the)g(w)m(ord)e Fm(")p Fr(in)p Fm(")h Fr(to)g(y)m(our)g (language.)54 b Fm(")p Fr(\045s)33 b(de\014ned)p Fm(\\)p Fr(n)p Fm(")f Fr(is)150 5121 y(what)27 b(LO)m(AD)h(prin)m(ts)e(for)h (eac)m(h)i(pro)s(cedure)d(de\014ned)f(if)i(the)h(v)-5 b(ariable)28 b(LO)m(ADNOISIL)-8 b(Y)27 b(is)g(TR)m(UE.)g Fm(")p Fr(to)150 5230 y(\045p)p Fm(\\)p Fr(nend)p Fm(\\)p Fr(n)p Fm(\\)p Fr(n)p Fm(")c Fr(is)28 b(what)f(EDIT)g(puts)g(in)g(the)g (temp)s(orary)g(\014le)h(if)f(y)m(ou)h(ask)f(to)i(edit)e(a)h(pro)s (cedure)e(that)150 5340 y(isn't)31 b(already)f(de\014ned.)p eop end %%Page: 92 93 TeXDict begin 92 92 bop 150 -116 a Fr(92)2551 b(BERKELEY)30 b(LOGO)g(5.5)275 299 y(Also)43 b(in)g(the)g(Messages)i(\014le)e(are)g (lines)g(con)m(taining)i(only)e(one)g(w)m(ord)g(eac)m(h;)51 b(the)43 b(\014rst)f(of)h(these)150 408 y(is)i(the)g(w)m(ord)g Fm(")p Fr(true)p Fm(")p Fr(.)83 b(Some)45 b(of)g(these)h(w)m(ords)e (are)h(recognized)h(b)m(y)f(Logo)h(in)f(user)f(input;)52 b(some)150 518 y(are)40 b(generated)h(b)m(y)f(Logo;)47 b(some)40 b(are)h(b)s(oth.)69 b(F)-8 b(or)40 b(example,)k(the)c(w)m (ords)f(TR)m(UE)i(and)e(F)-10 b(ALSE)40 b(are)150 628 y(recognized)27 b(as)f(Bo)s(olean)h(v)-5 b(alues)26 b(b)m(y)f(IF)h(and) f(IFELSE,)g(and)g(are)h(also)h(generated)f(b)m(y)g(Logo)h(as)e(outputs) 150 737 y(from)j(the)g(primitiv)m(e)h(predicates)g(suc)m(h)e(as)i (EQUALP)-8 b(.)28 b(The)g(w)m(ord)f(END)i(is)f(recognized)i(as)e(the)g (end)g(of)150 847 y(a)f(pro)s(cedure)e(de\014nition,)j(and)e(ma)m(y)h (b)s(e)f(generated)i(when)d(Logo)j(reconstructs)f(a)g(pro)s(cedure)e(b) s(o)s(dy)g(for)150 956 y(PO)j(or)g(EDIT.)g(I'v)m(e)g(used)g(capital)h (letters)g(in)f(this)g(paragraph)g(for)f(easier)i(reading,)g(but)f(the) g(w)m(ords)f(in)150 1066 y(the)k(Messages)g(\014le)g(should)e(b)s(e)h (in)g(lo)m(w)m(er)i(case.)275 1194 y(If)40 b(y)m(ou)h(replace)h(these)g (with)f(non-English)f(w)m(ords,)k(Logo)e(will)f(*recognize*)j(b)s(oth)c (the)h(English)150 1303 y(names)31 b(and)f(y)m(our)g(alternate)j (names.)42 b(F)-8 b(or)31 b(example,)h(if)f(y)m(ou)g(replace)g(the)g(w) m(ord)g Fm(")p Fr(true)p Fm(")f Fr(with)g Fm(")p Fr(vrai)p Fm(")150 1413 y Fr(then)g(Logo)i(will)e(understand)f(b)s(oth)g(of)i (these:)390 1541 y Fm(IF)47 b("TRUE)g([PRINT)f("YES])390 1650 y(IF)h("VRAI)g([PRINT)f("YES])275 1778 y Fr(The)59 b(v)-5 b(ariable)60 b(UseAlternateNames)i(determines)e(whether)f(Logo)h (will)g(*generate*)i(other-)150 1888 y(language)50 b(names)f({)h(for)e (example,)55 b(whether)48 b(predicate)i(functions)f(return)f(the)h (other-language)150 1998 y(alternates)42 b(for)e(TR)m(UE)g(and)g(F)-10 b(ALSE.)40 b(This)f(v)-5 b(ariable)41 b(is)f(F)-10 b(ALSE)40 b(b)m(y)g(default,)j(meaning)e(that)g(the)150 2107 y(English)30 b(w)m(ords)g(will)h(b)s(e)e(generated.)275 2235 y(Y)-8 b(ou)28 b(migh)m(t)g(wish)f(to)h(ha)m(v)m(e)h(English-named)f (predicate)g(functions)f(generate)j(English)d(TR)m(UE)h(and)150 2345 y(F)-10 b(ALSE,)43 b(while)f(other-language-named)j(predicates)f (generate)g(the)f(alternate)h(w)m(ords.)78 b(This)42 b(can)150 2454 y(b)s(e)c(done)h(b)m(y)g(lea)m(ving)i(UseAlternateNames) g(false,)i(and)38 b(instead)h(of)h(de\014ning)e(the)h(other-language) 150 2564 y(predicates)31 b(with)f(COPYDEF,)h(do)f(it)h(this)f(w)m(a)m (y:)390 2692 y Fm(to)47 b(french.boolean)d(:bool)390 2801 y(if)j(equalp)f(:bool)h("true)f([output)g("vrai])390 2911 y(if)h(equalp)f(:bool)h("false)f([output)g("faux])390 3020 y(output)g(:bool)g(;)i(shouldn't)d(happen)390 3130 y(end)390 3349 y(to)i(make.french.predicate)42 b(:french)k(:english)g (:arity)390 3459 y(define)g(:french)g(`[[[inputs])f(,[:arity]])1201 3568 y([output)h(french.boolean)581 3678 y(apply)g(,[word)g("")i (:english])d(:inputs]])390 3787 y(end)390 4007 y(?)i (make.french.predicate)42 b("egal?)47 b("equal?)e(2)390 4116 y(?)i(pr)h(egal?)e(3)h(4)390 4226 y(faux)390 4335 y(?)g(pr)h(egal?)e(4)h(4)390 4445 y(vrai)390 4555 y(?)g(pr)h(equal?)e (3)h(4)390 4664 y(false)390 4774 y(?)g(pr)h(equal?)e(4)h(4)390 4883 y(true)275 5011 y Fr(The)28 b(third)h(input)f(to)i(mak)m(e.frenc)m (h.predicate)h(is)f(the)f(n)m(um)m(b)s(er)f(of)i(inputs)e(that)i(the)f (predicate)h(ex-)150 5121 y(p)s(ects.)39 b(This)24 b(solution)h(isn't)g (quite)g(p)s(erfect)f(b)s(ecause)h(the)f(in\014x)g(predicates)i(\(=,)g Fm(<)p Fr(,)f Fm(>)p Fr(\))g(will)g(still)g(output)150 5230 y(in)h(English.)40 b(If)26 b(y)m(ou)h(w)m(an)m(t)h(them)f(to)g (generate)h(alternate-language)j(w)m(ords,)c(set)g(UseAlternateNames) 150 5340 y(to)k(TR)m(UE)g(instead.)p eop end %%Page: 93 94 TeXDict begin 93 93 bop 150 -116 a Fr(Chapter)30 b(12:)41 b(In)m(ternationalization)2219 b(93)275 299 y(Some)22 b(of)h(the)f(w)m(ords)g(in)g(this)h(section)g(of)g(the)g(Messages)h (\014le)e(are)h(names)g(of)f(Logo)i(primitiv)m(es)f(\(OUT-)150 408 y(PUT,)38 b(STOP)-8 b(,)37 b(GOTO,)g(T)-8 b(A)m(G,)40 b(IF,)e(IFELSE,)f(TO,)h(.MA)m(CR)m(O\).)h(T)-8 b(o)38 b(translate)h(these)g(names,)h(y)m(ou)150 518 y(m)m(ust)32 b(use)g(COPYDEF)h(as)f(describ)s(ed)g(earlier,)i(in)e(addition)h(to)g (c)m(hanging)g(the)g(names)f(in)g(Messages.)150 628 y(Y)-8 b(ou)31 b(should)e(b)s(e)h(consisten)m(t)i(in)e(these)h(t)m(w)m(o)g (steps.)41 b(Don't)31 b(forget)h(the)e(p)s(erio)s(d)f(in)h Fm(")p Fr(.macro)p Fm(")p Fr(!)275 762 y(F)-8 b(or)33 b(do)s(cumen)m(tation,)g(there)g(are)f(t)m(w)m(o)i(kinds:)43 b(this)33 b(man)m(ual)f(and)g(the)g(help)g(\014les.)46 b(The)32 b(latter)i(are)150 872 y(generated)h(automatically)j(from)c (this)g(man)m(ual)h(if)f(y)m(ou)h(ha)m(v)m(e)g(a)g(Unix)g(system,)g(so) g(in)f(that)h(case)h(y)m(ou)150 981 y(need)26 b(only)g(translate)h (this)f(man)m(ual,)i(main)m(taining)f(the)f(format.)40 b(\(The)26 b(automatic)i(help\014le)e(generator)150 1091 y(notices)i(things)e(lik)m(e)j(capital)f(letters,)h(tabs,)f(h)m (yphens,)e(and)g(equal)h(signs)g(at)g(the)g(b)s(eginnings)f(of)h (lines.\))150 1200 y(The)h(program)h(mak)m(e\014le.c)h(ma)m(y)g (require)e(mo)s(di\014cation)h(b)s(ecause)g(a)g(few)g(of)f(the)h (primitiv)m(e)h(names)f(are)150 1310 y(sp)s(ecial)i(cases)g(\(e.g.,)i (LOG10)e(is)f(the)h(only)f(name)g(with)h(digits)g(included\).)275 1445 y(If)22 b(y)m(ou)i(don't)f(ha)m(v)m(e)h(Unix)f(to)s(ols,)j(y)m(ou) d(can)h(just)e(translate)j(eac)m(h)f(help\014le)f(individually)-8 b(.)38 b(A)23 b(p)s(erio)s(d)f(in)150 1554 y(a)28 b(primitiv)m(e)g (name)f(is)h(represen)m(ted)f(as)h(a)f(D)h(in)f(the)h(\014lename;)h (there)e(are)h(no)f(\014les)h(for)f(question)g(marks)150 1664 y(b)s(ecause)e(the)h(HELP)f(command)g(lo)s(oks)h(for)f(the)g (\014le)h(named)f(after)g(the)h(corresp)s(onding)e(primitiv)m(e)i(that) 150 1773 y(ends)k(in)g(P)-8 b(.)p eop end %%Page: 94 95 TeXDict begin 94 94 bop 150 -116 a Fr(94)2551 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: 95 96 TeXDict begin 95 95 bop 150 -116 a Fr(INDEX)3209 b(95)150 299 y Fp(INDEX)150 610 y Fq(*)150 728 y Fg(*)17 b Ff(.)c(.)f(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)43 b Fg(29)150 964 y Fe(+)150 1081 y Fd(+)17 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)42 b Fg(29)150 1317 y Fq(-)150 1435 y Fg(-)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)49 b Fg(29)150 1671 y Fq(.)150 1788 y Fg(.defmacro)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)44 b Fg(83)150 1876 y(.eq)7 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(16)150 1964 y(.macro)14 b Ff(.)g(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(83)150 2052 y(.ma)n(yb)r(eoutput)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)46 b Fg(71)150 2140 y(.setbf)18 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)44 b Fg(13)150 2228 y(.set\014rst)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)47 b Fg(13)150 2315 y(.setitem)13 b Ff(.)g(.)g(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)38 b Fg(14)150 2403 y(.setsegmen)n(tsize)21 b Ff(.)12 b(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)45 b Fg(65)150 2664 y Fq(/)150 2781 y Fg(/)17 b Ff(.)c(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)43 b Fg(29)150 3018 y Fe(<)150 3135 y Fd(<)17 b Ff(.)12 b(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)42 b Fg(32)150 3223 y Fd(<)p Fg(=)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)49 b Fg(32)150 3311 y Fd(<>)15 b Ff(.)e(.)g(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(15)150 3547 y Fq(=)150 3664 y Fg(=)7 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(15)150 3900 y Fe(>)150 4018 y Fd(>)17 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)42 b Fg(32)150 4106 y Fd(>)p Fg(=)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)49 b Fg(32)150 4342 y Fq(`)150 4459 y Fg(`)8 b Ff(.)k(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)33 b Fg(72)150 4696 y Fq(A)150 4813 y Fg(allop)r(en)7 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)32 b Fg(23)150 4901 y(allo)n(wgetset)15 b Ff(.)g(.)d(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)41 b Fg(89)150 4989 y(Allo)n(wGetSet)8 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)34 b Fg(4)150 5076 y(and)11 b Ff(.)h(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(35)150 5164 y(apply)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(76)150 5252 y(arc)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(39)150 5340 y(arctan)21 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)46 b Fg(31)2025 610 y(arit)n(y)12 b Ff(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)38 b Fg(56)2025 697 y(arra)n(y)22 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(10)2025 785 y(arra)n(y?)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(15)2025 872 y(arra)n(yp)18 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(15)2025 959 y(arra)n(ytolist)9 b Ff(.)k(.)f(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(10)2025 1047 y(ascii)18 b Ff(.)c(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(17)2025 1134 y(ashift)16 b Ff(.)d(.)g(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(34)2025 1367 y Fq(B)2025 1483 y Fg(bac)n(k)14 b Ff(.)e(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)40 b Fg(37)2025 1570 y(bac)n(kground)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)50 b Fg(47)2025 1658 y(bac)n(kslashed?)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)47 b Fg(16)2025 1745 y(bac)n(kslashedp)18 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(16)2025 1832 y(b)r(efore?)7 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(15)2025 1920 y(b)r(eforep)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(15)2025 2007 y(bf)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(11)2025 2094 y(bfs)6 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(12)2025 2181 y(bg)14 b Ff(.)e(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(47)2025 2269 y(bitand)18 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)44 b Fg(34)2025 2356 y(bitnot)7 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(34)2025 2443 y(bitor)10 b Ff(.)i(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)36 b Fg(34)2025 2530 y(bitxor)8 b Ff(.)k(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(34)2025 2618 y(bk)13 b Ff(.)e(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(37)2025 2705 y(bl)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(12)2025 2792 y(buried)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)46 b Fg(54)2025 2880 y(buried?)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)46 b Fg(60)2025 2967 y(buriedp)17 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)43 b Fg(60)2025 3054 y(bury)13 b Ff(.)e(.)h(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(59)2025 3141 y(bury)n(all)10 b Ff(.)i(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)36 b Fg(59)2025 3229 y(buryname)14 b Ff(.)d(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)40 b Fg(60)2025 3316 y(but\014rst)20 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(11)2025 3403 y(but\014rsts)6 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)32 b Fg(12)2025 3490 y(butlast)10 b Ff(.)i(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(12)2025 3578 y(button)14 b Ff(.)d(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)40 b Fg(48)2025 3665 y(button?)14 b Ff(.)e(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)40 b Fg(48)2025 3752 y(buttonp)11 b Ff(.)g(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)37 b Fg(48)2025 3839 y(b)n(y)n(e)16 b Ff(.)11 b(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)42 b Fg(71)2025 4089 y Fq(C)2025 4205 y Fg(cascade)20 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(80)2025 4293 y(cascade.2)8 b Ff(.)14 b(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(81)2025 4380 y(case)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)48 b Fg(74)2025 4467 y(case-insensitiv)n(e)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)45 b Fg(5)2025 4555 y(caseignoredp)24 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(89)2025 4642 y(catc)n(h)20 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)46 b Fg(69)2025 4729 y(c)n(har)19 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(17)2025 4816 y(clean)24 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)50 b Fg(40)2025 4904 y(clearscreen)18 b Ff(.)c(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(40)2025 4991 y(cleartext)17 b Ff(.)c(.)f(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(26)2025 5078 y(close)12 b Ff(.)h(.)g(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)38 b Fg(23)2025 5165 y(closeall)8 b Ff(.)14 b(.)e(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(24)2025 5253 y(co)18 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(70)2025 5340 y(com)n(bine)8 b Ff(.)k(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)34 b Fg(10)p eop end %%Page: 96 97 TeXDict begin 96 96 bop 150 -116 a Fr(96)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fg(commen)n(ts)15 b Ff(.)e(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)41 b Fg(5)150 387 y(Computer)p 492 387 24 4 v 34 w(Science)p 769 387 V 34 w(Logo)p 965 387 V 35 w(St)n(yle)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(1)150 475 y(cond)12 b Ff(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)38 b Fg(74)150 564 y(con)n(ten)n(ts)7 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(54)150 652 y(con)n(tin)n(ue)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(70)150 740 y(cop)n(ydef)18 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)44 b Fg(51)150 829 y(Cop)n(yrigh)n(t)15 b Ff(.)e(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)41 b Fg(1)150 917 y(cos)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)47 b Fg(31)150 1005 y(coun)n(t)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(17)150 1094 y(crossmap)10 b Ff(.)j(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)35 b Fg(79)150 1182 y(cs)23 b Ff(.)12 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(40)150 1270 y(cslsload)17 b Ff(.)d(.)f(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)43 b Fg(64)150 1359 y(ct)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(26)150 1447 y(cursor)6 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)32 b Fg(27)150 1686 y Fq(D)150 1804 y Fg(de\014ne)11 b Ff(.)h(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(50)150 1892 y(de\014ned?)8 b Ff(.)j(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(54)150 1980 y(de\014nedp)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)48 b Fg(54)150 2069 y(delimiters)18 b Ff(.)c(.)e(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)44 b Fg(5)150 2157 y(dequeue)10 b Ff(.)h(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(14)150 2245 y(di\013erence)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)48 b Fg(29)150 2334 y(do.un)n(til)16 b Ff(.)d(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)42 b Fg(73)150 2422 y(do.while)7 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)32 b Fg(73)150 2510 y(dribble)10 b Ff(.)i(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(24)150 2749 y Fq(E)150 2867 y Fg(ed)16 b Ff(.)c(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)42 b Fg(61)150 2956 y(edall)12 b Ff(.)h(.)g(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)38 b Fg(62)150 3044 y(edit)9 b Ff(.)j(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(61)150 3132 y(edit\014le)14 b Ff(.)f(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(62)150 3221 y(editor)11 b Ff(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(61)150 3309 y(edn)13 b Ff(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)39 b Fg(63)150 3397 y(edns)16 b Ff(.)c(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)42 b Fg(62)150 3485 y(edpl)20 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(63)150 3574 y(edpls)24 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)49 b Fg(63)150 3662 y(edps)16 b Ff(.)c(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)42 b Fg(62)150 3750 y(empt)n(y?)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)48 b Fg(15)150 3839 y(empt)n(yp)18 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)45 b Fg(15)150 3927 y(eof)6 b(?)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(26)150 4015 y(eofp)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(26)150 4104 y(epspict)10 b Ff(.)i(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(47)150 4192 y(equal?)21 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(15)150 4280 y(equalp)17 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(15)150 4369 y(er)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(58)150 4457 y(erall)18 b Ff(.)c(.)e(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)44 b Fg(58)150 4545 y(erase)7 b Ff(.)14 b(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)33 b Fg(58)150 4634 y(erase\014le)13 b Ff(.)g(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)38 b Fg(24)150 4722 y(erf)11 b Ff(.)i(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) 36 b Fg(24)150 4810 y(ern)19 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)45 b Fg(59)150 4898 y(erns)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)48 b Fg(59)150 4987 y(erpl)9 b Ff(.)j(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)34 b Fg(59)150 5075 y(erpls)12 b Ff(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)37 b Fg(59)150 5163 y(erps)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)48 b Fg(58)150 5252 y(erract)11 b Ff(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(89)150 5340 y(error)10 b Ff(.)j(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)35 b Fg(70)2025 299 y(errors)13 b Ff(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)38 b Fg(87)2025 387 y(exp)14 b Ff(.)e(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(30)2025 639 y Fq(F)2025 756 y Fg(fd)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(37)2025 844 y(fence)7 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(41)2025 931 y(\014le?)24 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(26)2025 1019 y(\014lep)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)46 b Fg(26)2025 1107 y(\014ll)12 b Ff(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(41)2025 1195 y(\014lter)12 b Ff(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(78)2025 1282 y(\014nd)9 b Ff(.)i(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)35 b Fg(78)2025 1370 y(\014rst)6 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(11)2025 1458 y(\014rsts)9 b Ff(.)k(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)35 b Fg(11)2025 1546 y(for)9 b Ff(.)k(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(73)2025 1633 y(foreac)n(h)8 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(77)2025 1721 y(forev)n(er)13 b Ff(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(67)2025 1809 y(form)13 b Ff(.)g(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(33)2025 1896 y(forw)n(ard)17 b Ff(.)d(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(37)2025 1984 y(fput)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)49 b Fg(9)2025 2072 y(fs)10 b Ff(.)i(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(42)2025 2160 y(fullprin)n(tp)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)50 b Fg(89)2025 2247 y(fullscreen)7 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(42)2025 2335 y(fulltext)24 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)50 b Fg(51)2025 2571 y Fq(G)2025 2688 y Fg(gc)18 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(65)2025 2776 y(gensym)20 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(11)2025 2863 y(getter)12 b Ff(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)38 b Fg(2)2025 2951 y(global)9 b Ff(.)k(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)35 b Fg(52)2025 3039 y(goto)18 b Ff(.)c(.)e(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)44 b Fg(71)2025 3126 y(gprop)13 b Ff(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(53)2025 3214 y(greater?)10 b Ff(.)j(.)g(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)36 b Fg(32)2025 3302 y(greaterequal?)12 b Ff(.)i(.)e(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)38 b Fg(32)2025 3390 y(greaterequalp)9 b Ff(.)k(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)35 b Fg(32)2025 3477 y(greaterp)7 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(32)2025 3730 y Fq(H)2025 3847 y Fg(heading)15 b Ff(.)e(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(39)2025 3934 y(help)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)46 b Fg(64)2025 4022 y(hideturtle)17 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(40)2025 4110 y(home)20 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)45 b Fg(39)2025 4198 y(h)n(t)19 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(40)2025 4433 y Fq(I)2025 4550 y Fg(if)14 b Ff(.)f(.)f(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(68)2025 4638 y(ifelse)9 b Ff(.)k(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(68)2025 4726 y(i\013)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(68)2025 4814 y(i\013alse)14 b Ff(.)f(.)g(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(68)2025 4901 y(ift)17 b Ff(.)c(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(68)2025 4989 y(iftrue)18 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(68)2025 5077 y(ignore)7 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(72)2025 5165 y(in)n(t)9 b Ff(.)j(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)35 b Fg(30)2025 5252 y(in)n(v)n(ok)n(e)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(76)2025 5340 y(iseq)10 b Ff(.)i(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(31)p eop end %%Page: 97 98 TeXDict begin 97 97 bop 150 -116 a Fr(INDEX)3209 b(97)150 299 y Fg(item)16 b Ff(.)d(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(12)150 582 y Fq(K)150 717 y Fg(k)n(ey?)16 b Ff(.)c(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(26)150 814 y(k)n(eyp)13 b Ff(.)e(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(26)150 1113 y Fq(L)150 1248 y Fg(lab)r(el)11 b Ff(.)i(.)g(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)36 b Fg(41)150 1345 y(last)13 b Ff(.)g(.)f(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)38 b Fg(11)150 1442 y(lea)n(ving)26 b Fd(ucblogo)6 b Ff(.)14 b(.)f(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(4)150 1538 y(left)18 b Ff(.)c(.)e(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)44 b Fg(38)150 1635 y(less?)15 b Ff(.)e(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)40 b Fg(32)150 1732 y(lessequal?)17 b Ff(.)d(.)e(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)43 b Fg(32)150 1828 y(lessequalp)14 b Ff(.)f(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)39 b Fg(32)150 1925 y(lessp)12 b Ff(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)37 b Fg(32)150 2022 y(line-con)n(tin)n(uation)10 b Ff(.)j(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(5)150 2118 y(list)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)49 b Fg(9)150 2215 y(list?)23 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(15)150 2312 y(listp)18 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)44 b Fg(15)150 2408 y(listtoarra)n(y)9 b Ff(.)k(.)g(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)34 b Fg(10)150 2505 y(ln)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(31)150 2602 y(load)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(63)150 2698 y(loadnoisily)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(89)150 2795 y(loadpict)11 b Ff(.)i(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)37 b Fg(47)150 2892 y(lo)r(cal)13 b Ff(.)h(.)e(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(52)150 2988 y(lo)r(calmak)n(e)16 b Ff(.)e(.)f(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)42 b Fg(52)150 3085 y(log10)24 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(30)150 3182 y(logohelp)7 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(64)150 3278 y(lo)n(w)n(ercase)8 b Ff(.)14 b(.)e(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)33 b Fg(18)150 3375 y(lput)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)50 b Fg(9)150 3472 y(lshift)7 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(34)150 3568 y(lt)11 b Ff(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(38)150 3851 y Fq(M)150 3987 y Fg(macro?)7 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)32 b Fg(85)150 4083 y(macro)r(expand)12 b Ff(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(85)150 4180 y(macrop)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(85)150 4277 y(mak)n(e)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)47 b Fg(51)150 4373 y(map)18 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)44 b Fg(77)150 4470 y(map.se)12 b Ff(.)h(.)f(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)37 b Fg(77)150 4567 y(mdarra)n(y)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(10)150 4663 y(mditem)17 b Ff(.)c(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(12)150 4760 y(mdsetitem)7 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)32 b Fg(13)150 4857 y(mem)n(b)r(er)11 b Ff(.)h(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(17)150 4953 y(mem)n(b)r(er?)11 b Ff(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(16)150 5050 y(mem)n(b)r(erp)8 b Ff(.)k(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(16)150 5147 y(min)n(us)10 b Ff(.)i(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)35 b Fg(29)150 5243 y(mo)r(dulo)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)46 b Fg(30)150 5340 y(mousep)r(os)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)46 b Fg(47)2025 299 y Fq(N)2025 415 y Fg(name)20 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)45 b Fg(51)2025 502 y(name?)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)45 b Fg(54)2025 590 y(namelist)23 b Ff(.)13 b(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(55)2025 677 y(namep)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)42 b Fg(54)2025 764 y(names)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(55)2025 852 y(no)r(des)14 b Ff(.)e(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)40 b Fg(56)2025 939 y(no)r(dribble)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)48 b Fg(24)2025 1026 y(norefresh)11 b Ff(.)i(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(43)2025 1114 y(not)17 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(35)2025 1201 y(notequal?)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)45 b Fg(15)2025 1288 y(notequalp)16 b Ff(.)c(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)42 b Fg(15)2025 1376 y(n)n(um)n(b)r(er?)18 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) 44 b Fg(16)2025 1463 y(n)n(um)n(b)r(erp)15 b Ff(.)c(.)h(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(16)2025 1713 y Fq(O)2025 1830 y Fg(op)14 b Ff(.)e(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)40 b Fg(69)2025 1917 y(op)r(enapp)r(end)15 b Ff(.)d(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(23)2025 2004 y(op)r(enread)11 b Ff(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)37 b Fg(22)2025 2092 y(op)r(en)n(up)r(date) 22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) 49 b Fg(23)2025 2179 y(op)r(en)n(write)17 b Ff(.)c(.)g(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(22)2025 2266 y(or)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(35)2025 2354 y(output)14 b Ff(.)d(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)40 b Fg(69)2025 2604 y Fq(P)2025 2720 y Fg(palette)12 b Ff(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(46)2025 2807 y(parse)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(18)2025 2895 y(pause)15 b Ff(.)d(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)41 b Fg(70)2025 2982 y(p)r(c)15 b Ff(.)d(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(46)2025 3069 y(p)r(d)11 b Ff(.)g(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)37 b Fg(43)2025 3157 y(p)r(e)15 b Ff(.)d(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(44)2025 3244 y(p)r(en)12 b Ff(.)g(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(46)2025 3331 y(p)r(encolor)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(46)2025 3419 y(p)r(endo)n(wn)14 b Ff(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)40 b Fg(43)2025 3506 y(p)r(endo)n(wn?)14 b Ff(.)e(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)40 b Fg(46)2025 3593 y(p)r(endo)n(wnp)11 b Ff(.)h(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)37 b Fg(46)2025 3681 y(p)r(enerase)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(44)2025 3768 y(p)r(enmo)r(de)12 b Ff(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(46)2025 3855 y(p)r(enpain)n(t)16 b Ff(.)c(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)42 b Fg(44)2025 3943 y(p)r(enpattern)15 b Ff(.)d(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(46)2025 4030 y(p)r(enrev)n(erse)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(44)2025 4117 y(p)r(ensize)7 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)32 b Fg(46)2025 4205 y(p)r(en)n(up)7 b Ff(.)k(.)h(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)32 b Fg(44)2025 4292 y(pic)n(k)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(12)2025 4379 y(plist)18 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(53)2025 4467 y(plist?)18 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)44 b Fg(54)2025 4554 y(plistp)15 b Ff(.)d(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)41 b Fg(54)2025 4641 y(plists)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)47 b Fg(55)2025 4729 y(pllist)8 b Ff(.)k(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)33 b Fg(56)2025 4816 y(p)r(o)13 b Ff(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(56)2025 4903 y(p)r(oall)9 b Ff(.)k(.)g(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)35 b Fg(56)2025 4991 y(p)r(on)10 b Ff(.)i(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)36 b Fg(57)2025 5078 y(p)r(ons)13 b Ff(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)39 b Fg(57)2025 5165 y(p)r(op)10 b Ff(.)i(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)36 b Fg(14)2025 5253 y(p)r(opl)17 b Ff(.)c(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)43 b Fg(57)2025 5340 y(p)r(opls)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)46 b Fg(57)p eop end %%Page: 98 99 TeXDict begin 98 98 bop 150 -116 a Fr(98)2551 b(BERKELEY)30 b(LOGO)g(5.5)150 299 y Fg(p)r(ops)13 b Ff(.)f(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)38 b Fg(57)150 387 y(p)r(os)16 b Ff(.)d(.)f(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)42 b Fg(39)150 474 y(p)r(ot)16 b Ff(.)d(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(58)150 562 y(p)r(ots)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)45 b Fg(58)150 650 y(p)r(o)n(w)n(er)10 b Ff(.)j(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)35 b Fg(30)150 738 y(pprop)11 b Ff(.)h(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(53)150 826 y(ppt)15 b Ff(.)d(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)41 b Fg(44)150 913 y(pr)18 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)44 b Fg(19)150 1001 y(pre\014x)14 b Ff(.)d(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(22)150 1089 y(primitiv)n(e?)12 b Ff(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)38 b Fg(54)150 1177 y(primitiv)n(ep)9 b Ff(.)j(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)34 b Fg(54)150 1265 y(primitiv)n(es)15 b Ff(.)e(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)41 b Fg(55)150 1352 y(prin)n(t)9 b Ff(.)j(.)g(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(19)150 1440 y(prin)n(tdepthlimit)15 b Ff(.)d(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)41 b Fg(90)150 1528 y(prin)n(tout)8 b Ff(.)j(.)i(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(56)150 1616 y(prin)n(t)n(widthlimit)17 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)42 b Fg(90)150 1703 y(pro)r(cedure?)16 b Ff(.)d(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)42 b Fg(53)150 1791 y(pro)r(cedurep)13 b Ff(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)39 b Fg(53)150 1879 y(pro)r(cedures)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)45 b Fg(55)150 1967 y(pro)r(duct)14 b Ff(.)e(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(29)150 2055 y(pu)12 b Ff(.)g(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)37 b Fg(44)150 2142 y(push)12 b Ff(.)f(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)37 b Fg(14)150 2230 y(p)n(x)14 b Ff(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)40 b Fg(44)150 2483 y Fq(Q)150 2600 y Fg(queue)12 b Ff(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)38 b Fg(14)150 2688 y(quoted)13 b Ff(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(13)150 2776 y(quotien)n(t)7 b Ff(.)k(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)32 b Fg(29)150 3028 y Fq(R)150 3145 y Fg(radarctan)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)45 b Fg(31)150 3233 y(radcos)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)46 b Fg(31)150 3321 y(radsin)6 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(31)150 3409 y(random)17 b Ff(.)c(.)f(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)43 b Fg(33)150 3496 y(ra)n(w)n(ascii)13 b Ff(.)h(.)f(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)38 b Fg(17)150 3584 y(rc)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(21)150 3672 y(rcs)7 b Ff(.)13 b(.)g(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)33 b Fg(21)150 3760 y(readc)n(har)20 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)45 b Fg(21)150 3848 y(readc)n(hars)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(21)150 3935 y(reader)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(25)150 4023 y(readlist)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(20)150 4111 y(readp)r(os)16 b Ff(.)d(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)42 b Fg(25)150 4199 y(readra)n(wline)7 b Ff(.)14 b(.)e(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(21)150 4287 y(readw)n(ord)9 b Ff(.)k(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(20)150 4374 y(redefp)24 b Ff(.)12 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)49 b Fg(90)150 4462 y(reduce)18 b Ff(.)13 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)44 b Fg(79)150 4550 y(refresh)15 b Ff(.)e(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)40 b Fg(42)150 4638 y(remainder)13 b Ff(.)g(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)39 b Fg(30)150 4725 y(remdup)17 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)43 b Fg(13)150 4813 y(remo)n(v)n(e)9 b Ff(.)j(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(12)150 4901 y(remprop)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)48 b Fg(53)150 4989 y(rep)r(coun)n(t)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)42 b Fg(68)150 5077 y(rep)r(eat)22 b Ff(.)12 b(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(67)150 5164 y(rerandom)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(33)150 5252 y(rev)n(erse)12 b Ff(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)37 b Fg(10)150 5340 y(righ)n(t)11 b Ff(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)36 b Fg(38)2025 299 y(rl)11 b Ff(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)37 b Fg(20)2025 387 y(round)11 b Ff(.)g(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)37 b Fg(30)2025 476 y(rseq)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)49 b Fg(32)2025 564 y(rt)7 b Ff(.)12 b(.)g(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(38)2025 652 y(run)15 b Ff(.)d(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)41 b Fg(67)2025 741 y(runparse)18 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)44 b Fg(18)2025 829 y(runparsing)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)48 b Fg(5)2025 917 y(runresult)12 b Ff(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)37 b Fg(67)2025 1006 y(rw)12 b Ff(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(20)2025 1245 y Fq(S)2025 1363 y Fg(sa)n(v)n(e)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(63)2025 1452 y(sa)n(v)n(el)11 b Ff(.)h(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)36 b Fg(63)2025 1540 y(sa)n(v)n(epict)12 b Ff(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)38 b Fg(47)2025 1628 y(screenmo)r(de)7 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(43)2025 1717 y(scrunc)n(h)18 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(40)2025 1805 y(scrunc)n(h.dat)7 b Ff(.)k(.)i(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)32 b Fg(42)2025 1894 y(se)24 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)50 b Fg(9)2025 1982 y(sen)n(tence)7 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)33 b Fg(9)2025 2070 y(setbac)n(kground)13 b Ff(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(45)2025 2159 y(setbg)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)47 b Fg(45)2025 2247 y(setcslslo)r(c)10 b Ff(.)15 b(.)d(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)36 b Fg(65)2025 2335 y(setcursor)14 b Ff(.)f(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)39 b Fg(26)2025 2424 y(seteditor)18 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)44 b Fg(64)2025 2512 y(seth)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)48 b Fg(38)2025 2600 y(setheading)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)48 b Fg(38)2025 2689 y(sethelplo)r(c)16 b Ff(.)d(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)42 b Fg(65)2025 2777 y(setitem)24 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(13)2025 2866 y(setliblo)r(c)8 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(64)2025 2954 y(setmargins)21 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(27)2025 3042 y(setpalette)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)45 b Fg(44)2025 3131 y(setp)r(c)23 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)48 b Fg(44)2025 3219 y(setp)r(en)19 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)45 b Fg(45)2025 3307 y(setp)r(encolor)11 b Ff(.)i(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)37 b Fg(44)2025 3396 y(setp)r(enpattern)22 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(45)2025 3484 y(setp)r(ensize)14 b Ff(.)f(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)40 b Fg(45)2025 3573 y(setp)r(os)24 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)49 b Fg(38)2025 3661 y(setpre\014x)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(22)2025 3749 y(setread)8 b Ff(.)k(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(24)2025 3838 y(setreadp)r(os)24 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)49 b Fg(25)2025 3926 y(setscrunc)n(h)7 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)33 b Fg(42)2025 4014 y(settc)12 b Ff(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)38 b Fg(27)2025 4103 y(settemplo)r(c)20 b Ff(.)13 b(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(65)2025 4191 y(setter)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)42 b Fg(2)2025 4280 y(settextcolor)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)48 b Fg(27)2025 4368 y(set)n(write)14 b Ff(.)f(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)40 b Fg(24)2025 4456 y(set)n(writep)r(os)12 b Ff(.)h(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)37 b Fg(25)2025 4545 y(setx)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(38)2025 4633 y(setxy)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(38)2025 4721 y(set)n(y)6 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(38)2025 4810 y(shell)16 b Ff(.)d(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(21)2025 4898 y(sho)n(w)9 b Ff(.)j(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)34 b Fg(20)2025 4986 y(sho)n(wn?)24 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(43)2025 5075 y(sho)n(wnp)20 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(43)2025 5163 y(sho)n(wturtle)24 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)49 b Fg(40)2025 5252 y(sin)8 b Ff(.)k(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)33 b Fg(31)2025 5340 y(splitscreen)6 b Ff(.)13 b(.)g(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(42)p eop end %%Page: 99 100 TeXDict begin 99 99 bop 150 -116 a Fr(INDEX)3209 b(99)150 299 y Fg(sqrt)7 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)33 b Fg(30)150 387 y(ss)6 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)32 b Fg(42)150 475 y(st)6 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(40)150 563 y(standout)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(18)150 650 y(starting)26 b Fd(ucblogo)11 b Ff(.)k(.)d(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)37 b Fg(4)150 738 y(startup)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)49 b Fg(90)150 826 y(step)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(61)150 914 y(stepp)r(ed)16 b Ff(.)c(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(55)150 1002 y(stepp)r(ed?)16 b Ff(.)c(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)42 b Fg(61)150 1090 y(stepp)r(edp)13 b Ff(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)38 b Fg(61)150 1178 y(stop)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)46 b Fg(69)150 1266 y(substring?)10 b Ff(.)i(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)35 b Fg(16)150 1353 y(substringp)6 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)32 b Fg(16)150 1441 y(sum)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)48 b Fg(29)150 1678 y Fq(T)150 1795 y Fg(tag)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(72)150 1883 y(temp)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(61)150 1971 y(template)16 b Ff(.)d(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)42 b Fg(75)150 2059 y(test)11 b Ff(.)h(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)36 b Fg(68)150 2147 y(text)23 b Ff(.)13 b(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(50)150 2235 y(textscreen)12 b Ff(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)37 b Fg(41)150 2322 y(thing)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(52)150 2410 y(thro)n(w)12 b Ff(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)37 b Fg(69)150 2498 y(to)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)46 b Fg(49)150 2586 y(to)n(w)n(ards)15 b Ff(.)e(.)g(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)41 b Fg(39)150 2674 y(trace)8 b Ff(.)13 b(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)33 b Fg(60)150 2762 y(traced)23 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(55)150 2850 y(traced?)23 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)48 b Fg(61)150 2938 y(tracedp)19 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)45 b Fg(61)150 3025 y(transfer)16 b Ff(.)d(.)g(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)41 b Fg(81)150 3113 y(ts)6 b Ff(.)13 b(.)f(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)32 b Fg(41)2025 299 y(turtlemo)r(de)15 b Ff(.)e(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)41 b Fg(43)2025 386 y(t)n(yp)r(e)17 b Ff(.)12 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)43 b Fg(19)2025 637 y Fq(U)2025 753 y Fg(un)n(bury)8 b Ff(.)i(.)i(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(60)2025 840 y(un)n(bury)n(all)22 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)48 b Fg(60)2025 928 y(un)n(buryname)9 b Ff(.)h(.)j(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)35 b Fg(60)2025 1015 y(un)n(bury)n(onedit)13 b Ff(.)d(.)j(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)39 b Fg(90)2025 1102 y(unstep)16 b Ff(.)c(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)42 b Fg(61)2025 1190 y(un)n(til)13 b Ff(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)39 b Fg(74)2025 1277 y(un)n(trace)20 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)46 b Fg(61)2025 1364 y(upp)r(ercase)16 b Ff(.)d(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)42 b Fg(18)2025 1452 y(usealternatenames)21 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(90)2025 1685 y Fq(W)2025 1802 y Fg(w)n(ait)20 b Ff(.)13 b(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)45 b Fg(71)2025 1889 y(while)22 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)47 b Fg(73)2025 1977 y(windo)n(w)19 b Ff(.)12 b(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)44 b Fg(41)2025 2064 y(w)n(ord)10 b Ff(.)i(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)36 b Fg(9)2025 2151 y(w)n(ordp)24 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)49 b Fg(14)2025 2239 y(wrap)8 b Ff(.)k(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)33 b Fg(40)2025 2326 y(writep)r(os)23 b Ff(.)12 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)47 b Fg(26)2025 2413 y(writer)9 b Ff(.)k(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)h(.)34 b Fg(25)2025 2647 y Fq(X)2025 2763 y Fg(xcor)19 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(39)2025 2997 y Fq(Y)2025 3113 y Fg(ycor)19 b Ff(.)13 b(.)f(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)h(.)f(.)45 b Fg(39)p eop end %%Page: 100 101 TeXDict begin 100 100 bop 150 -116 a Fr(100)2506 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Page: -1 102 TeXDict begin -1 101 bop 3723 -116 a Fc(i)150 299 y Fp(Short)53 b(Con)l(ten)l(ts)150 540 y Fc(1)146 b(In)m(tro)s(duction)12 b Fb(.)21 b(.)e(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f (.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.) h(.)44 b Fc(1)150 681 y(2)146 b(Data)32 b(Structure)h(Primitiv)m(es)38 b Fb(.)20 b(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f (.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)67 b Fc(9)150 822 y(3)146 b(Comm)m(unication)11 b Fb(.)21 b(.)f(.)f(.)h(.)f(.)h(.)f(.)g (.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.) f(.)h(.)f(.)g(.)h(.)f(.)43 b Fc(19)150 963 y(4)146 b(Arithmetic)23 b Fb(.)e(.)e(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.) f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f (.)55 b Fc(29)150 1104 y(5)146 b(Logical)32 b(Op)s(erations)40 b Fb(.)19 b(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g (.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)70 b Fc(35)150 1245 y(6)146 b(Graphics)34 b Fb(.)19 b(.)h(.)f(.)h(.)f(.)h (.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.) g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)65 b Fc(37)150 1386 y(7)146 b(W)-8 b(orkspace)34 b(Managemen)m(t)17 b Fb(.)j(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.) g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)48 b Fc(49)150 1528 y(8)146 b(Con)m(trol)33 b(Structures)14 b Fb(.)21 b(.)e(.)h(.)f(.)g(.)h (.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.) h(.)f(.)h(.)f(.)g(.)h(.)45 b Fc(67)150 1669 y(9)146 b(Macros)40 b Fb(.)19 b(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h (.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.) h(.)f(.)g(.)71 b Fc(83)150 1810 y(10)97 b(Error)33 b(Pro)s(cessing)24 b Fb(.)d(.)e(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.) h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)56 b Fc(87)150 1951 y(11)97 b(Sp)s(ecial)33 b(V)-8 b(ariables)18 b Fb(.)i(.)g(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.) f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)49 b Fc(89)150 2092 y(12)97 b(In)m(ternationalization)22 b Fb(.)f(.)e(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.) h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)54 b Fc(91)150 2233 y(INDEX)35 b Fb(.)20 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g (.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.) f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)67 b Fc(95)p eop end %%Page: -2 103 TeXDict begin -2 102 bop 150 -116 a Fc(ii)2517 b(BERKELEY)34 b(LOGO)d(5.5)p eop end %%Page: -3 104 TeXDict begin -3 103 bop 3674 -116 a Fr(iii)150 299 y Fp(T)-13 b(able)53 b(of)h(Con)l(ten)l(ts)150 641 y Fq(1)135 b(In)l(tro)t(duction)15 b Fb(.)20 b(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h (.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.) f(.)h(.)f(.)60 b Fq(1)449 778 y Fr(1.1)92 b(Ov)m(erview)20 b Fa(.)c(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(1)449 888 y(1.2)92 b(Getter/Setter)33 b(V)-8 b(ariable)32 b(Syn)m(tax)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)42 b Fr(1)449 997 y(1.3)92 b(En)m(tering)31 b(and)e(Lea)m(ving)j(Logo)9 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(4)449 1107 y(1.4)92 b(T)-8 b(ok)m(enization)17 b Fa(.)g(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)46 b Fr(5)150 1349 y Fq(2)135 b(Data)46 b(Structure)e(Primitiv)l(es)21 b Fb(.)h(.)d(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h (.)65 b Fq(9)449 1486 y Fr(2.1)92 b(Constructors)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)44 b Fr(9)748 1596 y(w)m(ord)20 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)49 b Fr(9)748 1705 y(list)13 b Fa(.)j(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(9)748 1815 y(sen)m(tence)16 b Fa(.)g(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)46 b Fr(9)748 1924 y(fput)13 b Fa(.)h(.)h(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)43 b Fr(9)748 2034 y(lput)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)44 b Fr(9)748 2144 y(arra)m(y)13 b Fa(.)j(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(9)748 2253 y(mdarra)m(y)13 b Fa(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)43 b Fr(10)748 2363 y(listtoarra)m(y)18 b Fa(.)f(.)e(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)48 b Fr(10)748 2472 y(arra)m(ytolist)18 b Fa(.)f(.)e(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)48 b Fr(10)748 2582 y(com)m(bine)17 b Fa(.)f(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)47 b Fr(10)748 2692 y(rev)m(erse)22 b Fa(.)15 b(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)51 b Fr(10)748 2801 y(gensym)11 b Fa(.)k(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)40 b Fr(10)449 2911 y(2.2)92 b(Data)32 b(Selectors)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(11)748 3020 y(\014rst)16 b Fa(.)e(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(11)748 3130 y(\014rsts)19 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)48 b Fr(11)748 3240 y(last)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(11)748 3349 y(but\014rst)12 b Fa(.)h(.)i(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)41 b Fr(11)748 3459 y(but\014rsts)16 b Fa(.)d(.)i(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)45 b Fr(11)748 3568 y(butlast)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(12)748 3678 y(item)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)57 b Fr(12)748 3787 y(mditem)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(12)748 3897 y(pic)m(k)13 b Fa(.)j(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)43 b Fr(12)748 4007 y(remo)m(v)m(e)19 b Fa(.)d(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)48 b Fr(12)748 4116 y(remdup)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(12)748 4226 y(quoted)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(13)449 4335 y(2.3)92 b(Data)32 b(Mutators)16 b Fa(.)g(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)45 b Fr(13)748 4445 y(setitem)15 b Fa(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)44 b Fr(13)748 4555 y(mdsetitem)16 b Fa(.)f(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(13)748 4664 y(.set\014rst)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(13)748 4774 y(.setbf)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)37 b Fr(13)748 4883 y(.setitem)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)53 b Fr(13)748 4993 y(push)22 b Fa(.)13 b(.)i(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)51 b Fr(14)748 5103 y(p)s(op)20 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(14)748 5212 y(queue)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)52 b Fr(14)748 5322 y(dequeue)20 b Fa(.)14 b(.)i(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(14)p eop end %%Page: -4 105 TeXDict begin -4 104 bop 150 -116 a Fr(iv)2568 b(BERKELEY)30 b(LOGO)g(5.5)449 83 y(2.4)92 b(Predicates)21 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(14)748 193 y(w)m(ordp)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(14)748 302 y(listp)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)37 b Fr(14)748 412 y(arra)m(yp)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(15)748 521 y(empt)m(yp)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)39 b Fr(15)748 631 y(equalp)29 b Fa(.)15 b(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)58 b Fr(15)748 741 y(notequalp)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(15)748 850 y(b)s(eforep)12 b Fa(.)i(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)41 b Fr(15)748 960 y(.eq)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)45 b Fr(16)748 1069 y(mem)m(b)s(erp)17 b Fa(.)d(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)47 b Fr(16)748 1179 y(substringp)16 b Fa(.)d(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(16)748 1289 y(n)m(um)m(b)s(erp)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)55 b Fr(16)748 1398 y(bac)m(kslashedp)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(16)449 1508 y(2.5)92 b(Queries)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)42 b Fr(17)748 1617 y(coun)m(t)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)57 b Fr(17)748 1727 y(ascii)8 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)37 b Fr(17)748 1836 y(ra)m(w)m(ascii)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)53 b Fr(17)748 1946 y(c)m(har)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(17)748 2056 y(mem)m(b)s(er)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)50 b Fr(17)748 2165 y(lo)m(w)m(ercase)17 b Fa(.)g(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)46 b Fr(17)748 2275 y(upp)s(ercase)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(18)748 2384 y(standout)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)57 b Fr(18)748 2494 y(parse)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)41 b Fr(18)748 2604 y(runparse)8 b Fa(.)13 b(.)i(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)37 b Fr(18)150 2846 y Fq(3)135 b(Comm)l(unication)12 b Fb(.)21 b(.)e(.)h(.)f(.)h(.)f (.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) f(.)g(.)h(.)57 b Fq(19)449 2983 y Fr(3.1)92 b(T)-8 b(ransmitters)15 b Fa(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(19)748 3093 y(prin)m(t)18 b Fa(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(19)748 3202 y(t)m(yp)s(e)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)58 b Fr(19)748 3312 y(sho)m(w)18 b Fa(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(20)449 3421 y(3.2)92 b(Receiv)m(ers)19 b Fa(.)e(.)e(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)49 b Fr(20)748 3531 y(readlist)12 b Fa(.)j(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(20)748 3641 y(readw)m(ord)19 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(20)748 3750 y(readra)m(wline)16 b Fa(.)f(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)45 b Fr(21)748 3860 y(readc)m(har)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)39 b Fr(21)748 3969 y(readc)m(hars)13 b Fa(.)i(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)42 b Fr(21)748 4079 y(shell)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)56 b Fr(21)449 4188 y(3.3)92 b(File)32 b(Access)c Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)56 b Fr(22)748 4298 y(setpre\014x)12 b Fa(.)i(.)h(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(22)748 4408 y(pre\014x)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)54 b Fr(22)748 4517 y(op)s(enread)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)50 b Fr(22)748 4627 y(op)s(en)m(write)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(22)748 4736 y(op)s(enapp)s(end)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)56 b Fr(23)748 4846 y(op)s(en)m(up)s(date)14 b Fa(.)g(.)h(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)43 b Fr(23)748 4956 y(close)22 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)51 b Fr(23)748 5065 y(allop)s(en)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)45 b Fr(23)748 5175 y(closeall)17 b Fa(.)g(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)46 b Fr(23)748 5284 y(erase\014le)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)53 b Fr(24)p eop end %%Page: -5 106 TeXDict begin -5 105 bop 3702 -116 a Fr(v)748 83 y(dribble)20 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(24)748 193 y(no)s(dribble)14 b Fa(.)f(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) 43 b Fr(24)748 302 y(setread)17 b Fa(.)e(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)46 b Fr(24)748 412 y(set)m(write)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(24)748 521 y(reader)13 b Fa(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(25)748 631 y(writer)18 b Fa(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)48 b Fr(25)748 741 y(setreadp)s(os)14 b Fa(.)h(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)44 b Fr(25)748 850 y(set)m(writep)s(os)22 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)51 b Fr(25)748 960 y(readp)s(os)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)56 b Fr(25)748 1069 y(writep)s(os)12 b Fa(.)i(.)h(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(25)748 1179 y(eofp)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)41 b Fr(26)748 1289 y(\014lep)11 b Fa(.)j(.)h(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(26)449 1398 y(3.4)92 b(T)-8 b(erminal)31 b(Access)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(26)748 1508 y(k)m(eyp)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)53 b Fr(26)748 1617 y(cleartext)31 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(26)748 1727 y(setcursor)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(26)748 1836 y(cursor)16 b Fa(.)e(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)45 b Fr(27)748 1946 y(setmargins)11 b Fa(.)k(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)40 b Fr(27)748 2056 y(settextcolor)13 b Fa(.)18 b(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(27)150 2298 y Fq(4)135 b(Arithmetic)30 b Fb(.)20 b(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h (.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.) f(.)75 b Fq(29)449 2435 y Fr(4.1)92 b(Numeric)30 b(Op)s(erations)18 b Fa(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)47 b Fr(29)748 2545 y(sum)13 b Fa(.)h(.)h(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)42 b Fr(29)748 2654 y(di\013erence)14 b Fa(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(29)748 2764 y(min)m(us)20 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)49 b Fr(29)748 2873 y(pro)s(duct)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)54 b Fr(29)748 2983 y(quotien)m(t)16 b Fa(.)g(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)45 b Fr(29)748 3093 y(remainder)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(29)748 3202 y(mo)s(dulo)11 b Fa(.)j(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)40 b Fr(30)748 3312 y(in)m(t)18 b Fa(.)e(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(30)748 3421 y(round)21 b Fa(.)13 b(.)i(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(30)748 3531 y(sqrt)17 b Fa(.)d(.)i(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)46 b Fr(30)748 3641 y(p)s(o)m(w)m(er)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(30)748 3750 y(exp)24 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)54 b Fr(30)748 3860 y(log10)12 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)42 b Fr(30)748 3969 y(ln)13 b Fa(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)43 b Fr(30)748 4079 y(sin)17 b Fa(.)d(.)h(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)46 b Fr(31)748 4188 y(radsin)16 b Fa(.)e(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(31)748 4298 y(cos)12 b Fa(.)j(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)41 b Fr(31)748 4408 y(radcos)11 b Fa(.)k(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(31)748 4517 y(arctan)11 b Fa(.)k(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)40 b Fr(31)748 4627 y(radarctan)10 b Fa(.)15 b(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)39 b Fr(31)748 4736 y(iseq)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(31)748 4846 y(rseq)14 b Fa(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)44 b Fr(32)449 4956 y(4.2)92 b(Numeric)30 b(Predicates)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(32)748 5065 y(lessp)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)51 b Fr(32)748 5175 y(greaterp)16 b Fa(.)g(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)45 b Fr(32)748 5284 y(lessequalp)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)54 b Fr(32)p eop end %%Page: -6 107 TeXDict begin -6 106 bop 150 -116 a Fr(vi)2568 b(BERKELEY)30 b(LOGO)g(5.5)748 83 y(greaterequalp)19 b Fa(.)d(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(32)449 193 y(4.3)92 b(Random)30 b(Num)m(b)s(ers)16 b Fa(.)e(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)45 b Fr(32)748 302 y(random)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(33)748 412 y(rerandom)12 b Fa(.)i(.)h(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)41 b Fr(33)449 521 y(4.4)92 b(Prin)m(t)30 b(F)-8 b(ormatting)14 b Fa(.)j(.)f(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)43 b Fr(33)748 631 y(form)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(33)449 741 y(4.5)92 b(Bit)m(wise)32 b(Op)s(erations)20 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)49 b Fr(33)748 850 y(bitand)9 b Fa(.)14 b(.)h(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(33)748 960 y(bitor)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(34)748 1069 y(bitxor)17 b Fa(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)46 b Fr(34)748 1179 y(bitnot)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)45 b Fr(34)748 1289 y(ashift)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)56 b Fr(34)748 1398 y(lshift)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)45 b Fr(34)150 1641 y Fq(5)135 b(Logical)46 b(Op)t(erations)17 b Fb(.)j(.)g(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f (.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)62 b Fq(35)748 1778 y Fr(and)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)50 b Fr(35)748 1887 y(or)11 b Fa(.)k(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(35)748 1997 y(not)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(35)150 2239 y Fq(6)135 b(Graphics)27 b Fb(.)18 b(.)i(.)f(.)h(.)f (.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.) h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)71 b Fq(37)449 2376 y Fr(6.1)92 b(T)-8 b(urtle)30 b(Motion)10 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(37)748 2486 y(forw)m(ard)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(37)748 2595 y(bac)m(k)25 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)54 b Fr(37)748 2705 y(left)8 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(37)748 2814 y(righ)m(t)21 b Fa(.)15 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(38)748 2924 y(setp)s(os)14 b Fa(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)44 b Fr(38)748 3034 y(setxy)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(38)748 3143 y(setx)14 b Fa(.)i(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(38)748 3253 y(set)m(y)16 b Fa(.)g(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)45 b Fr(38)748 3362 y(setheading)14 b Fa(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(38)748 3472 y(home)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(38)748 3582 y(arc)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)41 b Fr(39)449 3691 y(6.2)92 b(T)-8 b(urtle)30 b(Motion)i(Queries)18 b Fa(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)47 b Fr(39)748 3801 y(p)s(os)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)56 b Fr(39)748 3910 y(xcor)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)39 b Fr(39)748 4020 y(ycor)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(39)748 4130 y(heading)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)56 b Fr(39)748 4239 y(to)m(w)m(ards)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)55 b Fr(39)748 4349 y(scrunc)m(h)8 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)37 b Fr(39)449 4458 y(6.3)92 b(T)-8 b(urtle)30 b(and)g(Windo)m(w)h(Con)m (trol)15 b Fa(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(40)748 4568 y(sho)m(wturtle)15 b Fa(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) 44 b Fr(40)748 4677 y(hideturtle)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)58 b Fr(40)748 4787 y(clean)15 b Fa(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)44 b Fr(40)748 4897 y(clearscreen)8 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)37 b Fr(40)748 5006 y(wrap)17 b Fa(.)d(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)46 b Fr(40)748 5116 y(windo)m(w)9 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)38 b Fr(41)748 5225 y(fence)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(41)748 5335 y(\014ll)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(41)p eop end %%Page: -7 108 TeXDict begin -7 107 bop 3652 -116 a Fr(vii)748 83 y(lab)s(el)21 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)50 b Fr(41)748 193 y(textscreen)22 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)51 b Fr(41)748 302 y(fullscreen)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) 45 b Fr(41)748 412 y(splitscreen)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) 45 b Fr(42)748 521 y(setscrunc)m(h)17 b Fa(.)e(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)46 b Fr(42)748 631 y(refresh)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)55 b Fr(42)748 741 y(norefresh)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(42)449 850 y(6.4)92 b(T)-8 b(urtle)30 b(and)g(Windo)m(w)h(Queries)16 b Fa(.)e(.)h(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(43)748 960 y(sho)m(wnp)11 b Fa(.)j(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(43)748 1069 y(screenmo)s(de)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(43)748 1179 y(turtlemo)s(de)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)56 b Fr(43)449 1289 y(6.5)92 b(P)m(en)31 b(and)e(Bac)m(kground)i(Con)m (trol)11 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(43)748 1398 y(p)s(endo)m(wn)23 b Fa(.)15 b(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)54 b Fr(43)748 1508 y(p)s(en)m(up)16 b Fa(.)d(.)i(.)g(.)g(.)g(.) g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)45 b Fr(43)748 1617 y(p)s(enpain)m(t)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(44)748 1727 y(p)s(enerase)10 b Fa(.)k(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(44)748 1836 y(p)s(enrev)m(erse)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)44 b Fr(44)748 1946 y(setp)s(encolor)21 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(44)748 2056 y(setpalette)10 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(44)748 2165 y(setp)s(ensize)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(45)748 2275 y(setp)s(enpattern)14 b Fa(.)g(.)h(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(45)748 2384 y(setp)s(en)10 b Fa(.)k(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)39 b Fr(45)748 2494 y(setbac)m(kground)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)53 b Fr(45)449 2604 y(6.6)92 b(P)m(en)31 b(Queries)8 b Fa(.)14 b(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)37 b Fr(45)748 2713 y(p)s(endo)m(wnp)21 b Fa(.)13 b(.)i(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)51 b Fr(45)748 2823 y(p)s(enmo)s(de)23 b Fa(.)13 b(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(46)748 2932 y(p)s(encolor)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)42 b Fr(46)748 3042 y(palette)22 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(46)748 3152 y(p)s(ensize)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)45 b Fr(46)748 3261 y(p)s(en)22 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(46)748 3371 y(bac)m(kground)15 b Fa(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(46)449 3480 y(6.7)92 b(sa)m(ving)31 b(and)f(loading)h(pictures)c Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)56 b Fr(47)748 3590 y(sa)m(v)m(epict)22 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)52 b Fr(47)748 3699 y(loadpict)21 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)50 b Fr(47)748 3809 y(epspict)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(47)449 3919 y(6.8)92 b(Mouse)31 b(Queries)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)49 b Fr(47)748 4028 y(mousep)s(os)11 b Fa(.)j(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(47)748 4138 y(buttonp)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)50 b Fr(48)748 4247 y(buttonp)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)50 b Fr(48)p eop end %%Page: -8 109 TeXDict begin -8 108 bop 150 -116 a Fr(viii)2518 b(BERKELEY)30 b(LOGO)g(5.5)150 83 y Fq(7)135 b(W)-11 b(orkspace)45 b(Managemen)l(t)40 b Fb(.)19 b(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f (.)h(.)f(.)h(.)f(.)g(.)h(.)83 b Fq(49)449 220 y Fr(7.1)92 b(Pro)s(cedure)30 b(De\014nition)e Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(49)748 330 y(to)11 b Fa(.)k(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)40 b Fr(49)748 439 y(de\014ne)21 b Fa(.)14 b(.)h(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)h(.)f(.)g(.)g(.)50 b Fr(50)748 549 y(text)15 b Fa(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(50)748 658 y(fulltext)15 b Fa(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)44 b Fr(51)748 768 y(cop)m(ydef)9 b Fa(.)15 b(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)38 b Fr(51)449 878 y(7.2)92 b(V)-8 b(ariable)32 b(De\014nition)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(51)748 987 y(mak)m(e)12 b Fa(.)k(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)42 b Fr(51)748 1097 y(name)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)39 b Fr(51)748 1206 y(lo)s(cal)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(51)748 1316 y(lo)s(calmak)m(e)30 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)57 b Fr(52)748 1425 y(thing)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)42 b Fr(52)748 1535 y(global)19 b Fa(.)d(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(52)449 1645 y(7.3)92 b(Prop)s(ert)m(y)30 b(Lists)c Fa(.)15 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)55 b Fr(52)748 1754 y(pprop)21 b Fa(.)13 b(.)i(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(53)748 1864 y(gprop)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)53 b Fr(53)748 1973 y(remprop)13 b Fa(.)h(.)h(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)43 b Fr(53)748 2083 y(plist)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)37 b Fr(53)449 2193 y(7.4)92 b(W)-8 b(orkspace)32 b(Predicates)d Fa(.)15 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) 58 b Fr(53)748 2302 y(pro)s(cedurep)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)53 b Fr(53)748 2412 y(primitiv)m(ep)19 b Fa(.)c(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)48 b Fr(53)748 2521 y(de\014nedp)14 b Fa(.)f(.)i(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)43 b Fr(54)748 2631 y(namep)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(54)748 2741 y(plistp)25 b Fa(.)15 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) 55 b Fr(54)449 2850 y(7.5)92 b(W)-8 b(orkspace)32 b(Queries)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)49 b Fr(54)748 2960 y(con)m(ten)m(ts)16 b Fa(.)h(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)45 b Fr(54)748 3069 y(buried)11 b Fa(.)i(.)j(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(54)748 3179 y(traced)13 b Fa(.)j(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)43 b Fr(54)748 3289 y(stepp)s(ed)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(55)748 3398 y(pro)s(cedures)9 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(55)748 3508 y(primitiv)m(es)26 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)55 b Fr(55)748 3617 y(names)13 b Fa(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)43 b Fr(55)748 3727 y(plists)12 b Fa(.)j(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(55)748 3836 y(namelist)13 b Fa(.)j(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(55)748 3946 y(pllist)17 b Fa(.)e(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)46 b Fr(55)748 4056 y(arit)m(y)22 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)51 b Fr(56)748 4165 y(no)s(des)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(56)449 4275 y(7.6)92 b(W)-8 b(orkspace)32 b(Insp)s(ection)d Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) 58 b Fr(56)748 4384 y(p)s(o)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(56)748 4494 y(p)s(oall)19 b Fa(.)c(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(56)748 4604 y(p)s(ops)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)53 b Fr(57)748 4713 y(p)s(ons)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(57)748 4823 y(p)s(opls)11 b Fa(.)j(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)40 b Fr(57)748 4932 y(p)s(on)20 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)49 b Fr(57)748 5042 y(p)s(opl)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)58 b Fr(57)748 5152 y(p)s(ot)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(57)748 5261 y(p)s(ots)9 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)39 b Fr(58)p eop end %%Page: -9 110 TeXDict begin -9 109 bop 3677 -116 a Fr(ix)449 83 y(7.7)92 b(W)-8 b(orkspace)32 b(Con)m(trol)19 b Fa(.)d(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(58)748 193 y(erase)17 b Fa(.)e(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)46 b Fr(58)748 302 y(erall)8 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(58)748 412 y(erps)13 b Fa(.)h(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)42 b Fr(58)748 521 y(erns)13 b Fa(.)h(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)42 b Fr(58)748 631 y(erpls)22 b Fa(.)14 b(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)51 b Fr(59)748 741 y(ern)10 b Fa(.)k(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)39 b Fr(59)748 850 y(erpl)18 b Fa(.)d(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(59)748 960 y(bury)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(59)748 1069 y(bury)m(all)20 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)49 b Fr(59)748 1179 y(buryname)23 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(59)748 1289 y(un)m(bury)17 b Fa(.)c(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)47 b Fr(60)748 1398 y(un)m(bury)m(all)14 b Fa(.)g(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(60)748 1508 y(un)m(buryname)19 b Fa(.)13 b(.)i(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(60)748 1617 y(buriedp)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)58 b Fr(60)748 1727 y(trace)17 b Fa(.)f(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)46 b Fr(60)748 1836 y(un)m(trace)11 b Fa(.)k(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(60)748 1946 y(tracedp)10 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(61)748 2056 y(step)13 b Fa(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)42 b Fr(61)748 2165 y(unstep)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(61)748 2275 y(stepp)s(edp)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(61)748 2384 y(edit)19 b Fa(.)c(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)48 b Fr(61)748 2494 y(edit\014le)25 b Fa(.)15 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(62)748 2604 y(edall)22 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)52 b Fr(62)748 2713 y(edps)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)56 b Fr(62)748 2823 y(edns)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)56 b Fr(62)748 2932 y(edpls)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(62)748 3042 y(edn)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(63)748 3152 y(edpl)11 b Fa(.)j(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)40 b Fr(63)748 3261 y(sa)m(v)m(e)12 b Fa(.)k(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(63)748 3371 y(sa)m(v)m(el)21 b Fa(.)c(.)e(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)50 b Fr(63)748 3480 y(load)11 b Fa(.)k(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(63)748 3590 y(cslsload)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)58 b Fr(64)748 3699 y(help)11 b Fa(.)j(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)40 b Fr(64)748 3809 y(seteditor)8 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)37 b Fr(64)748 3919 y(setliblo)s(c)17 b Fa(.)f(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)46 b Fr(64)748 4028 y(setcslslo)s(c)21 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)50 b Fr(64)748 4138 y(sethelplo)s(c)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(65)748 4247 y(settemplo)s(c)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(65)748 4357 y(gc)8 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)38 b Fr(65)748 4467 y(.setsegmen)m(tsize)9 b Fa(.)18 b(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)39 b Fr(65)p eop end %%Page: -10 111 TeXDict begin -10 110 bop 150 -116 a Fr(x)2593 b(BERKELEY)30 b(LOGO)g(5.5)150 83 y Fq(8)135 b(Con)l(trol)46 b(Structures)18 b Fb(.)h(.)g(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.) h(.)f(.)h(.)f(.)h(.)f(.)g(.)63 b Fq(67)449 220 y Fr(8.1)92 b(Con)m(trol)11 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)41 b Fr(67)748 330 y(run)24 b Fa(.)15 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)55 b Fr(67)748 439 y(runresult)22 b Fa(.)13 b(.)i(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)51 b Fr(67)748 549 y(rep)s(eat)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)41 b Fr(67)748 658 y(forev)m(er)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)53 b Fr(67)748 768 y(rep)s(coun)m(t)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h (.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(67)748 878 y(if)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.) f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(68)748 987 y(ifelse)18 b Fa(.)e(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)48 b Fr(68)748 1097 y(test)21 b Fa(.)16 b(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(68)748 1206 y(iftrue)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(68)748 1316 y(i\013alse)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)54 b Fr(68)748 1425 y(stop)11 b Fa(.)k(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)40 b Fr(69)748 1535 y(output)24 b Fa(.)15 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(69)748 1645 y(catc)m(h)11 b Fa(.)16 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)40 b Fr(69)748 1754 y(thro)m(w)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(69)748 1864 y(error)19 b Fa(.)c(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)49 b Fr(70)748 1973 y(pause)25 b Fa(.)15 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)55 b Fr(70)748 2083 y(con)m(tin)m(ue)14 b Fa(.)i(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(70)748 2193 y(w)m(ait)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)39 b Fr(71)748 2302 y(b)m(y)m(e)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(71)748 2412 y(.ma)m(yb)s(eoutput)11 b Fa(.)k(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)41 b Fr(71)748 2521 y(goto)8 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)38 b Fr(71)748 2631 y(tag)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(72)748 2741 y(ignore)16 b Fa(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)45 b Fr(72)748 2850 y(`)17 b Fa(.)e(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)46 b Fr(72)748 2960 y(for)18 b Fa(.)d(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)48 b Fr(72)748 3069 y(do.while)16 b Fa(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)45 b Fr(73)748 3179 y(while)12 b Fa(.)j(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)42 b Fr(73)748 3289 y(do.un)m(til)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)57 b Fr(73)748 3398 y(un)m(til)24 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)53 b Fr(74)748 3508 y(case)13 b Fa(.)j(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)42 b Fr(74)748 3617 y(cond)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)52 b Fr(74)449 3727 y(8.2)92 b(T)-8 b(emplate-based)31 b(Iteration)e Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)56 b Fr(74)748 3836 y(apply)27 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)57 b Fr(76)748 3946 y(in)m(v)m(ok)m(e)12 b Fa(.)17 b(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)42 b Fr(76)748 4056 y(foreac)m(h)17 b Fa(.)f(.)f(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)47 b Fr(76)748 4165 y(map)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(77)748 4275 y(map.se)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)51 b Fr(77)748 4384 y(\014lter)22 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)51 b Fr(78)748 4494 y(\014nd)19 b Fa(.)13 b(.)i(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)48 b Fr(78)748 4604 y(reduce)8 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)38 b Fr(78)748 4713 y(crossmap)19 b Fa(.)c(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)49 b Fr(79)748 4823 y(cascade)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(79)748 4932 y(cascade.2)17 b Fa(.)g(.)e(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)47 b Fr(81)748 5042 y(transfer)26 b Fa(.)15 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g (.)g(.)56 b Fr(81)p eop end %%Page: -11 112 TeXDict begin -11 111 bop 3677 -116 a Fr(xi)150 83 y Fq(9)135 b(Macros)13 b Fb(.)19 b(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h (.)f(.)h(.)f(.)g(.)h(.)f(.)58 b Fq(83)748 220 y Fr(.macro)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)54 b Fr(83)748 330 y(.defmacro)9 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)38 b Fr(85)748 439 y(macrop)12 b Fa(.)j(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) h(.)41 b Fr(85)748 549 y(macro)s(expand)23 b Fa(.)14 b(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)52 b Fr(85)150 791 y Fq(10)135 b(Error)45 b(Pro)t(cessing)11 b Fb(.)20 b(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f (.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)55 b Fq(87)449 928 y Fr(10.1)92 b(Error)30 b(Co)s(des)25 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)55 b Fr(87)150 1171 y Fq(11)135 b(Sp)t(ecial)45 b(V)-11 b(ariables)38 b Fb(.)20 b(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f (.)g(.)h(.)f(.)h(.)f(.)82 b Fq(89)748 1308 y Fr(allo)m(wgetset)29 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)55 b Fr(89)748 1417 y(caseignoredp)14 b Fa(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)43 b Fr(89)748 1527 y(erract)21 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)50 b Fr(89)748 1636 y(fullprin)m(tp)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)44 b Fr(89)748 1746 y(loadnoisily)12 b Fa(.)k(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)42 b Fr(89)748 1856 y(prin)m(tdepthlimit)26 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)56 b Fr(89)748 1965 y(prin)m(t)m(widthlimit)28 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)57 b Fr(90)748 2075 y(redefp)15 b Fa(.)f(.)h(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(90)748 2184 y(startup)15 b Fa(.)f(.)h(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)44 b Fr(90)748 2294 y(un)m(bury)m(onedit)23 b Fa(.)15 b(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g (.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)53 b Fr(90)748 2403 y(usealternatenames)10 b Fa(.)16 b(.)f(.)g(.)g(.)g(.)g (.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)39 b Fr(90)150 2646 y Fq(12)135 b(In)l(ternationalization)20 b Fb(.)j(.)c(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.) h(.)f(.)g(.)h(.)f(.)65 b Fq(91)150 2916 y(INDEX)10 b Fb(.)20 b(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f (.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)g(.) h(.)f(.)h(.)f(.)55 b Fq(95)p eop end %%Page: -12 113 TeXDict begin -12 112 bop 150 -116 a Fr(xii)2543 b(BERKELEY)30 b(LOGO)g(5.5)p eop end %%Trailer userdict /end-hook known{end-hook}if %%EOF ucblogo-5.5/docs/usermanual.pdf0100644000161300001330000130735310276035435014550 0ustar bhdoe%PDF-1.3 %Çì¢ 6 0 obj <> stream xœ•‘ËNÃ0EYû+fYø1ãØÛ@D#Rª IJ*¡Zª¤‰¿ÇÎCªTu,eäãñøÞ›$*q u½H–›ƒh@uGcYï «ÂaØj‰–Cõ&ú{ ¼¶ ½…j'&Y¾¼ÏËüåºúÊXôƆ®êULÊÅÝ"Ò”ÐíÊÈæ<†wÉèþÉ)Ità¼Gç€Ù)”.jÌ ‘sønµHžA‰d?ÙÃM(Å-\‰¼è&]p`A/½:u`œÇÔ“FêMÔígT¥5*¶fZoëßsZî7ûŽÚ`ËÒ@ŸuÛQ>í¯¾:ݤ#<®¶q¡!«£¸)©4Ü5! #‘m×›µïý"Lõ8a¶j"4ŒRé1ï^ìY°áÒ¬’üÏ`ãú3þ{Åendstream endobj 7 0 obj 304 endobj 20 0 obj <> stream xœ½Z]sÔ8ÝçÔüˆ~djiÇ–ä¯á)d`è*Ù¤³µÙÇ­$Þé¶ÛMÈþú½’®¤ëX0³SEE-]ÝsΕúÓ"Ž’E¬þàÏzwôéèÓ"ÑcöG½[¼\_$F¢2.“ÅúöÈ| Y”ñ"ç<*Ùb½;zvz_íGÙÿ¼þÏ‘`‘ˆy“Ö›£gÉ/j,á+ †c«V•QVI‰ccßé‰"b"·7‡zl:=›‹,Ê™°«ª¡ã ø’G,I…²l)XñÈ`ÁôNœ±H Ø)‰ba¶Šôf¬€5â×xÿY›yj ýçF>à²×.ÁŸy™ñÅ’•QÌËRÏ?íöxŠXäyì›»{½¶ˆ’"µ~õL°)V3#ž–e–èßÔè±|ºáb9™u݇삓§êŸèû²äè-®Œ5£7j(ráæ=š sQÆöèã½ÔQ»£\È;Ù¢ëráÜ4z*ƒðºÄénqL¤n̯™.q®ÚÆxžEÏ„óüÐŒÆÜNhhZ”qöN«msÛõmS©ß-ä@œ•‹e’Fe¦g¬ï›c’{Ïìûvº4x”ùÒ0“ÁÏÔŽÝöR¢…eê–º[Ù,*rwCÇÞåU/_èO'OܧMh8œÏV[wÐË¥Qì·®«wŽ}pz¹i†±on£¶+…n?ãM8Až»eªvsÜé4âY$a½¼³õ ucçnšÛG´7óçr«¿ÚA®Ò2' >àÐN»v)b‰Êð'.¦‘-·¸]¥Œ˜_å·wW˜””­ì«­Ž%TYáby~¸Ù6µ*ØÒúmSËvÐËs•õîÕ€¸H\·W‹ ÷r£×W™T^›—W%™3ùµÊ¢$.ãÂÕz-öG»´9VÐXøs˜I6/âÀ.ĬRªS2U¹æòO6`k1â htŒ˜þåçy¾ªÊE€TñIÅŒ&ÛÚs> ðÄd Ís &O˜=¡I_ÃYv‰ëgՈđù5‚¥ÕcDìœÛí•#®Æ< ‰cŠ ;ái0´"óNßVÈ® u=ÞÕU‘Á(åÊ Q…å‡R©“J ¨¦§(Å(TxLЩš5»éí<¯}^’RºGZË=Ý œŸ|¼7ŽPͼ¹eºÒoóÐl·M&Ä”M– ìräía«s§ ¯=ÒP")%*|öfX­ß¼¿Zëbª~NÞ}Ä$Wê…“$ÿ`l(}AŸ\\œ¼[ 0 nÂÜ¢/̉r’ôPO±TÄ”cägÄÒ$wéeØ8ç%ÒìöÛÆ„x ^!æé‘>Ò(!$®?«@ê lÍÉö©‡§ä{öêW'"èô 8Lï žÛôäåêíÊ82…hg¶«ká%ÅëÕúÝ«ËK%^¥II”^Ï]ýþÂI:—y'˜ŒÏ–|Ö•.¾È¹DЬW§WoÍ/RY>ÆçWçï/_“Süˆæé})tdJÏq«(ÇMriÂqqòŽcþ·èð,ʼ¦ßu†?X%¥ã™«f;DÕBä¶Œºþh2.™k˜L¥¶ ÄU°Ý`‹Ô™x_ÍQ6„óäìe-QKæQìW4ef+¬5…NT!ÊFdSÖ€y©K$-™sÔ$Þ³+ …U /1E¿Áˆ©,ñl´íÚ;”YqæhFÁ –_îUéˆDMèZ°Æ× ²‰F*‘ƒvÜÚÜÎ%cÛy‡^Ä-ÿÐ7Fsª–ŠùÇêÈdŽ^:öç„Zøq›Äâ[›8ÝóuOš»[µuô|NãYž"¨ÝΪaÀã“>ëä3fJêo4 fš“nEs94@0oúfsgf/yY€·¨4>;Aö,<@Å,ᥡE€qŸAW—'2[”+åjƒà¾ù2cÀx›.ÝÔpQ—T‡@óæÁÛéÝÒño¬:ŒVè6ÏÉv8s™Lo”FB 1wÉ{†§¤ÿ´š Õ!ÇÞVXx@¹šsç5›Bd>OwÍ0Àt«C¡¬]­´õö°AE‡qý@µ‘Ÿ•©ÀËB¥å¦CÀ+<‡Ö‡¡~® Çs´NV}ZèØ¤M}Yî\›È|b úLÅä/ì8ÌaÉ…rRï_oS=Eµíeµyœ³Íïm‡„Pøà< ˜‡ä{ë iˆ3àQ¿÷´•çþD¨z'’åmw×=G°N}­Cì@3çTlìd/·sòÚ÷rp#4”yPÇ!¹"s ÷á^ £®ï¬Õ­¹±bŒ*¥%æ”&ô…BrjÉÔ][ɧMÈÄI•TÞi·Û°Ñyµ^üãèÓ`GY/– `GÅB@g¼¥î-_®ŽŽWg‹±?È£ã‹äèøúëåù)üXýºøÛÑ«•^éÿ¹ÜLŠT´Ú¬o8/ëF¶µüªiŒÅ9dÞw7éÛ%NMS™öu»D‘CÌ¿¿])S:yâ²Ñƒ³®Ç­á…žþw[¯žŠ'eú#NÅFå=•¹Ñ[Å•VùkV=YIÁÃÈ&Í~™f“¨=î0@ä¢#@žJ˰'ŠòÇØÛ$Ó¬3 ‚¬4Ä_®ˆò{)B!Æù{<çG숙ï‘_öMåðÞ«ð7U¿DÍU*UñWfóåúÙÙj²$öÕw3X‘G®l“²ÌñÎ æ{%eûº‚Ê ÛüŽñ0vpÛJæä†­Eª&¸E1(¡$}z/µÃxfP_³®T‹g*¹ÛßWƒá0¡–šoJ¤ó`’}Ê—$Ù=™dÚVTBµV­Î3^’R5üFb¿›RÝê/Q™ß7HÞÃ~Þ0ɽª.Å|‚ÜÊj<ô¨¸ —ð|~8qDŸøþb+Ëz´=c@+<‘8¿’³ˆ3|¹ØWzÃ—Óæó§­Á_”Áƒ7æwÓ¦©ÚÙ¦4…Zw§½j›/V_å~ø×÷—vTø[ÀMk$1d2i¼LÚƒÇK/ÈQ¡•ï. ª%+(\—œÛj„bØá½+sµ8!S°¢u,Öí–U]KÓÍå©¢C·UßW¶©ôõøˆë•€Í9ø¬ Ê J ý"·t­Ã÷в›ëéP[Ôû~2y~"›ò~˜ã†“ÎäÍ÷0È~¹‘?µæâ$‹#kæ¾·º¼ZÔr£2Ù*Hhس‰ÎTÁu½IuЗ¾Êƒ—NÛf°=>Éõà¾VƒýU;™rýlSµw²ïÃõÏÆŠD¥¶ºôVœ›hÄ(ªƒ¹WÊ$ò¡gòÞ&û¾ëmªf¾>|ú1ò€`ßK˜ê4]þ‚ǧ뜶t!:@v Ÿi¡GÖPô´­ˆµ¤ÖîÁÖ- 3†Iµ-×VÏÛö€;²m°êjç8r}6ºn‹ *ÿMèìÜV`ž^ ‹òÜ«²­F+€¨Yê|z˜ÕMXÿ7ˆÉ ûkJøÉ÷æÔK–—jSÊßHw\œ{+UÁ4ê`Ú"PØ4ÓB2TFMp"¹CÙ`ÎÈãzàv\nšQn0ÿ3¡ÚmšÿæÅƒ>b@¢Tû¦]šrƒ¦0çnÓGüäæ`ì~GS®Ê¶ù¯‹çÓ”ÑÞ¡ÁB¾lþ¥ß/øDŠJ½'þn¦<¹OŸ¨1þoßT³i>@f’tUC@äª8 2N¥L¾еö™Ÿ<¶ï¤½³ËDHŒøï1U¦ ‡Qˆ¯UfYÇÒ§—+ Ïè#ƒ¹ŽmÉ2V_,MyË®Ÿá‹~êü+z¥Ã‡ú©Î•_j¹祼~P¬¾à±umTxdpõ.%hɼnúa\Ö[¼Ü…’vÇMk ó^½˜»ë¾'È/ ”ìÃxª”™«µd°z36YN+hÀï˜$4#OÎÏß"Áï˜|´ìÇ %'Õ’¨ïð¤ª[¥ï5{q"N¡J3Z‚¼ Ïtm7†êT=¹ù4½U×ì(è˜Ï÷üL4þKÙÿŽ…˲­é`”<ƒ»&$§wžæ"6ðÂÕw7s0ïÆ¦,±sŸ¿;T MmŸ ˆß®VØŽ±éÍa³›<,p­ûª¯¶¶;TYG¿P±•M;w‹O¿|H«€™Û±ÙTÑœ…B "ï;üªÄ‹|?ææ`¿D^dÃèšµR½…‘4‡5œ ßþ„¾Pþâ›ïendstream endobj 21 0 obj 3245 endobj 39 0 obj <> stream xœ­[Koä6¾{ó#Œ\f¸‰Ô39““™Ìd=Þ|‘»e·2Ý’GRã¿E±È*Jìv;Yø`@-Qd=¾úê¡O§a†êÿ/·'ŸN>Fã5óo¹=ýþêäëËH• ‹èôêîD?ái&ePˆÓ«íÉkñÕÕŸ'2JÕmðóÕêäõ÷ç—¿œ¿=ÿCý’&A˜‰ yûþ§÷ãýIP$©Ä«I¨‹ð¾ô4ЧB½oGYPÈütA>ÞãëD¤ihý©†ªûúÃøOý…"Èüõw}%(¢Ì¼¯ìêòvS©äYj6þá©—Oƒ0² å_¸;G ¦ât!Ã@¦úxí}‹ dQ㫺êæ~W÷ëª×KÉ/•Æ(òoÿírÜ1È­È^{ÿïóþ{yþÁ·‘4 ¢ÄJø®k·¾wˆDb%> Tæ­o./Þ|ÿÖÿ†$ ddßèg“¼Sóð¸ã(ÈS»ÞC7Jì"J3sŒeµÚu£ÜeÄElD\÷¨¤œÄPªKE…E˜ã¥¾Æû² íšíÝxMqbÅU7ýÐí– õËB±Òñé"’ЭÛf|£ÈÀŽ£§Aï”A+-Ë®{oU[±·¶»q'BiÞî¤o·Z§È¬¨—íöa7”êߎ’Ë´\Ù)áà!Iîóh—ADºaö*Ó eêÊ- Š,?°bSn«>Òy—mƒ–VëCY7Ú‹¤©UѰ.õ‘ã !;Z·›Uâ‰ie¶ãå0^Ÿ†Ë¢µæû¼ÙiIŠ (ìËúÝ”Çv¿km&YHÖXj©È ެÇ—çAÁŒ¶Ñ¯Íèµ»­YŸ àV[{œoªî å–æVùêR$´ZÛ­Îð’±0З£ ÊÉ :Ü30=-È"¥E“Ñã Ë oG\D¬^ºÿZ² (’ö@CW®jeåf@Xs²ð•¿ÛöOÆLò™É_æp VÐg944m³0  ŸXQW]½D›„^1¢«1§MQ¹°·== Rº6z8>sÇzX£÷ÆX =üîY»ÑOG•G ]ü©«ºª¯Æë²àh;ôÚ¨•„A JÖšMW}ÚU½Þ9Ä/z³wêFl&óÈlýD2Í·ÑÓ²ŒN­_Í-vXWhHileøB' J«‚D©ÑØÆí̇žpCQn/1èè’‡4 ¥²÷7¨×Œ@ó‘ˆØc$6‚°,9‰²’qAðq95o5Iˆˆ ¢»5ybC ‚Û§];X£#c«ÏmÙ}Äx‘=gl°ù0Âh6çιW>`19Q=ôÕæn9P˜DXƒüQc½Ÿ¦V•Û‡M5â@¬è…Ý©¶^ØiêÛ)CM ÔF>@Z&+ƒ Ži¿]^¼»B !(äüxqùÁ\–„«_^¿¿üÁKßrÞ‚/íæ7éÑ—óЊÎúÉô(à7Œ?ØÝN·AW’{•w-RؽXxÖ‚ÖêÌáØ³ÿfttéåär·–q°~¡XçüK5œHŽhn»6»$ìÙ§ýÈ»LClmÚÜFþ?dö-Ê,‡Å³×…§p]úzñ~q¹ð9hçaŽ!ùó}@:cÖÈW7jÍE`¸rBæ\×j"¢Cå-îƒQ. ÏŠöeíeÅýw#þ¤Y¯ÖšQÄ1¸€c²s*á‘ýœ=ký~Î“ÛÆj—eƒ32ö• ûìè6î8,ÉkÎ":‡påñ €c³×ûú3j ^o­ô¢’©ÐdÓdJœ!‡UØ»€°Ÿi*ÂFcÄ´r2Ô/ð¢àžÕrô°î†aÏ¡Ÿþ”!ÀhZþ_éPVLt©†üYù/t_9ô¹dMÍ;îi#Hå@ÞŒ™ÇD †&AL Ñçz¥“¢JˆÆ„ë-äŸ1ޱB žžS±mvk{»ã0 bÌô4Äþúæ—s4é4ÏìôL …;ÛãZç `CìøkÚ£¹Qqìs*„·äéx7O™ÊGøëµO”€X†–*N¡èYʇ ã¼6¦„g+Æ©ÀW}–ï©zœ»ßF—d{Gœ™œ'%޹¹¨b ]*û¾¾o*M髨ÂaáJoVHNÙ¿èt‚¤®’¢G%Œf!áq^“06ˆ¹Š §%PN~í}|¯ÎW-Í5A4£ÌáÏž@ð"'Ýåú‡¹îªeýÅe”h?]¡{\·}eèI™yØT<5 ‘Ø-|l ¼ç9Ñе Øfœ-{2¼rõWH)•ÍÞœi¿4ŽžÚì!›>j®òjLAdÁa0r(”© òúšÇ|žæú: KÙõžS,+½™¡{nÛmVH‹fˆl¼EóÀYP– ð"IGb¥NTVMÌ/ý#øýÍØŠ€ÜžÕœ_œhGb´Hž ø —ñÜÜ—’&N˜d¥µC‰#30uV«´êÓϺ`…2×nÐ[о68­Ý˜ÝmX¨Š¨”l^à.a›CÛŽˆ$|ö§Æ7_at†ƒgn™eq†%$â ‹—ªð< P“è`X5"q,ÙÆélÞш)ŽÒ.ó³ÜÙQî³Ü¹È§¡ÊÍKžåμîøLµÃS,J©úqõóÅ»Ÿ|¦¨´FÁâL³WÎé\Þì´L±H&‘z(?¢A3¯œ+Äe3/hZù ZiH/‚c0Oy!À!ƒ Ü6£d7CF©ø;˜Ù”¾?Çý(г~µ5Ò(óI–÷—Ëe<ÃôšÁ~ Ðû3x+Èš²äT…ÂΣý‘T 9@!Iº«õœ¢ìzŸ B̲ôˆÂ«µÎI< øqLéõ±ÞlP~9q_ð1S8‰k*ƒŽŠ’å¦I5=o^÷»‡ ½¼ÓÖcµÞȨ¿©ØùüÞ6á»öÖ´f,ÚS2Ä’LÈ€cm9=ËÞ|=IÝ0pkw«¶©â•Î(qúP+Cdç(€(È _³›pSÈIêñt«J oî3ödë¥ „*¡*vÜê­Ò´2áÆx4W{ŽC$é¯r®d'=Ô æ=QO3zÙn·Ø#’¼òÝ>Ìm©êƆ’'!õÏŸ”›¾Å(Ì·À Â-ëCà­¬óTÞÞvÕçº4ÁZÈ 4‘ñŠzÃ;_ ¨ãŬ¥ž\3céçmÝT^€Rá\ÌQÈÓaDÕW ИKøùrƒ-§ñ8øÍÀ‹s 5œ_!§pÒúe»ÑârwCü’úhZ’¹ ³–™¶›Õb¨!«%™¨ŒÇ‚ØAÓî¦çOT É–Õ¿ônìþÚ÷¯ÚÁ«­¨à%¾#Ò%e…]õ°)—~s€ðžKk`ûÍ!â”i_-ä ïfu5ÞÈÐfÃrVqûmUÙmjÍÙ!–C†*<ƒ0NHèzô ØyJýxÇ÷æ"¬Ãª¹~"êqS|‡B`ØšàŒh.€†|¨¥‹©Ñ9a°½*3ùó©£-hQKLe–¤´C½ GŠæ N§©*“³ñ6®ÇY ‘kÄδÀZCºš!`iM…è¹7'†_½'³Ên¨—»M©§„ ˆsY1?ä\Ç”¾Æm¤iÀk;ˆ–l¿°¥g2”t¨4|°¥ÆØ©ñUX—q[odUÄ!{=žø4rÚ„‰9B%]’ï)F¬~9F÷(aœ}¯§ƒ u¹ƒyê)Í §ÝBΓ=<ù‰Ð–rŽy\œŒ4$ªl?˜°Íc‘ ë…ÃÉ÷ÔnÞ_›X`/)ð~óþí{£Tí¶þ®G:sS=º—âŽ!®êU¶8ÍŒAó!ÞßœNc U­Ò?©±mŠ’sïÕª2ùÏPß=¡§³¤Ž8Ö£ý›'Ý߬A$V ‰ª7¯.Îdʘf) w ®*W†õfÓ­{ŠïF% ÊÃZ~°ª§ÿý4å dcuOóÛÚ:G§ï4ôªK§Ú)'ìDžä@»dT‘)«TƱÙèYHEk­…{r£Vs¾#û<£ÆÒºJŒÁ±6 ÔLÒ–¥Y “1 #ðþ"v3ø—Oçy*FlZo?ý‘<çõõ†þÑtË\á>¯¤Þ2éŽd˜i64qªý#ò¡DÝSäMUmÇlãÌú<5qXÍ6õðªÇc0¯õ@£pk8†4=ØÈÚñ÷pÈWÆb6ÿ–¯mYðisžov¢ÄÞb‰C{më1³*í¥±Z»?¹ v’Ñ] srìo¥4¯Ì<. G[¬ƒü=žˆ¾jzSH<£Qüc†þ#Y·Y¹éŒßd¼p~(±e*ñ{ÀX9qsŒ‘ Æ¥éËÝ uXÈ Ôõí-,mñ‚ϺDƒcí7_´A©L™zþRã€OJ¥—ßéõx¾H9¶Óã Õèw!ÕF–œw½Ù(^}?Æ­8…Èç”x^™¹3Ö»Ÿ¦Ð0†Ý)\ÂK ûmÜM¹ÉÆy¤Ö¨]ªBÓ$Ž·•Sj‰ ¯p*†E¤N»ï —•T﵃r¹3øÎ!u>(ÇèËmÙu˜pCæ’†“¡{px1ƒPdŒ¡BVúfâ Q†y&¥–ü»›š¶ýù±¯Š{_7MÕi’èäG×k}…›¸_‚ ‹r…5&¦0€]2ø‹U{h^DL¸ûv;‹«JýŒ«JÞ…ëMÝ€“ÝHÌG+Œ2ìcߦÚ‰xTˆg’;ì©;Åó=ugîæÀ¾^!šWt“}ãržgÕQ£àî4¶¨€ÅL©«æŠ³…gQLËé|–óE¯ßó‡ûœ}&¸EˆTirò=“;2ßå3M0'Kä2ʧ2º‹> stream xœ­ZYsÛF~WíÐúÅIVD0.û!¥ÈJ¬Š,z%ÚÊVå¦ k” ÐJö×ï=Ó `xxkË®‚†3}~ýuÏ|9Ž#vëðÿ|yôåèË13ßÜóåñϳ£¯™P_¢".ØñìþÈþ€ñq&DTðãÙò軳Çò©«ÖßÏþ}$y$c‘ªE³»£ïØ+ý‰ˆ9‡oþVDi‘³¾uë•Y(#.3·ðn3ïê•Y-de\„þôãµèI6E%;žÈ"Êͺ÷×W3û󈧉ûù»EO¯í}í&2b½pÂÒHJ³ºlîôRGiìE»\=y‰$ðõYRBÈ‚Á—Õfa-¢Œ¥N€uU.êÿTF2AÍÕ=–èS¹ÔÏóÇhùͦJXá7 kÄŠH2oúº5VŽé·îÑÂòHp¯_S.+8"A¹W÷f%‹Š,w–ú“ZqŸ¾êOIÄÐ åº.?-ª£±:ˆñÌ´êàôO§çðíçLîW.QT¬ÈÄÙä¹n ©8ÚGT¾ 5e&UÌH9šMÁÔ àýå‡ëÓKS}c T¯n§×oŒiµ^¥E½é‡Ùû³ñÜo”ÍSÜoÕ/¥/nÌö,æQÁRâ¹ó«7ÁËê¼­l>ªÄ—»jÒ¨8æQ†°u ø˜å>@ò¡,úwè_ °BÍÉdûzUv›µ­"‹r,/scÉHbø=®ê¹ƒÀsÍ%‹Š‹<+,‘ÿÔÍÓ¦s® ¸ EŠvlˆˆ¡ÖÊÏ$ƒ F‚qmÝ€Ø ø1žëíã4¼«Úùºþ<&KEæ³ ’Gˆaò¨,O5€ÒPü\þJUîÇ›P“9šy“ð&™ù wE¹2ñF©þ|‚‹#ªy×F©ääÛZÕó ¿G*vdÿ l¡Ôw5f“•GÍÜ" £hÈ5¾¹#n·e@½úšK¸úºzZW­-¢°Bà6ÓiæeÑ<âek« Ìò^=®—Šd}b¦„˨Vªú“öo™S©‘Q‚ÚÌWË1)ùT764‡`q¿¤õJG€ÉCø3ÄŒ"¶]ÃÖßbݣ˷<˜· –{ù€ã0}ˆß²©žO`!i,«æÁ¶a:3o¢p-~ T°u0ñÀ=2Eº%èLjǽþj[è ®>€4õ«494ôrU†PHdV1âç>¶Æ0ׂô»+ëªx?3ƒ§™h°i¬t#¶WáY}EŸ¸M¬Ÿ”ÎŒ4SónÅEÃùÿ9Ò1*bŒ†ÔƒÍ9¦ÑÌ©#»y~´_Uò*\ȊЄa”,„š ‡ªl*ØgÚɬ>»JM^u+I5Ýa”8ü ÌGÚî ®mìèÅÙôb@ç¦ožä‰Æ2ºî¯7‡ñ˜z“½æôûêP„è¼>AòìmxvíuÚ}ò[¦é—góMÛ­qv’h¦áÿ4_lî,JåˆÂ–êkÄÅpÜ4_6«®º¿sáW1ÎHG2'½®‡f|6h”“Ó^Éê ÇU,³ý5QŽMT ÌŠ!™#zg[Çœû·•iÒ=')?nòÓ#*¶S°¹‘öAš#’˜Êl@Gs‚{»!.QäÃË¢Sd@xéºrüª£ª*m‚J¦üéƒÁ7¥ÆËã2è¥õ6Q]q¶oÐ bQ.CØ Í‹ÄáE(hÃà= Û4ó àœÔ3=’ó }uÖ,ª¶ •(°Úy’¦Ç² qŠtÕÒ“~ú‡qq è,0X§È·Ü/Þœ¿wpÜpöö|Jºñ™s¾ïà `›BŹÐíÛ)Ô°ÉïíXÆS µŠH’l›S•¤3ÙýÖhº\ÿ¿¥g\ÌÞNmC:Y¢¹MʳéåôÊÈ«¼bó‹þ”öèÉÔ˜³(GðühÍ“e§×§?_ž›=SµÑíìítzsnÎb ýYÛ71kÚ^¾³[Ë„v;S`Ÿ^Ÿ£y] \Mgh7÷ñôòf ᬛ4œƒqtvþæƒÝê{cÜw§¿k®ÖÞãòËvìÏ¿­Û@1„ØØOü±5>]”v§0h¿feÛk®ç">¸Ú6 ,Ë4á¿;Ä)ä¾9J¯Ûj“Œöš[ ±Ñ¦UÌ~ñWh3Ýc’f›“F±B7( 'À`„îö{•Æ•TÂŒž š)ââ7M \Cšçvµ¬ô´ÚØ á:ð<Ût3£' uÛ¼´r+r2‚w3X^icoº>©þ,—O‹-3T®Í°}SÔ‹«³ëówç¶®é)Ð+¸/œdRsiÌ+ƒa),ïßžý¡ÀÿâêWÈs:¦UËÿøþ ªE†Üò5äZ‚µóJr£f[w61û‚‹V9EÂàEPºÇj]ýÝèÈS“—4œ`š«(®2ߥn¾^z¯°!^ü>6sbÑöÕz’CÝÐ%<õ.±[O”¬©²qÉáá+»…6ù@ß4\ó†£x Aʺ‚öŒ®†Á©$"µ¶§ïˆÆªªúw¥k ÒÖ.2 ÚÑñÚ7 FÈ¥én|²fÈóê®…ÚF&žz%F+Þ·‘µ zÙmP>¹ôÀâô~Ël!³¥µë¾Èп\‡®’i˜[êºwÙi ÞH1$Á;Ë}”`z~\Ùi¡ª9êCâ*ÞY/xT2gˆ†„§†+{–~úЛe¸R™Gœõnÿñ}GŽd¥f”£ì`œ^B….“‚W<[ç(ýÙâï¯!®$ ÜÁCöÕxòHb‹Þd"0Òrä­žÖ¿=£‡¿EP$OðÑL<@^?쓉(”u9åÇ÷k{]Àª`bs‡ÞŽ….IÒhüífóôXBš!Љe½XÅ4ô­Ë}l¢Ýî›§O6i$U%à5}qRÛÁ×°6@ÌSî’¶2å”box×A†P¤Ä„¸cçÀLëese0=H!&Ø9C—ØO—÷ð’mt™˜Ð”ئ¯j¾T·“кz^‘€"½º ]¦Úk¾ÃP¹ÇåCa¼%Ä^q"!vPÄîx 'éd6šv7zÁ³iˆ"äåNè¡Ðóºî‚d‹ëù™÷àn²¥ñùh·‰Y$¸ø?ô}Ö`ýͪy^­?×̓åèL×Þã¬aîèu[;ÒˆL f¯ú¿ýMG|ÀãÈ^<Ø90޲•c0nªgPŽäïÎMæÙ¾ýïW¯^$®qÕp¿‚G”qã“A¢¶J@’2X?ó^4ÕgÂ…œlȱ]~¤Û®ƒzº;waM Ö3rs 9É5N#ß5ä'‘^ºIU:˜ÊCË…‚覄×2U€€$ãÏÕy@sØ0 <Í9Æä–K :ÜqIá–´U·­ ¥ôr9¸UarKö½¥ôÙJðq¹wrV~*×]=ß,ʵ%T¹ªRP8ÚÝ6‰‚NT±‘&ý\C眚àåc½XcLöבñ“º¸fJ`fps>ûe:ˆ$ʌª<˜ç;À¶ç³ãéÿ£øendstream endobj 44 0 obj 3233 endobj 47 0 obj <> stream xœ½ZMoÜ8½ó#Œ½$¸9"E}0{J°ž$˜Ì›x ø°J·ìÖ¦[r$ulÿû-ŠE²ØbwÛ;ÀbÁ¨e‘¬÷^UñûyÂøy¢ÿ×۳ïgßÏùôÌþ³Üž¿»>ûå3Oá S‰âç×·gæø¹J΋4eJœ_oÏ^ËŸ¯ÿs–ò\¿?_¯Î^¿»üüÛå§Ëé_òŒ%…(ð—OWﯦ÷3¦²<ŧËôÃ_>§Áz‹´TŒ§åùB*VNoú½Oá°dnž~¹¼þõêÊ|"ÜrZ0‘É ×iýüÌ‹’ã³*¶rÉ`é$ÇWþûrÆ ©{®¡Ǻ×ï ÅråV¼ï»iÉœñ¼øpY¯v}[7MXéÿ8ºnɲÄom\Wã´ª`eáì9VߦU%SyaÖæð‚¥iiwÒµÓ6¸b¢tÛkÚûùhÉDžI||?àYÈËãÚU$,SnËj¨q[‚lkmV+Y_--ÝjÅÍϸÝ\y_µ+\KúTÃÐܵÓ&©šÍ¸;çîn:…(÷'«6˜©r_xð™äÎæ»¡îü@áýãLSøTZêG’Iᬰ6oqVf>ækÀ̧DÝ€]{ƒ$,-\ Xk+š?c_­š±éÚj3Ù]2a·Õvc¥¹˜¶R°$ç¥ 4Üqâ÷ò°n¦M Îdḛ̂¶(Qºƒ¸€N™œôBêüN²)ìã¢Ü<ýd‹ÿrkŸB ø§ËªE‹(áùÕ„Ì=ÈLZ°”Äxg…û*ý#Ûk\ƒäÁm×cr@,»ÐÐ`¯rÅ€ $w.óIÊýiüJY~l¥ƒ‰49Ð\eŽKð“ ÙxXõ‹ßMàü‹Çè\0éQ%ˆàœRÓ…8Ï œÌoÿ(2ü'üƒÏ‡QHˆQ$<‰i$9Î o8úÜ,‰‰}™Æ{¦#ÜZR¦³nç4ˆëÇjÛ´&DÃ¥dñdoñÜôÙ&€“%Þ;&Qˆ»½¯H2 µ€G—Ì?¢9j3w!“Œ•eJsò÷Õh1ÖCä¡ Å…Ë` kÚ6_@âH·³Si()rz@Ÿä)Ë4àú„2͇º·0FpÏ…Xîmî žû°{° ê×szëã:Œ0G³´n€CÉ#+à2$ëÕ›¹z8I¥D*%Iæ<ç('ö(*“Ž¢lR„n_ Í‘B,yh2Ο–O5E:ìX5ÃØ´ËÉS—x·}·Eroc˜"âBx&ý`¹pR6÷/¶ôVaxjnñEá1Y«ë~¢Aû…Ç»‰ETfÇåXÎ9—c3,Î lÝÂomŒ)&ïëñ‹Ö}@‹‘UÖ¨z>@ÑæT8ªFÁ¥{Yôâ3ìú³¥Uoä?/­šðïÝxÆ€™E‰õÜxÞôA‰é/¬âËC‘2UBvëOáA¸U}[í6ãÆ¢ $°®[t2ÏæiùìŸcÕ-ERâkºÝýÍÏh¬"£Ò¬EX•Ä„·æ¼º¦4~€Ê<ö è9´ÃØï–:uP('ÙØ×·V+h¥^Ävˆƒ¹ £b.k;AÑBuöyl’%,Ï\…¹Pžm…g‹›×ƒ}»¤Å]´ºŒ•qußÊ‚øRž·õ0TwÑZWjfJ_Pc4|ZV_užyIqò­%‡±Û~Àì)Êyy2ã,ÜÞÿ2_ë0Æb‡*uÅ-Ô±C•Ó¡"¸é ¤Ýf…x¹^HŠöJñ ‡3å[+>j Nx¨AzuàËMïÃ’–å 4¬‘šö?LJC-Ú|~{“mœD%„óýðÆ© m¯68C4#‰òѲC°Ã|÷¤¶"œíƒÈCÔaY¿©«aÄø%mˆÛn×ÏÁ%"Wª¾ZŽ˜ýR§cËM×Þ] ý2ÿå¨>‹6~ê›…¤®×}m(E”üX}Š—ï¯ê횤2Œnd3P¢©T F°Öëè€æû9zÔ¶j#É„b7¥ ÀDb©ýÆÕÁs_#\§ku›!ZT—Ä–àüèé]&`ڜӴtÔL‚ôP6Etéô–¤ÖœA÷+õ{¬”eÌ¥ÚrÙ¾9j;/J6Ö§qUr1‡øÿÁª‘¬]ˆ"Û‹b­†;S¶I­ÙÓü؇¢1Ëþ£ÎJ«b{´î½¦a¿8Ä´tÿ£¦´]ZmúºZMÞ¢ZzÝ8ñ¿^qDPZyÁ˜èL¤Á'‚‡f3U"a£ÖÄ™V+%ß;Ž.Rmâuß,y-ç?ÊØ¿¿ýí2Fa5éªȲ³Xã–@aJa[ÈŠ¶Tcõ·¥²‚ædDœŠÉ…„d%U…˜ÈK‰W¢>kh/ýÀs’A¸›Æ Nš45»c±4€Ô#½vXôÃåÛÈ‚ ä½Ï43G5e³ï3šÔl#Ñ>Œ$£O·±ßÉ£eµ»[£Ù¥ï/™L {VZ²‚ó'›äTr¢}§É…#ƒfƒA¾»yB6H¤gˆ©™JrºN嚈§}÷¶~ð¹IC†0C‚‚ùõÚvê¤ÿ̲Ûn‘àg]År_8½ÿtõîí§(”ÀeÎávBpÑ_™/ÄÐj2_=G¶j§2½ôG<¨˜îšè«T'Ÿ×5ã\Ý~`Q0•zRH‘ðªuó[RYcwÞØÆõÛçví°“z¦élømHn“`8ÌÒÁ‡Çu|„•Ñb„P–ÐF™›F’Z9>˜XWöfY»Ú< |P"Äfzë*ÅÏ+}|Äâ­ŽÄ%:+#ñbyî— Z?£-~]½ÿ“䳆UpSkÄ$VûUÛBê~‰ Êô(k/Ôs3µ›-–À¾ùlrñ©¶µ¿:«>£ÔŒJLµ\ú`†l\!s„Љ’®_5mÕO˜(SJßqíV?Þ÷Z0Zá¬aØËf†ˆFºMmÔåžúîµ…–»MÕÛÉ9‡äŠÝ`¼ºì6¸jxmÀáT0Fœ’Ô„Û GvVó‹ÉPU›µ så>‘™;é:ûnÂ÷uŒµ‚ƒê·ÅÛªÃ,,g¡^œ^â¢4ºð;"‰•Ü¿µ#iÛ¤µ L ]Êz毨ûÃT%/À庒T¦¾r+i‘Ö׆ôA4pOÛ¶Þv­™me‚&jÕ¬Ûx%£¼¾Þ6P5šÔÎtÅàŽ!®™oëkQH(Ÿ’¥¤¿®[]ä¤>1**hý÷+Û¬'S+´ÇtͨHi†ÑøNÄ<¾ÉµS^}ƒÉâæõÛþn¿D úÅnÛddê·ç£.ú¦LÝëU¿š[)F/ëjNV?šÎ¶äÉp4vd‡É¹Çäj…Æß±$I5ïÒF{}×´mݯRÚZvíínÀ­Ô2ò_‘!èý8wS%¡šÌˆy©#.̯͎ÔlìB?rrÎïúj»õW¢¸;l>ŠVÔÓ. bL™¨ïŠ«Iƒ‘»ðÂo“Öí²6Ù™¥ž|¢ ècšž'áôÜuÊÉ<Áó<¹bh¢A÷µü‹„ûɨÙãªøX7YesÒö}wãMùå¶uÕ‚µµ¦Ë%½OxòÚ ¹zD(<¬ÀÁÙjè‹-^ÿUtüé ÎèDØißÜ%½pÒÝ›;-o¢”T†×²Ñâe¼K¦[‘~oo>þÁ->úsÃS£´E)ôü¥$êþ@±µOüÙ²ûÙ{ßN‘Ö!Û‰БK™¨}þu&œ@óü+•¹°Ö)4kóËéEÎRkÜÜ-}i…;ä™»TP÷Vñ‚‰„Ü»vBI]ºÁõ§º²î>à º „ Ú'ЙáxE^†ÓZ¦´‚ O,r@Y –sŠã7¶')o1ßwsâÊxef#)¹Ü:ZνLél#–´pž"bÈL ¦9¿ŸÝ»îEØž†±Þš¡9(C¦Ë´…æãßGsqª×íþl›Ç71„·ë^¡'W$®gq÷t@BŽ !EèÅcKJ®œÎ¾ÖõñÌUº±ãÏ"H"g¾fÁÑ] ëz³a˜Š^‚±áŒ9VM_/Ç«+ì³;å-Ž\ VÓMÈH¬¸ØîÕ Ýþævu8Q\º‡@7kS*bm\/Ò,Ñå;Aï-ªwoþ) Íäe¥Øˆú¹á_k3—×çÿ<Óÿýq¶kendstream endobj 48 0 obj 3598 endobj 51 0 obj <> stream xœµ[msܶþ®æGhò%ÎôŽ&Hð-ßbGi»€oOãHœÆêþ½ÚœÜžÜž }ÍþµÚœ¾8?yþN¤p%ªâJœž_˜ÄiŸiUÉéùæäÙË›z75÷çÿ9‘I$ã4‡›Î×'ÏÄwêšH£¤*¼öj«®UQ^•¢ÂkÓÐëe”ÈÂÞ¸Þ¯¦¶×w§2ŠD♺´”I¥…8]Ê**õõ«ëÏߥžÅIT•ðo|ô‡·ï¿3wùëJà¶*·øFSD™¬^‚%n¯}½ŒÒTfÖÈvhVS?´Í¨~ÌDäìŸÌš¸Ý-~ºÑïÜænì·æbÅ´ú•Y¹ÈÀÉEj¯Ûm»½Öf¨œ£_÷×úkIYno¿x¶úËú²»GÏÄ|Ͳ׈Ò.ð»÷àŸ%…îâ"ôø¤¬b{χ—/^¿ýÛÛ“³<ÊKgòÅ·‘Ø ìÅó›F/{™‚u¥<]vbÝI¯:*“û:8ÎÄ&´Š2Êâ*.·P¦QNè½ê5¤˜Mq±ób—® 8“Y™YmšM?ÜcZÄ™Íg •(eÀl†°¾0`çFfqI#I‹~ñ:´€N ~ÚbòÒ]Ìeüw½p›p9A6 áÙ™xå…²Vª xb:þ\¯þX:þÐï/»f¹êÚ•¶ XÇÞýÉ ª€ˆ;ÚTbþÆÑâB%¥Q‹¹h¬²WïÚé¦5ì”FEá‚‹/žEÌûÐ×ÁüЉTLõG‹(%ª°y>s«ç°àÛ«HæU,ºu3`ìÒ8ÊóLÇ.jè>¶Ûu7Ã'Á}ÀZ<|ðf¡ø^%tòÿ !¸í£ cì•:;Âa4!ɱ}oVq"ó\™ƒ@´È•çêzU„ÝÞøC9Ó¾¢kj´‚}0ÄæQ…M 0iâ¨ÇÐ(Ä$cÅÇ”h(>1}%H«~³©·ë  ÚTw.ï› õªÛO׈P!CdŠÙÕß_¡I ä±³jÜÔÖ]ûßz²œ˜gQFøfÕŽ1T‡Ž-Rª'ý§W—ÎK… Î-¹6Ç Нº)3!× ^„Âó¼ªçäØÕ~L ½ùO«Hw¬œßúá“­óÙLn˜¢’EBº¾­7Íé¨"gŽS=Lû]Ô]€B@e°<„8/Й<-®p™iáÒuJ"8#µã\å\õ{|))KÍ—fµŸŒR’R%Já{0‰¹ta.#ÁØx;Nƒ‘†úEyÌ5†GF‚Ìi§õUB PJcîT²ÁpIð;n/ض_X†Rºää#\ g¡T¡²kMšó×Ü 4PÆäØ+Ì`±S+dÆû1dGÊp>Ýô£[Sî|kßm»íÕK“ºªŽÚ…7.uÝ¥®¯×.3Bèé+ëçŒãø¤”ÄcèÍ.ès74¶õ‚ŒÊÝOÚG#Æ CS¯-µ<™‹q•¹à^ ýF¿Hr”3,:xídÛ,§Ó ›v[wX KÌ,.¯,ÎËêI8gb_yZ–ªê`?Xõ â9“‘,™ø­§ùÓG¥QJnûÅOJU:¬ë¡ÞàíL¸‡_©9"t ’Iu¨ÚúËxñÛYP-Ç'ÇÆ1£/8>ÍA¹X¨Ã[$¥Ø°7}˜*Uxã-L|?’˜íðzÖò6_”ø9©–ßL6‰yܥ½[b½ÅäÌÞË .Ÿ 4&” wC;ÙÐÉ„—Æíºî3ÅÂ}—c©N2i#"ólJ$\9:vfûYK‹3–ªÍÀä‹Þ4]÷ü²ž´v–ÐÔ‘Çnÿ6ãjhwÓ¨=žBv¨”§<¯Çýn7WÎý0¡<òVÒŽs4MÍ kŒ$t³mo÷ÍbÎDLÞ±Ï™Â Š¤Ì¨ÛñZEegÛODB‰ gkÝìãxÖÀ-f}Qk8ð–…íÇ}ÝÍKÉ6"ôÒ鸮R‚玅„ˆªô;ªf©ªÎPjÇúÉT(á• rÅ @ÈÇHóºýlë=­‹,È™LÔÖÃõ~cJ²T¬“:ge ûÀ¼é_°ÝèlÀ=|!‘™º‘ä¥úMwUî6 yØüŽY’ßß? ²âG‹õ°ßMˆ÷„T™Éa`&gÍM=Ô+š¨æø‹gccU¸$e2Õ—@±.0$9:;–d­æÝÅ·™=Bj¬\0ö§~‡5!a¥ÅV ¯à´Ó7#"«,½1’Š oL¨C€×ØË%>û!4€±°czÌ[v¾j¨·M·°)ÂP>Îßð'äøº vÒ¾0>ÿéÝÛÚ>É¥à×çoy}ö³à„/S]„ÃŽS×W¶‹K²'¤ˆ¯ÞOŠ” `GS¤¤¤¿Ý·LFØõ>’ iHÏ@ÕÔý½W5J™øÚÕ{Ó@¿Ææ .ÜI5wü4ϱ±†ÛL쳿P&Úg¿7å£`¯ûðþ, Ae ’3…2e†'iU™»¡)ÕþÏxs=ésΙxA¢Z+~®W†M+Ý×­FÒ&äG£TËZ;]ü:;p(XÃ0 Ýò¥^„ä]¾¾þ«}QE× Ÿ/õ ³‚Ï..žíš¡í׆†–©P#ðB›—”~èà…î¸qf¿"`ÝLJ­[„¬Ó?ãsp™Bo*%kaÖ%c'ç#º›–/šVJµ¹´CIœój~n‡~kK¸Œ¥Ó4çü´ uX­-5©’ªäpˆCcyÎÛJc8?«êëW/‚t…†ú†;Û¯»ƒhÏf&ÑÒ»}ƒ™5fmH‘¸1“ ɪF–ØçŠj€7#\J¥Kㄱ?•¼ _Ì5Ädg^ÚºjëM\ ~Sø´Èçí¬}OeÕ3Mµ?Î45HkL­zÊ·tVêh˜Ã>¹n®ê}g ë}»ör¨Í7Á«eéÊm„€Ô!?¨Q ëçÙâ6›\¶ŠGHe±l¡!0~•…²ÁPæ*Ñ=…n²€gw¸;{ƒ¬f½7½fªØŸmÿ¸0ª<7õžéTà"›Ç‡$[c{V>×ÍWÛÆtùRð¼a@’$º¾Æ@Ó~ld^ñþÀŽÌ >ŸEW•‘¹®Ç#soË’ðÄFž‡#s7J1Vò˜z¸ÖS%Yð”¤i8pÕ‹p(q8®–ì‡àNžÚ‰ôÞ¸ ‘™ª¬”±HFÞ+Ø =†5 8Rº–¹’ò±-èXС‹ù®î%jâC³œšz½Y×L Ép PpQç{ÓþK5§r)aГ± >ur×|iÇi´s^¡àËBÏ€e šŽè,oÔê†Ylü _æÙò*°'roÚq´ ½Útp¹ùxtKšÔ¶ãüsãÄ BîíZ8:ÈÔ††ãC>Ý?¶µ0Y¸ûþáFo¡èÍèÚÃ!†ÏˆÒA <‹qS#¿¡c 'ë\¹”~8f®’ïë¹ln3–â5KòM“Ã=·‚”!ªˆg;‰œ­h'‘18Q”< ”FL®æ¬*\`Ž4@j;¾Ak”­„YvpÛ‚)ïÒíÜ)e×´q*Ì„S–¡ ÿ˜¶pi‰›+´³Äµût2ªhåŽO˜†Ý6­‚«~»š>¦‡~.x™}ð$Õˆ`ããDS—*³Z{M*)?ÛX$p±]Ò#‰o ldÎ ÏJxx3¶×ۺ簭íN¨JGðCoN*¤1™¼7£!Í`†žzö’ù*éÈzF¤½X†¶BJšYÕƒu”?¨Ý€·?£*© œ}p‚5é›~´3'F螸DŒ¤{Û¾±úÉj ›ÂÓ <ÂÑ;ÑF%Ç»7¾¦ŒSÅ1›Ø˜rS#ÎYË|oLâˆæj§¶'9ÄÁ`Ø·o ¹ÐÛ`gçaØ!kÂ\ f¯¨qƒ9ã4á Ç*ë£ÉÕÜ#àÍeZATrž¶!iˆ¬ "?U5Y扞kØ»–©:”¡o‘D…ç±·ƒT©ds;ØpAUÌÝè©ÙâyžP9S¡¿UKÔ2õoìI@›ø8•¤]ޱ‘é üÓ ýÁ©Þ 5ð´cã±To7Ä¢ƒ7Ä^hîç2·Sµ/IÄÙDÉï%”ªf;ZZ̨*4¶fƤÙß[&©¥öÞ~X«4¶\EÙ!?°éw³D‚IÔ–5‡Ôª­ÛÇ¡M(¿=wöæ{¬†ñ97˜Îè26€ à°êGÞ’Z_ã`ÕÇÒKÛÛä|JìVQáÄ~G¿"åÄëô±¬›±>cIfômŠ‚Ò7ü¬rÛ$Ãjì+ªá^7½F„²sÁƒè@ÖÈ=q o+IªpÂ*ÉÝ~elè ™åî•x6^hÏø¤ô#¡…†(ãí¾v-»ܶB°±m¦OâŽâÓŸÿA¥×þ3qÝtJš`a/ù€¸ßš´íKcVA_ ”¥qW¯‹«œš?B63ÁsK.žî–œÜÍy량áäÃCóªï´ ûkˆ¶ýË鿈#°±Küa»PÑ hÑ BŠÅ£ÿÂÛJ p †=€±O½é§Æ¥e,ñg¿Àº”1È«|Xu‘Èv#‹éáðçŽ&CM‘“Sîíõ,Š|`€zXð0²lŠÚe <ç°S æJ9ª-6j¾(RíÝŠÛW\<{‡f'K>¼±Ý/›;½úqË`§7ši™Ú?]44»zíâ842ò]4Û™,;“lxƒ-¸7¥¹©µGÎÐÒejæÀ’ôèÜ™Ã÷ieÄV:V!díÚî´”ŒÔM%© ø¾(:JÎN?c?Ÿ³õí¾ŸjÖϳqΦ>á;Nûýä ÷ÚtFÇÞ„ß]¥üÁ3Úœ=r@Ün2W³³ØÞ¬Ä/[ꜽ[.(ó¾ô´s¡+ϪhYÝV¤2ØròÑRƱZÇÜÓeOi°Ñ–Ës¶­€ðÿ[YˆÓ=éaÿMgl žÎÎO=Qþ’~€endstream endobj 52 0 obj 3989 endobj 55 0 obj <> stream xœ­[KsÜÆ¾³ü#˜ä*áBÀ žåWÉe:qE%Ç]®Tñî‚"â]`µÀŠTþíé™é™îfwI%¥UX`0Ó¯»¿n|8£ä“I®nƒŸ¯Wgß]½ýÇÕë«©_ò,Š Qà/¯úÛOúþ,ª²\âÕ,ÊÔÅE‹¨’åù"­¢RÿòJ]OD”•U‚7?¨KE”¥îJ¿[©k"Žd^¼Øõ#^©»XßÍN_ÎaÉ,µ—Õ¥*ªÒ*¶ý°ïÇzlûNý”°Ê¤ÄŸ6õî7½FU•;C¯×MÒHd¥}]Û íª1ò‰àu^>ìë]ƒrˆ+wývW/í¦enw§_–E²$7ã ßVD¸5×Ô›ÜVͺݴc£”–Q.Ü1nͲ;ô'½ˆÑ½ˆ$“Ø%‡m½l.¾ŠLœ/Å% U\>ÿTzY0¥œ©l¾à„סešYé÷ÍÐz jHe>UMœ8ÁÔz$‹Ê„©ë‹G½l‰‚»‹µÙÕ£Yõå[éùˆQN ýëâ//¿þês£ïLiűÛb4·À7ý¨MDà@n7ã}mì:Àç¬0É'ÜãàÃüÆ»~½îõy*мs€‡¶{en¹ì×}78MÇU©5-ŒÃ: 3A#UE™¸Ã‚KuYÍû~§-NVQ,DD(n‘;g¢€³D‘ÓÂÊqk)Y“‹w+ÜÛ®> ¾\EiN÷º£‰2€' d¬{í½ë¬ˆ¬B¯ŒÍƒ‡üؽݣi˜Ù\–<Ñæ´6Ê”)C¿+RáÖ½¯ÁëìÒ”C°ƒ‰ŠtÀc0›–sç öÆ¡Yß]¢2ᬼy\6ÛqO$i6×d–1ýZ5080O+88KÜT“ì}ÈÄ dh>ì›nÙ !èO 3¿ú*¦Ó~óuȽÍ=‰o}ÓÅ5Ú†q B¢]èÆJe‘*ëm1ì]×£ oG¡MSwèà)Ȥtú›^ÀáëõÍ m¾"’ýíxJ)(Ìu=â¦à¸©®•Q!)HÂF>ê;KåœÖ³»Ø`BΩCÊü²õÃ2¤Ç]³ìßwíLHËd”­«wôÆ´“˜âÇ›X[Œ$'fI‚l^{öœ>*5æ:ñq¹I1õtnâcÉ`µF”…Ê.è ý¦cªŒÒ”•øÛ/YP#Ž.Ó[mIB¹ÞÝÓÊ΀•8Ü㲑Rs µÞ^½úþõï®õ½ž+QLßÎr u· íd«¿ÎåòÓÛï ÎÀ,\/\*Cf§Žá0Γ²´iÙws•XV ¾Þs–TƒyÂQ×Hx¼Cç•<–PIŤ|ÚQ˜ð­F¼JÒ¨1òD%²ÎÿZ䨲HÒÀÇùã'ÊWϜٳ£Ös,ÛµaÞ ‰c4€É¦™È“ÑP¿‡òŸ(»yÙ”|–¡;—äþÛ]3`Í bK‡mƒ5É8•fnoîÈ‹4®”ur¶éD•RSkð`¨k”Ž¿Äˆ'Éq¸Kå jÒÉ‘À§è0·m|„’,Á :z /P,9¥9@GäoáÚTmð­³4Wt«Å‚__ÿøæJ_†ã‹ãåe×|ÄÜê5—dïæg9í·öâÞB¯€÷«l’Co‡‰ªÏOð4µ•ÃÓ9õìc=‡Äðà c ²Úƒ«¼ `lNÓÍÅ­ÉYaÕŒ“#JœenO~ù–}ô(@ [ˆªÜ§ªz?ö›z\`êY(/à Ú.ëµIÉ”§{ÿ,Í[°c –Ååt–¸ûþÜ5~SiñÒ*Œ•¡¶€ã•ƒEeÆV5Ý ë¿„»s¨j’¬™*ßñ: dl^wŠ£­˜áÖ*DëH&ªT¡ãT±Rºuï YOuá8be¡bfžò:ÿHË©ú® Rï´?ÀÉÝI'ÿH[q¡7*ƒB|g¥÷m½HôVÛ@’Û­ $Û míïÖ¢’âXQþ‘4Dœò%â#µÛñÏâ„$ßu¥)ó f·3§T4¡-è=XyÏð$׋ƒà#Šñi“’„·J«׭ii(‰¶Üwèé šYë÷8Žq|ìlWo¾ÿýÌ«š± M¸O»œ&%Ù:˜`E*äÑîU‰TEÅòDoÿ»}W㫳,Ð9òÈF¨äĔ쫟¦¸`®š/ºVé»$Êññ'õA­z-æ¡ÍãvÝ.ÛÑh&-8Kú9Ì$œ?¨<žF“†±'£€Ç÷íŠpNÌ áAB~«C>&HU ky©Âws#ÁlÇÌØ B5³Íï!±þ¢Vï¯|Ú¢Pã$±j^S¾î@ß~D8e]¾ÆhÕO¾œRYžE>Èš9¡æñ§[„2ÆŽöõ.À€„ÜíYeÙaÖ¬jZíÐáSÖS°–æs0s½‘¥©sM(…E*4éìuÚMúBYJ.•ܬŠ.cÇLã¯û÷=F<–ê=´ë5Š=Ϫ¶ë2£xŒXÀ )@ü¨¾\’"f&<áÏ7Ø&,yëd™˜=w‡aÙ›% 4«Œÿ§ ¤*4j_*—Cr¥Œ{ê•ÔΚMëZÏ©2(câ§ïƒ+ ·e¿AªäV‘Î0Ä,sÇ+#^kϯEàÇé¡}3c“íû®ß —Ÿ{8¬ÒAŸu_ïÀ.ÐCÊb¤!ÅËÍÈ9OÂYuÒt6|äd2®GÇ(¤àÓ$$,œ¬MŽ’?å0§¶Éx•"y:¯Âf-$‘¤´tªY £1’aЙ//"³& äã ¼ÆacZ¶¦T“3Ó¹ ¿ÁzjkŸåæÇµžó´ö€ZÒˆ9ØÆáùNC,róXo¶k#ÐB‘ù}ˆIÀ¦&{EätÐn&þlÁ)T€V"8·ÝˆÂa}Š?Ö·Ë/ÍÁõ¯EÊ[t¿›¤&1e\Ñ«æÎ¼vÒ”ƒ¼VûÙ&Ë×ÔVP÷ e´c ‹ õªŽ ¸°T±¾µNZ_¾µ.ý£wo2ÁñæÞx²¿tgsh–¸?£7ÅÇ:RÕÅv_#¯ç¤:<ˆË¬³v¤[Ι±pãèÐÀ îædˆ±ää3¸Pæ¾ÎbŸ¢Wd“v–ͽ…ë‡ý¥PN°‚Ù ?㸅œqüÞ[Tór7øPŸá]C“>ɽ¬ —ª¿äX0c²9ë(üòæŸú>Õ²uÇ|õöæ;¥ä5rÀ(Á»bÎ…ŒvRÂ+‡˜evŒ…“ÈÃbð S7Ñc’¨ žˆ¥—D]£‹(cqe†|Ÿ3 ¦ÊÙ(Â,#¿ÿô½NÁ[¡fhí –YÊ*(»0“ÍæódØHY'¥^=JбÃXïŒÖ°r*Ì¿—Rº]õ—®}ÄîËq}?`' >³@.ĈÍBºn…^¤Î±ví" ñ‚ã‹u`âä d§;¼T4\)y€ãâ/Ë9ìh©ZÆ\…az!˜+X5Î#¯¬T²Å"¯3AÖùz¹v/×=Ô€/oÛþgÎ0 ¨*P©§¼Q„Y¯bÖSN”dÅç£p$.áü?c}˜ŽLg ÃÅ„ÍOéTßÜ„œ=ܪö¤á¸D1/e<²ÛÕ•>³~Jã,¤ºpV&ÓpÆÝ‹…³*0ã"g±0cŽxD°¶“S»Äe;ú3iyä¿k.Âe6©QQ2ù“%ãÍŸš»(ø‡ÁþÉiƒbÁžÕPlÇÎ0ä©V¤›èËNôy˜±xøÄ/ ú@ã)üÇè\Ü%9îËQN„!’ü´^ŸAÛJ‘GæsRÅBÏ}° #|–ãTò‚ä@°PÝ@ªÅü`ÁF‰ëù½Ï2=þY˜¬çÕܦ€,$Or÷C0eò­áæ&ŒŽ†ö·wÙX'ÇacULõâqŒ–&š›ŒÇyUÛÕáY¾#r[àèFš?q0(x#È‹ÈÝV¨|6–øä:žßÀÎ׆fRæâp˜×ee_)YeØ7x3ÿ¬ÊàŠ*bž `*jPµbÉPö©“E»ûÔB(¼Ùãø,¼D “ŽLåëÓ$¾àDÎgq‹’ÃÀÙtV0½Âä4W–=]¿[lÛŠÞD„š)n‘vÏ¢”…@;AÍ&0Cäù1D’Ï岩!ùõ–PÌ ÙTú î>Os”P>§„4¶Å|8;d*‰”nÊÇsB†F)ç‘ÔcÕ,?ÈR:û1sB*> stream xœµYMsÛ8½{÷G¨rrj- ðsròd¼5®Éf2Ž·rÑ…–`‹ŠTHjoÍßÐ@7-Z’«vËWA Øè~ýúuóÛ, ¢Y¨ÿðÿrsöíìÛ,2kîßr3ûéö쇛HÂJP„E4»½?³D³"œeR…˜ÝnÎÎ߯Ëí º··œÅ"ˆC™Â¦ÛÕÙyô£^‹d Š\àÚu£×Š -ò¨Àµ¡kÍÆ8qæ6®vË¡jÍn§A&bü!ÓKóX¤Ì¢Ù<.‚Üž²Vú÷þ”Ÿ.ÍÉI'Þ„÷¿~þpùù—«Ÿ?éß2x> )ÛN­ªe9¨@ÿ–èçüo‹ó_¬Y ÓLâê£9$Hâ"Âõ§Ùvdþª»ÀG³WWHo@§–íCSýGõÆ8Á ¿+—xXA/øÚ×e¿V«¹q™ÌáíE:›CDBë³Fõæ,!ƒ,Jݕڦ~2«q$l_GÞZóÎ8ˆ…¿üºìÊ% ÁçA(¢ºo;ô óãº2‡ˆ(ˆeêb¼F²ƒ«Á¬Á6SÕãZJ&5j —*»'¾D)E^6¨~[.•‰F’kcàËN™ j\ÅIâ ¹V½êÍn™aì±}×Y‡ÜÙýÕȼÝF5ØÇacAάš¿·8†[JÈ2aý¼ÅKå ƒO9´ÚQb<w9Š»ÝðVgÌŸd_áðµÙ+yöÞ•³BÀû¼áCU¯¬÷ )‹£¾íÚÁ®K˜eëªwyË@&ÞòMÙ}µDA'΅˶n·±3§lVˆzôôjS™‚Å[‹qˆRƒ7Sô¦M1 ¥Ô#©®…GEt±N•+}ù€>VƒÁ¢H¸n®.¾1'3剷ñˇëWf9 ºÒºì!™Þ´ûéÔo÷Y–{6YV6:Ú„ÜŸ©ý]5æeAæFY@ä$@¬Ë¦ê7ïд4§ ë¥T{'t'·öÆðbî­=3 ãP&œ[&v€"çDCb:`q¾Rý²«Œá2ƒœò€R+¬"ÀÑþýü¶ºELä!±¸ÅÏ8@ èÊ<ñÇ®ð^œ»UÕé Ì™U(ÒÔ˜¹€„†Tç˜m'Õ•5<Ñ”Ce<'AFuÁX™X§i‡’¥Þž¡Å¢½TͲޭº4>€Õ=V½B6©g󕪫Må0˜DAHÅèXY€wäþ ªÁpHé bEU‡]©’ŒG{̘4ñ1Ÿº¡‚¶ösYdAžê`iEIÂ<øÐµ»-ÒË»ö­-¤áñëáóëJ­Üö£Y‘²ÂGºP9».ëšÒþÔò<2l*U‹,ˆºkz §¡7yꕲtt%¤^ dw#ʾ”²ošl¢K–þ K± ¡h¤+§Õ½­Ž—/bk5!p&n†&dAJ7«Õà“²¤Œs×µ mJÀ[•C‰¯Ê&‹ +A¾ØŒöêbƒ8L¨0}q•"÷Öþvcö pé+TÅàÅüÁ³ð„D¤à:Äs¯:s¸Œ ò3û´Oi Q”jÏ3ŽÞÕ¾âAÜbÜý¸WhsBŽôባ©ð0$øðH®ÙXxØ^žןoKf‘‡ÃâÜ ^è„?{|‘”(õ¾k7ûb£´9˜³¼üD©êâwyóù ƒf¬,íSáuWÊJþ¿?~B¥—QcãN„Ú9%—¨$8A¡“±…v |Ò€wºTÈ'@::vå$ƒÆ}uSn·¨‚¥P~ä  iñû¶®–ÕP?½³eÏ—çßÅ6o÷D²#ˈ’y‰‡-W…݋罛'§ÖXÓíÉ(eQ[`wÇ…¼52]QïZ†<<½ÑñÁÁF\›QœÐWÁ%£j„Þâ㺥gmêË’«Œ„ØÁ RÔÖ€w’1jjw&ý¡Ãˆ¨ï±—"NH½@ ,ãA‹¦Éó^J—£=ý¡å!å€âÐŒ„„Ú8Û2*¬‹Â›w$‰ou] ÿ¤xŽH(K ±›™>"w<¡ˆEè¶AKhâÌDÌ”ñâ—v½Z½C÷BϤöãëGÀUD Çt¸–ôé°.ÇŽDû{©ld×à«WÂ;ú—®5–ìülÑ:ž‰éúiõð¸³]úÉ ;xPß'n5YÖ@ç‰Àÿ§ëƒØnzUÛÞXrƒÂ.JjÚ1 hê’êý(¨ €:”Ãi uHå+uqz²ôå'¦ªZ±/½à¾¤ôïÛÎŽ"ÁvÏN¦cxÂáï.)'G™MTü­È*DÅ4eSéÆ÷±Ñhë g“½ºb .e6 ñ²j°ÖÉŒûU£ ‹-SÔ~˜˜$êÛP½"¢šNAYë1+G¨»fó"vô!½±¡²ê¯Íè“é5÷ð‹zÍ5%lžö, >46î!E<ø´EVäwTï oÐË{rLL%®´ñÛçñH¾ç°8y†ðÑÜ…w~ºZûhöíF="GkMCܰªþ¦P}€¦aÍ"È·s99ÿË÷ÁÈçò»`Lmf+'•"o÷¤ÞݶGÁšriËäÿ䬪RÌez>Ä2äÅ’g~€€³Òâ†*lDÑí‹y;9×ßtF¾òæñ)CLÁÕÙkìÓ“GŒ)¯z̦åT5öÙHµ¬íW­ÛhªûD¥ÞÃß«T.—ƒ«¾¬?Ô4åÓdy¬G,2^m²¯@nhBm÷úæ5É:šA4m·q TÏ<·¸¥[§!F½ï ¸º7R„ø‡ñs´ðâf‹ÌÚ¡¶ÊÉ1¤5Xr,˜’šVmSNyÚ/§íΡ€"^úAûôt·«j× Å:fÔ*؈G,âÚ‡mÏ3OÐB?ߣW ¸B':'¾vçú͘D€ïŸ%•PÈ.l $°)x?ÍdS‹—%ï & ‡+ÉѸÆ]`=Œ‹ÃJnŸâlH¡l²’5Ø]ðÞ0~ ö-x׳ÙÔIâ\çÃ>SýÓú"bïòSæ2õ½Ülkû…ê‡9ú¬=¹NdÉFðŸn®?Þb}D17è@¡§.š‹s[ÊÇ«o‹Åùþ²@o%¡÷à› 6™%n“4ÞÓ¾µíóïòóÔm†@à=R‡Ó@hÛaßPðL<ŽWÆj\r )^wË{îÓ_#¢¢`î{ŸþuùëÕ¾§ß¼ùkqþ®³ù»xÉ^¾“ú®¾2:Â,yž•®NÇQ«G ì]UÞÕîC !küº 'ÛdmSn¦4›èVó…ÉaF3÷Ùk©Bq *̆‚ÒçWå‹ßÓ êÆù€ V’8žRè»z…ÜÇèø¾¬ÀØ(Ë’4HÀœ›³2÷?˜9OÒ!™Ñ#³3IxâŒß&‰žÅ±9€ê–¸3£û®ËæA­ðóóÕíì÷3ý÷_NZt·endstream endobj 60 0 obj 2624 endobj 63 0 obj <> stream xœ5‹± Ã0 Dw}…ÆtQ­ÛÕ0 Z:§t(xðÿ/‰R—Þ»kˆ1xzo4ä“ýk«8\W–ƒe´üŒ0‹Žh†Ûž œ|vh{Ã0•õQæòr“"…<ænæå¾œûH“t):,†Oðì?"wendstream endobj 64 0 obj 123 endobj 67 0 obj <> stream xœíXKoÛF¾ ý<Æ€¹Ù÷£Ç:.ÀHS[E.¾¨2e«°Ä˜¢êæßwö½)Eu-|0<Üýf¾ofýRaD*lÂïåfö2{©ˆ³Å_ËMõÓ|öþ–0° ƒ ©æ«™ß@*ƒ+Å2´šofﮞ_û¦»˜ÿ1ãqÌ$,š?ÌÞÑ­0D¦ÁöaÑ/¬•*„•dÁz×wûe¿ïçD#¦‰Ÿ>wëͺ_ÿi¿0ƒ˜¡*|ivΑHš¸ÚXÓû[Ê+¢%‚Û°kN%¢‚T57HûÐ\dàqWHQ¥¦"Ó.ÅDd #IR>2@OV„#Æ%uaPʑĬª…DðÉň»„FRâxæU»Ý¹cÛ.8R¤1äÁ; Ëk.ñŽ^Ý…°½ nÚîÁïfÃ$jÄ­£Ú‚âÑøòË퇓<ì.:Æ•¢4;øjIÁ)$ª¶±yO÷É×xSôÅôØ×x5›B÷ÙÁ•j"਱R"i÷ý×}¿ e£uªJ—dƒ óåÀSHðCìÀÇ*Öîªí6³3‰ ¬X¿[“@*oÿæÏ`t\´l·ËEßlýzûh?Kƒ„ÒqÇÚ‡J¢XEZ¬·ö hº€A\C 0 ·s˟׻~*ãV]¦ûæãÝ|œîþ s9âa’nçì!á°AØÒ±œùŽÎ†©ú¾3°6´³ñú)‡`(5GRn½àÔÃò”òˆ°‘¤C¯OíÎ1@¥4ÝfÓl^Iž’ã².—&·ñ|éÁ¹j^;ìA4O¤û2˜ )þ×§õÒ@Ï {ò·ÒÅ­–‹­[go2P§fHð; ¬$±e\î¼i[wH¡H¡<,úý&TÀ ·û K©ì¨uÑÌ—±ùpæšCqI+ÖYUÚ.7’`í¢8»ùv1MH(³åVÐe×D°¨HÑC—͉-N4º»þ4¿þtuíØO ©3A%l9·¼»ÅSdà O6€«)¡ÁwžÚéYÄ<´Gb„MĬ‰RÐuÄÁù!ÃZ§2üW'Ÿ' ÐW#Ç»?„!’$À0% É·K‚,I”ã@f>0’½>KÂz¸)4Ɉ…PAØqÕûª¦3“QlÛ(‹:Çk‘ñAPa‹@&*»µÖkQ±Qîhvð=´ø-Ð…L¨©˜ÉU8‹g²fÅ:Kë@E‹”GÈ L—l²B¸ È¬èŒ Ó¥l;t¦U‡†´á¥ê¬Àó9MúçÏ¿kÒãv›;ÿ%0ÂhGº$ Feõ]R™D‰æe¿xv±™²KömPi55ÖÈœ¡]ÃÐC¨i¡ºõàWC⺠µGó“¡Ý6A½yöÜüÕû®`Q{ Y/Yiö Ú”Æ: ¸4FÊæ20­¸Ø¢ÈèÜ¿‚[(ux ðr¦š ìq½ÝBæ]•q‹Nô«Ðb嘃nzeS¨2P¢® ì‚_^ôÜñÄ19:{©€û”…º­€'œd§MØ2D² sãu¼˜½÷©dMž· LÍp2Úਢ)@™ÕÏMß·Š»7VPªáÛháч!®PÆHsà3´/v>ÎIÖù·&¼"•©¶ž=°ö¾$ÃíC3ÅM=‹×øgÂà/ÁÏ·#Z{pV¾7Δ²›ÿ¥ì?'e!CÍöÁU> stream xœÍYÛnÉ}ò|‹ ˆ½}éN^bg™Àˆ½ÚÈL¤‡9’&/ž¡Ö«ù÷Tßk8CŠ^A ;V:uªæÓ„6¡ö/ü_¬Î>}š07ÿ-V“·ó³ï.™€b¨a“ùÝ™_À&†NJ!ˆá“ùê죯çÿ<¬ Úhø}¾<{õvvù—ÙûÙ?ì/…"´äeøåýÅŸ/Ü|EŒ*DUDÙÁï.K6a‚P8Ñ8•¬„cÊÉT¢Ý̪m+;•„RÅÂúg¿Zô®ËIi¤™La*÷‹ß\^¾qw’ðBɰºkþUÛÑižÂ¸ûé:¯‘”P&ÕÞ®I!ЏӦmî›õõk¾õ¦š©àaS¦ˆ(üü§Ýöi×…í¹„a¿Qµ¶c0Q*ÍãXx:3„æ#ÝÓ )ÁfqñænÌŒ“Âh¶wÿý[‚±tÞ|U¯Ü#a©,£³nW‰, ^­[÷ð—e¼ïõ+·Î5"=â©Û¹AMT‘fŽíh‡4)eªüKÚnºf×üìn­WÉaaC¦6ëpˆÐ,"wWß×íõëó€S$—ÔÕÂÝ\’‚¦›?¸!ˆ%mXÏú}k~hÜbΈÌÖ}ðRž®·¯Ÿ=$ Â,ã±éÂe™6XËæ±zµuvæ»3`…sC£Y›nG‚…N!ñ&†ƒ :¶þKR2û}®nðàa00äù®~¬»zBGf†ùÜìœa9Ø.3Ì»ùìƒó)°K£ÕÚmÀÿèVnO"yréCµ¾÷G‰’ˆ2a U”iÓ³¹=x–%SÊü¡ža<ù›¶‹þâ¿&üœ‘,Z€!if?ì­òÑGh¥ì€=FŠ|Ê×ÜÐù^Ù'<­’u¾ó±ÍxŽ0æ¡©š1”ŸÖu×§‘¼æA7 GE4²ž#ò1‚Úú3îÕ¬¿ìÙ*¿@}†¡=š¾öOa4?Å_Ò!D <Ù‚‰ê—8̧e"Ñm#{èl¸{O–°#Ä`ô`½>|\'Ò[ÛTy±áœ´¨º: Ř*`S=Œ`¤<õ ‘Ö»e¢d!ÒX>Zç'M±6ñDK>T]˜'s2Ø=T1ˆe¦ó„„ã8—GžÎía¿ñ L5òÖ²þÅs¤Vy螬™‡X.3>Ÿ·Í"¦ T£¥ÒaæMdÀ¸'IH¼,3oº1JY™ˆhÖ 9æµ,ÇksP‹ž‡—ï¿{hÖ÷Ä_Ây,=à@:ë‚(C"+ÂBæ›mÛ&&*xX\²Oÿ·Co#…#ôÇËw?8°*MY7¦#†ÅÑ]ÛÔëewAaµ#"€¼†Ó‘Īõ ‰Uè¨ÁÂi×ÛCžÍžYÁ0†ÂÕ¬»f鎖v’SO­G/ ˆ´hÛ¶ZÔÝïÝ|+Û“ú8:wn' n7É·I*Ó|¥Þ©1aJiqïüï*×mÀ›ðáÿùKÀPºL *@B…#¤“þÒûícC€g]Yápsixzþ¶º¯Ch!Nd<{!nqÑv‰ß¸ȯ8°±8¸±BX¹r8÷}–ãÀ¶f¸-ñ6Ü+üH2eèà-}XFv–ºŒGÖ~Sðž²sPõ÷áû\ËA„feok!«ƒ]è2¸pzÆ5èc€dû~R™R¶ífQ/ŸÚÚóÍ”ŠÂàмÆGöW>òh ɬ~†$„pÔ/!E~U(—°¿VA+ Åõ¸k¦ËfUC˜nÖÕ£›Ûäˆ<’!h´IH"þ§!æºô©nÂ’‰tœÜ˜Â“>­tŸÖp~J–ÏvÄ ‹Ü•Ùg¹ÂàzïxL‹¼óÃÆ2¶‘•ÛKÕI–ô±Q†šH­m/È‚Œ½k7+ QÏâ‡+PAsdÑ›áXÂ&ÏcW|8OÞøè°j®Ä8$f¥‰³¼MÌ%OºÛD „’=í;HÎÀñÆÎAÉùý»óùEBV|m9zêq³·ª´ýÛ䪸î Z´/æWJ‡-Z~Œúy'…µE½°îªUÌ&‚¥S÷™öºY±ÒBM–¼)j:àdË2ˆ­ÁeC1ª yÎO†¼@žRÔtŠ×â¸~¹ë—G:Æ›y*aµï¼'Ê5v¶ \A÷ì2 ‡û>‘eê»M„㉟)æÜû±`w…®ýº OîPG IJ\ÇŽg§sÝð£À!ÇÛ@È_uÌÉió@(¼”MYÜ”x⤨%žuê !Õ«ØÉ ÞA'gH„mÖcïôhÑy#-ÁÑ ¾QWnð€o)mB‰Š›Àm}_µËØV¶‰”¦§ Èa‹¼W^¸ÀoÑ'dg—^µ¥ïÃåܹð)ÊdŠ1@o›u=ư+¥ÀTñÇ‹oßý0s¦èÕ´®Æbðçï–nœÇO¯t‡I´$ë'ÍT%ôz~ñdÏûìµ"EÔp‘tíÒg«^»µO{en¡ü¯”¿h\\~B_j”…¢åàžÅ¾åÈP‘¾»>à+›31ǪûoÓRÄùúñoó ­"à=6Hϸ BÏ™Úp³¿ /Óãí©Ÿ‚À(sY6¼‰_K‹¬Æ@f˜zÆúUö9¡«$ðWñ#›‚n‹85·¾,ÑÄ$Ö £Á L_£^Îþ>»ü8lHi"rÿšPÕq ƒëÏÿçtŽ8ôÎ nDÙ¦/Z(+Ø&e®z#H`¹a¨”XÖ­‹ Ù|ò×3û÷_ËzC#endstream endobj 75 0 obj 2350 endobj 78 0 obj <> stream xœÅXÛn7}7úB_š³¼só–‹h.U …“‡µ´Ž·•´Êj•Ôßá«¥e9(PøÁÅ%gÎÌ93ï“áI¡ÿÜÿùêäëÉ× 6kþß|5y>;yòSXAeQâÉìúÄ~€'e1‘”¢’Lf«“G/nªM_wg0‚XAlš-N‘§z SDJEÜÚ˪¯ô*‘¨‚ºÕ‹¾ÛÍû]W›C¢ +÷Ó‡®Y5}óMÿBKDK"Ý/õÖÄÁéwc¬×ž|”x÷`¸¶{ÊH$Å“)+‘2¿ÔëííÊn¦'‰‚-S"±;_½»øó­1¬@fÜ]õéѲ¹êªîVÿÄ1â8X¶éÚy½w>=¶7 aœâ‚# »§X ÆÌ'í®ßìú­óR©¢A«D|ñNîÖÍ׊rÄx°è»^’ˆ³»•¶[˜”éCPWs³È(¤À½F‘xM߬Ì%„!Y†P5ý/ÆJ¬NV×zMÈ1r&dà¨ÒQpöüm>…`Èõ¹ó ´~qvc¯&©áYÿlP$q0¦²y'’è`{mÖ¢4\Ýßø*ÞrÝv+›XHòpæ+|j šßúŠøEM¯û9rQ™2AlIIH!Y„e"æ…»GÈ!ó©—õ¼o»m6Áp†–:ÁÁ@›·?uÛþ˜ü>óñbfîcˆÎ6ÍúK6{Ÿ…Þ—docÁÅÀ…÷À-‘œf Yn.+ì!nyë¾/eø¾r©‚Uw6Ncøã2¥âM(8ƒÇŒ6aˆ‘p×MÕUs/t ä+ðÝå|O»ŸuÀd Ä#qàÍõÀ“@‚Œð,D¸|Ùl{ß”ñB@þè¤REl¢Ò6‘ Y³ªWnQ°ÀÄ+½©#ÊòT°—à@Î@ØÄ‡ìÕÚ ä®¡ŠïaX †3„glŒ¡¦!ÙǰÐAõ[«µSNÅãZ×U.0Púü×·6}d"~§c¿‡s’Á˜EàÚ®ùb…–j«‚î·I¶Œ=MšJSS¡D‚T6ˆ+pýMÕ»b-UÌ©C¡ˆò:R¿øæÝ˳?¼s,ðþÜ‘ôñ{¡rIÅñ'•ˆ ”VqR%¦ßÕOQV ×ÖPÐU‰XÔßíÑ|1n0t^g˜S¤ô6#À´,3šGÅ~Á!ÅÞÉà2d·6»¹.Ä!®U³v…€j×2RŠ£ÅZ"ލ«XîîBÀUZz`´©nGÑV¹²„32J SŠ2•Êð¦j…)©ÜW ŽxÒít]Û9Ná„S׎„ -¥JHèÎÀGºµ•EŒèƒ9QұЊœÐ&MYŠe”¼XEU €(•õjã+­:(•Èu“,Zþ)ô„"ýø›š~[/¯Ýv.§V•KºÃpæ³&‰¤A¾ÏìÑ<µe'´:nÚ››Æp‚` ¤?Ïuæ%`á-žWÛÚ]L#]Ì – íÞ¸–brs€#Ô8•ô Ëmë¬(£è:;ó kùìÆÞ4%æín¹p±ƒ‘ˆÝ >I–¾wMß×¶êF?ê]Vt§XIEÚµöÆO,Ód¸n¼lÅø©Ïò)‡ýÜ ož£Ýá7«jãH©T åÏæ†Cà‚häÓøÕëE¶À•zteÍÀz‚Œ´Í&T§MIñ­YÔ> —, vŒ4“ét“ê*m]ôx²9¤Z›»…•'¢÷ÆA¤×{—¶ç’Œb_×~ÖM„}·qnfµ-i5h쫾±%º{çXk@i˜ê×Úe6Ët$âxøöÙ‡\Ô áHý4wŽ”k8]œåŽ‚‘E6' ¦gcåg ºß—ƒ$>ÿñìÙ‹×¹[ QIlÿQž^ YzÏ=ôê»j½Ý´V¾4“X€ôéªê»æCÉts”À ˜ƒ³´$ÝnÆL t’y 9Ÿñtž¹l34½üüÙ’Q˜‰)eû&£ÉÕñN-X"“ñônt®®·c#SÈD@WÚP‹Ú·D$â²îó©#3ÃÆ¦úbk×rê-‘ÒÕUIêÒ1Íd}èââÌž *|ð¹2‘“ËsKQÍrŸú:ŸùX¿ãø˜¼xm/‡kT|³íñ0O¾ƒòµÝí¾~TÕ›~oIµ?yHÛÍïǾ·$m@:{à´gmò`Aƒ!äñï-ùÞ’\uà½Å¼?÷ÞòŸá™o!# A-ÆÊUÀ°H><ðÌ¬Äøá¡< E#b@[¤+[J hHŽ}‡|þû,ŒÃçô!?¦þLjÝóó±$ßC*ˆŸ4©(IHeE„à¹iQ(ã#¹÷ˆ9d à‹„¾ ɽÀ÷œ9î†îðÅàžåÒ‰¯Še±ÃL^!³(å_ï¡9”·Ñ³ê`Î\EÓ€ K,hžIëuxT÷µ€É(™Œ#ÙiÜþnƒ¬%Êp'­ï8™…ˇ<ˤǺ qh¢ì¼XE&hÿï‹ñl6ùíDÿý ´öendstream endobj 79 0 obj 1949 endobj 82 0 obj <> stream xœµY[oÛÆ~7ú#„ó”Ö–{%·}JR¥5š =¶ÎЦŒD×lu EÙÍ¿ïì}(®d;Eá«ÕÎÌ7·oFŸ&¡“Âüùÿ‹õŧ‹OjÏ¿Åzòj~ñÍ5åpBt¡éd~{á¾@'º˜”œÍ&óõŠʾžÿqÁ©"•®àóùòâÅ«ÙõO³·³_Ì'J’¢d¥ÿäíûÞÛû’h©¸?•DšÃo®K:¡œ Ñœ Z‚˜r2šTöæÇCÿU·ï÷î:èÇ*¸4eŠ0w÷Õÿæo®®oæ7æ², 4(¸j÷½9†ã)ˆeî[oì}ÆHU•üèþ1$S®ˆ2צ`¿TöîöÐïNC®‰\ùGjsTÅtq¬‡±3Á±Ønì¡4Ƈþn7íæwû¬ÂÏöw½]ÎJ<àm·(HÁ£¶·ö6”+êÏšzaQExgŽ4‘•.‚¨u³öØ(ï}´2ˆPº2šÎË`´bgä&Õ…ˆª·€ÏŠ1XI‰ "^:¯¤ðÇW?JxŸm-øà&%£øzã-,y2»ë¶VÓ©(*BŠ‚öÖ?!Óuÿ%”Çg?;´Ð…ü28¡Is¤@Ò<€¤!®3 E4b<teŒ'%¹|½sßç¤âJ`sÀêBé¨RP³ÒÇH@Ú&Õ뮫½žÅуzeRÚYY¤4øðbîŒd%‹¤wÞȶß7+ äºæ"Fgí]|ìgÐØáÁÆ%f¥’’gàqÖ¡—æ¨$‚EÀÚ )PÅÔÃ]kÓŒ#Ò›w Žðæ¢Þ7^8¥”,*Å+6¾¢*-äÐåÅÀk«ýÖË×éÙG-~ûðõ8«çwNƒ»°ÃjéG‹è¸\8è:zèÚ¾o,ˆ>)RýÌV}(øá`8*ÁýÖU Ð9nÛÐ:†ÝàÛØJašGrY‚W@ ÑïºÞ›Ä‚ˆs(ƒ‡„°2 ×§šÍ2Û[LÎY«Tì}>Á*T2ŽÞu[ŸŸ"U ûvÙŸ\bª1Š IŠ2t×µë¶oï½WPG÷”è²Ë•ÞÜvKWð˜¹Å{OYñÁ¤ýΛT¦êÒ8ÝÁvª¢í‡7SåZ Ê’¶oººo][P ªè§TpžÎ¶«l¤'Dß|÷òçœ× èXý2÷ŽôTx‡ÜÌrOq;†ÜeJž‘uœ£Œ€§qPŠã7ï¯g/_ÿ˜“Í™°Åyʤ;s)UPûÑM“éC¿‚ú¿]ú¨àRög\wMœ?%Pm¥AØ9Î’2íWnÎä¦èFãîÜ:‚ñþ”áUZšžÑlèšœN‹®©ûf™ïúTPSsð<±^>Ú÷ý8ñîûÐú‡{ ë‡@´†+ cÉgÏ P­ú!ð±«;û‘¤Htê®Û.šå¡kÜ¢h¼ÏÐÀ¬gâJ÷aèÅqÕâ%R•xf– ¼ïô¡ gTcAZ{[¦êÄô8¬úvÙ®›Í¾ÝnêUïrÀQ#t™‰¾`)¹›Ué©>BÒÚ$±Ÿ}c¥éh =ÎOŠV‡Ñx4n¢ŒˆÛaí¯¡öà»Ñ.¿ˆ³¿Ö”ƒÄÃáu O™Â-ôá ú[¢šß ü·ÿ̶˜ ä8~¾zýÓ˜GР¹&²té’>=Ò!D…’'"=3¿'ŸJïv½rB1Q }Üîý®R%ÅÖ³¢¥ Ã7[ìNLþ‘åŒÜɰJ³ªM“K׬íK¥&÷®E!3³bj~Ÿa’b_ÏÞ½ÿÿl\é"U9Èõ( þ‰ëUE˜¸¿Èõ‹mØi¢ñ6Ó>œF? ¥§ÏŒƒ©Í?´ŽU 7øÍ½oO4Í®ÃÃQÐ/†Q 5Ÿ®œÑómÖ¶ÁŽø4óžÒ DL,¹÷Þ•>Žè«ïº³ùä¿æïo·EÀendstream endobj 83 0 obj 2102 endobj 86 0 obj <> stream xœíYMÛF½ü#tL«Ãþ`7{}J2“ÀÀÚIÆ2ö’ G¢GÜ•H IÅ™¿ÕßE‘š‘‚\Xø0F«É®ª~õêUñi‘ºÈÌ?ÿw½¿yºyZP»þ¬÷‹V7ßÝS+Dgš.V_nÜt¡³…âœh¶Xío¾ùq[†ªûvõïÁˆÈ¸„M«ÍÍ7ìfrÂtÁüÚm9”f•)’)Éýê§¡;®‡cWÙ—„´ð?ýÚÕûz¨ÿ0¿pM¸fÊÿRõöE98¢ÂnÊÍÚw÷Š.àÜ 7v/ˈât±švcWí7ǃÛÌGN²¶,™$Ìí¼¿ûpûùWkXF2*rÔ®îk@A$—¯þë]Ù=›ŸrŠí=tíºÚ€“¿ëÎwI!¤…‹%͉–µµÇápz¼LÁµQÔDÁùuk23Bk ch¡©_j¿Ìùmâ•Ç{ ÞZ9¾·¯õ°u—@rcÝÕërp·©ˆJ·¹¯öv?#RDÌ’$Bê,Þmg]¦ \VÁ&¸³Ö> ˆJ·ÈÈ2æ²ýÓb÷eÏøô{ë5¥DÒè¥u¢Îbl¾šEr‘¢åö´ëTâ›ö­/ÄGÓŸ×ÜÕ/¹ë® °ËÀÀ®¹ ÉakÏ¢ÉeÜ^7H]ä!<¥³ ^­ÓÞêéXîÞZç)$FÄôì‹»úqëWE û°oB¸G<ÎMa´ ñ­m_yËx²ìZ,H¢·½Çu¡Ñ93Ö·[„,ââ°-$‘Ð ø*ë&äš(b®Õw*W :³‡Ùl%³ĵ$þo¨EØÝOÇv¨6—pÐoŸYÝÝN9hØÖÍ£½A˜ÌÏ‘PN¯ !MrÍ= Rüˆø½v‹€ZŽa %“©õ—G"/hX³DfxçO^-¬®·Á.OØŒl%Ol5c„¹˜r¨ÛÆ—#%•Ý|žË„œCWYêe¯VͦڸPÇèkC‘¨(¦BÛm<¸¨\€Ï\Hæ €Rk±„ld]°Ê“Œ/å‚(UBðáî¶.Í&¸•´б4wpì«¡\ö¾†ÜOw«÷«»69$0Ê©MõçºeוÏ~qÅåîXÍNdô¤j®Ûý¾l\¬rAt*Â÷ÕaW®tƒPyö =)‹šPL²ÞêI]4(‰æ:œÁ±TQ/§;¯šP5>S±)ËÆÈšÆ·Šiä„%¨69ÛT_g¯˜a">{3."ßÄá[C•¸kzà!w”°”ÓÕ°^ðùÒ—HôÇÝà©PÐ:1_MT¼gY*^ÏΩ“2– JÓþ0™[×Ýú¸+»·Þp¤njR‘·³!ý•½f`LDWûÒƒˆò„ÃgœÃ•£‰–<épt)A÷^Èu„‡W<]=ÂÛ‹‘U'× ¸)âÖŽ]XE5ÔßIMíŒ`: õqÎ×aaC¨ï7WÚ‡[Di¹"4ÕK!€ð“#ZCl‘ð·ÕoåŠ …ë÷ˆ 9QgÉ0ã§d8Õ• 6BËYãü"c,FgmÍ%" r£/¯EEÚøà:•´üóœÐTbÀ—xjHž ã¥"=¡tÆ1tEv•ŠìR*}Öp ‚ò‡ JÖoºàÉ˰&€êŸÞßZMa=ß螯ÈZL/ƒàÛ²yô丿…1€-xqãúâ.ë/áR\Ð KÜ= ­¯ÛhÚqކOÏsð58XB•1Šö¿œ¼Ô ÷ßß|ÿñg;ŽÉ3hXb”_›®@.R ¾†F M†4åÞíçi?”Ýà¥FƦ41?UáKú÷0wƒuë«<"¿IÚ9NGb×KSu¹uP#ýýÇŸïî½ó¨‹ýåó'’ ÎYm«º Ë,V£cÎRl\€óQ|všÆÌJ–4MÛ,«?­·¼À:¨ê\sêçÑŠ(T>L@¤ŠLÚÙ&Ä:£†ÄÊåt,¨M® aA‹'áé]H°…EºX—ÍTJîªrãs”æ§)c“-¼9È+‘j’&(}öVy-y‘<µñe´õÚ{ŠÆÛD™F?õnç7¢×c5ھ݇iJ<ôÏö±õ«T£Þ¥ \¦7óË`„5@ž£hd…÷½ij7aã 4DÍ®M/kí¡çSަÆ÷ØxÔ1Ó¶Zû¡Äå3U727 Jím4W¢è<¤N‘„ÎÆ·£K‘i3´Âi‘.Ö¦’Q q^%¥- [ŸöÌŒëµ]ùXù,ÏR¨"I_xŒdOé±§1!ÌÑ»ïBÜŒ!V¨ÖKyD¦›úMµyçÅ”@LÕŒ½hTÛ÷~+Rà>]-Zrkš„"+N'Ú> stream xœíY[oÛF~7ú#ôØÑ”s#g¶‹´Ñf‹fc×VP,¶} %Úb#‰ IÅõ¿ß3×3iÅíf_ŠÂ†s9—ï|ç›Ñ‡YFè,3þÿjwñáâÌڱðoµ›}»¼øúšr!:Ót¶¼»p èLg³‚s¢Ùl¹»ø’Н–¿^pš¥|_®/¾üvqýÃâÍâßæK.IV°ÂysùúÒΗDËœûQI¤üúº 3ÊI'šç‚pL1› M”Iºª¯ûjç¦ó}LÁ¤9Ë ósoËï—‹™¹’I£õ~]ýfÍ„åRøá²mËÇñðÇr{¬ÜÀÌ)„A 1›Sp'Ϩ¾jv»r¿&öØœ:ûݦÜßWù ÉÏý‡~SM9D5)ò‚}jø]ˆhm¿1s¨ WaéÎŒ1’‹"ýÖf‡ˆ\gÁÀªµk9Ée\ÛÜMšÆ‰ ŠžîÔ4ˆUhZãMãE\:eÅÔšpSžLÉ0/Ì”‚Jg!ÔÛú½5‚žÇPØ­4‘É<»ƒT„ñ˜ÅÛcoœ€l&!ù€X‡¸‡ºß4î³ÈˆÀ¯ìL¿7•ƒ=`ç`Çûzo%Õ±:î—–Üd/¤eU·«ã¶lkw#ÂûöèN3n‡!‹F‹Wž¼Ú?9×µˆ–½¼~ûýÛ×óU£Ð‰«¶ÞÕ}ýÑVäí0m‸yØ4+Û°˜öåÎÍS$fªëËÖzåËqØÔŽB¨ánÎæ‡)0×oB0×n­b:S½ÖNªˆÀø¾rÐÆy/ß¾^\{çu&¥¾|wc£Ë ZiçZ󩤎º¾=®ú£«iý7‹1òå¥B#òp‡ýxTj­S‚¼©ΙŠÎþÇcú‹¨Ζ‘jå}å9‹c†Á¾I‰C!Þš‹T·ŽÝæ9úæêÝÍ?íAŠäZ`ÒÕ{ò¶Þ BbdãûËPßü Mñ¶-]J†BéÐ6«j Áüù«i¤¤©ƒ4^ùcT^ÜìåzÝy{5æií#²‚ŸZ>,e×ȵOë`?$aP®aùû1áö›²÷™Ó1¯Ÿ8ç£#uФ„ Ð[Ò-"oR¬òÁ†l¼a PÞnC•K«<íÀŠ :°{&M{OjÇù5J%9~ðuš@Ox#ã^»Ü¸3 8$º?¦SÝÎ3N=v}àz$ßMé3” ÁŸÂYä…KÕÀØèmíà¢Ñe7[íº0Tƒú¾ñ½!ÕÇSªÂërëó˜´ü)(L‚«Mºµ4·.FEØ ‘Þbš¨o”U,4ÈÝjwèýq èqÜ5M‰o.ý}[=øÚ’ØÿŸWé¼*VÈË(åF°\ƒ¬ññ¢Šì}Í1=*b`TÜô®mö~´ÐÑÍ~,c³ã|TÅ*EDŒÇ¨°¼¤tÐâ%èº(³“ý$½ÂZá:Äå•%Ä(å¾'ÄÿÒ T–`¶(w:Ü„GW ˜b˜$‚{×tñ€Ê „iµ÷ ,jî~û蓟TŠé‡.Ñ´cuÅï¼ýÚôÚ‚ž4ÿLGqüM€ÇO;JF丣 Î9WõÌèþ\Ë'èi¢¥€ÂÒ"I—HûJRORpá¡'ZÊ@ƒo)`J¸ G©)p¼½ì ©ú5 û ¦M¢ó‘òߙݾØùWÈS3$‚'P3Í fVO¸áñ:NʧS­øã»Å»ÅXúÙõ °üÿ)5õä)±È'Åâ8ˆb1ççÄb¢ƒâ©˜Ò\É~1Ȝڢ4LîwQ }~׳Ò0Abl*zÜTžÚpZv¦¤a1.á?( húKþ% ÿôÒð¶ ¯¸:yÅu^¦¯ÉŸEB†KÔݺz6ý¿ZÄ:­@"8mŸI æeªR¦ŠÁ„ŠBogæM&kŽÍçjÐf!lavjÄ3ÿ£juú[È4¹é ¶ óš0n,mjQûM\þ»bYG+í—¼û>ÛΩOµ>”~fíw¾gü™µŸõÜ×:Ígæg17<[ëw¨†ÙÜÀÇÕ#ÂË¡<\µÕº^•}ÕMS†Ÿ<7¿Ö¸m<Ô’'®¦]O^'Í-Áì„„óÓåõ««±$ŒzkÆÀ˜5?³fÄÂ<ÎKñ4w$¿H-¯}ÝË"æÔ±œ‘FÈÝáeÙH¨³9©÷÷óy£ÄnE]†Øñ/Ó:ayÜ‚H‘Æö…ǒĺø‡C§yÔè|ùæfá%fò6Ú€‘íCÝ9˜,–³/Ìß*Öz‰endstream endobj 91 0 obj 2065 endobj 94 0 obj <> stream xœÝYKsãÆ¾+‚Çu•9Ƽ03v’-Ù¦SªZÛ²D\Þ°d!!A.ZÞŸžwC)ºrI¥ö ­á¼ºû믿i|\„. û/üÝì®>^}\P7ÿlv‹¯×W_ÜQ#Ć.ÖW~]˜b¡8'†-Ö»«7ß[ÿëJ0" ^¤õÃÕö¥£œ0£Yû¶*;Ê)TÉÃèýÐ7ñ«Ý&špMuøé¶kvÍÐüná†pÃTø¥îÝF Qq6•vì‹;Epn·÷^ VÅéb) Ñnâ¶é‡ƒŸËG62 3–¬$ÌO|ws¿¾u‡ ÂJ)ÂAÃSÓþf‡—q|i MKÞžYòÒ­K°¸ð[”D7yÇ¡Vkœº¾sN•DªäÔŸWnÌ`G7v̾äéÎÁL,TlZ8ÈyR£Ómw6¥¤ iO9;Ëñ:ÖŸ»Õ”ð"­þÎI¢K?týîÞ]“SbLŠüîÔ=7}MfÇ ei Š”þ]çT’¢4lói>–Dap4¯ïî®qáX&ä$œq܆³@‹ÞžY4 ¨äDûMJ"ËÿံáìÂèèÊè`8R9®þäÌ'J瀺°—DA°ôag„Ò‹ÃDB!ÑsØëÝaÛýJØ—œ”0‡âÀ¯¾¿]ÿéÀ»Eÿ—ÏëK­â`ô1#^DÞ1Ìûl‡‘ÂÄ@컇pqQ¤ýö]æzîâŒÙ†ê‹ØÆÁN\;^2R‡:áP”Ta’ U'3c3‡Ð(T¥ÉçPOÕ$ …F¦ëç`šÉ´½¢“#[–»Ç›&ˆÎ+?x µ­»>$H¡S‚ŒìäØNçTðËéþèéŒ bÄõ'¯˜,±Ç]žªÊÓµ~÷·çˆìkŸŒ‘}Žr~_íê ïTöhvMÞ¨»fã|#ަyfµ=ú@@ÆA0Åk0D"}ÒîÛeôœ"çŽG™e6¯3á¹~Å€Œù„½ àCrŒò™Xlö±ƒÊMT_5Þ†uSpþR@:Bä0y H™÷ö\°dÙSÕU›!àMX£“èö'RfkÎË’²@Ì…[dæŸÕ ‰%2ãÜ`\ä š¡¯·_E¸” Fþd£;-‡#÷õ¨~¨ýµ$€Y%'nº~qyÊ5a¹ysÂ1%µAΚIɶvôGË‘b‰l£³±'ü–»ÞN4­žaµ„+4/á ¢ šAáÞÌkàRpñRM-—m÷ÈÄ1ïßÜ Á½Ñ"`° ÞEf–%z< žÅ­D`I¸ ž¸8Â`‚P9+,“E~¥FC±P«ð¬Ò~*_ñßí>Ø¢s8Ÿƒ)&ëÞÙ4¿µ8µê?@ê}µÄÁVÆM„íyÕJéØfܰÑk´$ÖŒ"%3˜êÏpv?=Fú€îÒÌPœ½XB÷YiÀTy˜›êèkÁøuóJ¾¢Qìx3î’=I¡_…â©334ŸCEN¡ÇðØ/±:¬ÿ¨v‡mí¦ «tSïöbLhûJ{=ÒjžlÖ¦ÏÍvÖ£÷Lµí]¼mcÇœ}´´¿yôSK‹b1†îdßA÷,¹öõŠû÷õŒÒú?þé‘Ò^Rѳ•¿€Íè|Sm‚£D.Œ¡AŠIí×ài¿q Ê­…ù)·cÓ©²e\ i».èV…vè?®sÇ ¨•f,\Ðc2°@AÌFû½ý¯÷ ¬{jÕ_ÿ¸kô„<ÙµRðiɧ¾¬ ÏUç¿Y”9±cCD3•"„ÚVÌ÷…_2°bsm+«Òä3mbmK ÃhÏ]+€lVy飮+jYü¢ËTNKÅÏÙ·««6}3îÖ~\8#›!X /¤HN3ÍÞ|•ïñÐüÞ•m¨J¨ç8xW(Ùâ·FAL~nOKÿŠeH–öó-b*…73å݇P¦Ái1\½žÏÃ2PœŠ_¯¾®¹ 5Reî}Þw4êʬŒí°ûj½øéÊþûÊÊ»endstream endobj 95 0 obj 2088 endobj 98 0 obj <> stream xœÍY]o7}7öGè1,–Ã!¹}dWMƒº¶#ÉXí>L¤q4[i$kFqóï{ùMiFŠ‹<8 9äå½çžsH? 0"¬ÿ¹ŸóõÅÓÅÓ€˜1ÿc¾\Í.¾Ÿ#HaE³Ç û(<Œ!E³õÅ’7ûÏ#9’JÂïg‹‹7WãÉ/ã›ñoú79GXPá~ss÷îÎÌçHñœ¹Qޏü~Â62©o‡™BÒ­üÓÝdüVÏÎ89ËÝϛ݂˜•3Dsž%ÃÔ®}x˜¡bHRøÿ"Ïíâ›}»Ý·Yœ , ‹Ï&zŒ@˜BR7ö0Öc£œ„±êÑ̃o•$>=$Ï”ñ‘ÒQ–ûHç›ui¶†ÔæñMQ–+ìsX>nv¥Y@¤3{7¢n#“]Õ&È M¯ß»™™3ÍD2Ù{¾Y­Š¶ª?¹ 䔸¢7åÓ¾¬ç&²,G\…¢ÿñ"6ËSDEÞ 8,› 3H"áªÃvÕytqCÂý WeÛ–»æÒäMé/Äñ)%§,VÛeaÊ(ÊxÆ}BÛj^¬,Œ!+a¢)w|‡Ì‰ *8âºhÊaSÖMÕVŸ«ÖÔH¦Õü‹ó±Vædp"Bü‹Â_Wu¹Ð¿ãpUZyÀ8Ô“­šS?©]–†*¾nŸí—$Il±ÚÛ‰0¡¦Ôïq=† èé Pó›éøý»[è¾ïMá(¤6‹l-3ª°ÇÃí¦õ(ÅSí²0颂þ ˜´`$bnÜшBPÕÐaµïP–¥¥*lG ´&×1ƒnd¿î¢¢¯Ã¤ ­2Ö´7 ]ÙìWm;ë¢Ûe_Ü!Õ›ÖmDâšID~o³3ÀÇüö†Ók›t™Ö¹pME¡¤‚¤Mõ\µKW¡Âü›ñtzÿƒ=D+¡\kÆÌ–å_Åz»*/û\stìIKÞ÷ž:"¿2‡kCzY(Gju…µòø±ÇbÕ”îDßs4:/öv*0®Tá̲ž’ ûø,ë9z–©p¤âØ5–ˆÛÓC¦AÊóTc¦¥¯•!…¿_bsýûÒžŠ"Î}Ûâ“o_Ë$•ÃÈ_êÒ”'ÑÿnÊi—Í4Á‡èû—e.õ€ ȽLÊ;~˜®/Ÿúªà“0 äÍž?8ö—RD"!c˜„ô›ñ~É9ôF§“çÇ’ ü/å $Rù‘d+¤˜$ì‚l±F¶Ç­g8)¸Ý.MK3a¥{,ý`.»--tú}Œ‹¢Ý¯­î‰´E›Sª&uœËRu/¶ÛÕ¯äš#¨»°¶C"‘”}[´–OÖ&ø3lêÒ‰J†”H4å¹Záf éC››˜´šø#,‹ÚB”›R~–’70j{R—"̵$xÈÈÝ–«òŠ ô.q† `ö“•m‘¼Žn¦ci"&¨çª±<É)b,|Q~vgÚ\ }c ’þü—ë®8y4¹}ûîŸf ÓB*ïwÕZÛ)×Ë,’¬%^í¦bß>/7޼Av#ñÖ…wÑ8iÚb×:¦Ãq8¨KKåà/³íó•ºÐ߆¶´ßBBëø¤‹Tâ´ÀS SŒnß'îð*ÂöîaŠœ¢çqŸÙ²¬v~˜Ù÷dã÷Gv‚ôîW[ Gš”¶ÞÔÃò¯­“9ýn¹³p:슠¿‰ks†ðHòÄ$Áíf]Ö‹ra"ÈJ4Æ3çai*‰þ$˸Žó«01^"3“gˆ©ñÜ6/j›ˆk®Êbá¶ñhij>¯vóýªØ¹%— ãÂ{ޏFÓîöóvñÒº©3•º¯ªþG]Y—ÌòT½Vw*P%?¶Ù:S Æ€D^ÙuùþfóÉ| œÀz¾+šeÙ ^q'ê ”`Å›ÚÒ$—ÁЧh‚ª€¯ \µÛöÙXàÅIj~ÿz5žx ˜Üß¿n†’[ E¼ÚÕz^¾Á\(¥­IÉËòíñ±Žo)§V„’qçÊs˜ˆ|^r ¹ªß?8v»+òt^ T2¶Ûñ냻(ø{5ê²K?éãN%îìã9V§d‹|[¶ÆF7÷N7;ö&9ätf˜¡{àîÂR0Ý´|Cñ¸õ¦÷hF¹È@žAƒvé!fçÒS£xÎIMý'œ“àñÍàý©d$q 'ciŒÝùbµâĸ{ŸåøqíølàY¸$üëøzÅÙÂAêr8w¼ÎpÙe±+æîÚ7d Š£RRêMH×£À«³öÙÁ9…KŸEŽaI%$ÈS?|‰ö /á±>ä¦Nè¼&ÑÖ"wHÁvâ§ŒÛ;¶©²XýF&Ûcÿ–pÇɽø„ìÁÕEC4¹Ó6û ÜŒ^M;¾ÚN®¦³ ZSÉ,L $MßòÁë¥l~Á·ß²`GÕ ûpgæ/R5òBžNÀj…©³ÖyžUHÚÃù¤£4á› 2}@Üô°vÑs…z­Bâç‡ I¾z 4c°}¼žœàçƒ3ŸÍîpA”÷ä«ûH‘>²{~Î{ùH-C2c ,Ï>§$À9 ®äÉå,IKÞ= &ý&àõ¬šÛ.8PÉÿ+IJ¥ Ôןÿ7$)33±¶¨p Wϵ³„˜R߯¸+D!ÑYÊ­·çî &;~<Õ~têJÐË‘-néûKà+žìõ=+Æ×½äõÅ<Õ˜Ìé·øúÒƒýžg¹ÿâ/—î ÉKã7b´ûRœ±g"ÌÇÂ)‚¸ VûÏf¥¯¤‹^DÐÖW£ë_¦7£éÏþOPúO½áä󥽚ýpEòáÛÓŽgƒúßßÝ!> stream xœíZKo举û#¹Ä“¸9âC¤¸›f½b`7»ëñ`ë=Ȳl+ã–zÔê8‚üöߥ–ºÛ“ §s0À¦ÈbÕ÷}U,ΧEFè"3ÿüßjuòéäÓ‚Ú±ð§Z-¾¾>y{E9Œiº¸¾?qЅΊs¢ÙâzurzþX®‡ºsý×ÁˆÈ¸„I×w'§ìK3F9aº`~ì›r(Í(S$S’ûÑ÷C¿­†m_ÛE  ZøŸ~è›U343¿pM¸fÊÿRoìB9D…ÙT™±¥Èr¢8],…&…ý¡Ûëí`¿É’‘×WÖÈœä*ùáÂŽilxsoÇàÛ<Ž Ö`Z"Sá,M YËà{– ?\Ù­‰`šú‘Dz/«à8N('{6CŠä"Î-7Þ•9»w}óдåÓÓ‹÷噾i½µh>lUßYà ’%Ã;µ%§ßNÐ"˜ðm÷`G™$—áëçfx´£‚hGmˆ5¡™ÎÂ’·eå  &}Ü<•›G2F˜X,aÓÌ…ìæÔüðöŠ0(-t<çÍ›3Æ)_è,xóæ™V3d2M«ï;‡?–*’{w© ª¢çíQáÉ»ÆΕœÁd‘ûq ÜŒ®û¡©Ê'?—³ˆÅÛ²w˜f$§‘¯ñÃ?þ=7ø8ƒçi<Ⱥ¯­Í À£cDg5]°q£`]Šòv³u§Ò‹¼ÍÚ/©TY]5~*`O¦©/­"ÚìiªÀ4*‚WuÙ6íÙeEN$¼ú“‹EQ+¿ûöýEÄŸ¤ÌØÝ?7›šØ¯$Áîô{¤'Ѝ¤Jõ¤HzÒµŽ·@œ<±Ž*#§*£A[ãáʉJrÒ¸˜P8_\Ô3TíchØÇ1Ô醀¨¦ƒnÖeUŸyk?”·g>‚€ì°N[??5­›?;G¦¥`”-pÚÚã0KçîîçÈà¨HctnÞüüËo—¿yûûßýáW_~usóÏ?΄f’ÈG˜#€_.$3sÀž‚h¡KQqyä^F¥Œôúq[÷KIo¯]3ü4K„™KH`ʮ궭‡n!¥ÆŒÚ=Ü’’ ¦€k@z…wþý‡¿\[× ÂMŒ=Ìt Ù!3ó–&ºr7#‚Y 7ro fF·Ž:*¥¤íÊ3½HP“ÕÞƒO¡ÌuŸIÚ‘L’<å''´°@1¥ÉÈl›ŒH)á*‚ÔñÌÈFAÅÑ|´‘§=¥FÕ@éò(C‡Ÿ&ò®¿ûÊ.Gq¾|],ø$q£#ÁУ`ט)M0×î}"0i.êèÊ'#)âÞ³Þx9ö›¯ fÊ%M21!(ó‡Q âr1„&,Eqã)‹xqãÈAOÍfðµ’[ŸÈ9–Û2¤Æú¾ ¦§ÚÇÕ]D¡sH35AÂŽó @ ޾]•!A'¾8«!‘ðË«>l»Á›«äfb9áq¬– ápOE}WÿÝ‹%O•YÄ,’þÙï!ƒ ©¢ £¯‡÷™‹,"jïêõóu{çõdY'±éB`3}ØÐ=Ñþµƒ¸Ä>uÅ? 9k7áHiäÁfŒÜy¶ÜTM3—^@Ø ”ZÞ½?¿¼œ¦– Ôø¿“Yfïõƒ“*cV2âÆÅg\ÕƒûÞä’éîÖ¾€- à§™û’#Ò”í‡ ,Ësçh¨ixRá±<„Tík¨ 7n;sü7³æE¸¢ØDD5Ôæ)§˃:Áü\I2^:ÞŹ‹KñT„Âm:?ŠJÀjŠß:0¡®Ñ‹ÿ.ª»¢¶csl p\IsÒF+Ÿ“p“dè‰j™¹.‰>|‰w$‚BÌ\l‘šN}†ÊQûç®–Ÿ•øFýßlÎÆ IYŸ¥ËRƒÉÏ1@ß×Áñ,}ðsƉûò—3"¤uù^LxºX»78¨žŽR–‚ðR%ð5ÕßÊ9”w™Î±ë@?AÓcÍ0Kã¥ÁË)ºÏ~wñÝ×Wž„MmjÓ+¥{ÆÙ,ÇÁ……¡'ºê6óíhK ztEgB=É×µég{Š>ËBÛé0 sqc¨ ¦R¼nŠôùÜC„såÇPª¤7Ôø8ÂðÚåPÐ\œyâB…ÇG¯ £·(&ê<Ê×ë)y»>\g¸éC§nÏ+^(@Báµîûnå‹®À³~ÑoB)‹bд›¡l«zZ^î5“ѱ™ô¸™ñ¹˜NKU[SsêöŽø€J”`Ö”šÃÚ’+ó”ÄPðf8 "øN_ÝÆ(ÇoTè!0è®y<ó3q“q”ÄÙän>®kêÕÚã7ò—Db9û‰Ç 9öaQžE$F°¬àR.ßBãŠ.F?ÝÎYïå4Î[¾öõ$z®§‰u/–ÐèÈ›LCCÜòøFw9øz×Ô¹£‹z|†)ô´Žmîû.ÜFU’"ßñ˜.q ^ËUü&½‡¹óáW¢9‹?ïÅ2’©žøñìîyå²¹yO+íÉærO6¿¸^üxbþý w xÎendstream endobj 103 0 obj 2482 endobj 106 0 obj <> stream xœ­YM“Û6½ÏæGèhWY AüHN{j˵ŽíËq¥â=p$Έk‰”IÊÿûm tSÄh&©-lC$Ðè~ýúuóë"ŽÄ"6ðïõþâëÅ×…×Ü_ëýâ—ÕÅ×BÂJTÄ…X¬n/ì bQÄ‹LʨH«ýÅ3‘?_ý÷BŠ4Ê‹~_m.žýruý¯«7W¿›_RÅY’á/oÞýóÝø¼Ž J\Õ‘6‹?^gb!dÉæÀ¥“-–ªˆòñÉ]k"Š“BàÛ÷ãRÉØ/Uݺì+»§œ\"‹T*²b±LÒ(ÉѦOW×//?\™çu %ÜEîÛncw™ºb™Á¿ÍcK¡£,ŸmÃá8ôæqƤ2ÅMJ³TÀ¹Eìܰn£ÑÚ\Ïyá»}®PE¬q©½K¢\äînÃv¼˜("‘ÂÑv±nàl³œ˜ƒ´â®É"­¼gàB/Æç`ÏÌà_Ž#•û=ïëa;®êHP¬ÊÝM×tüñ`ï“GiîïCAI$¥r—ÚUÃPu££F9j=ú.RÚmÙÜUcd°ð[ 2Južœó˺íºjiÖ—*ÌJˆÌ¾? r²Ì{·m6us‡Õ=žF@ н{þÊQä…Š O.ÁÏJqw&*Ê“´xÓp¯L éïßÿÿ!­òSHgp‰üQHÃ!qJ¼ÅÐÅ¡Ð%yÒYüHËHˆTÍ Æ!HË"i†Þ¿ð"ŒqÅñS1žˆ9ÆWƒŽ’a\ü]?–Æ"ÊõÓ0mª€Ù`Z§ÖŽ¡l6­ Ê)€“èÁ÷Ãêòí«wW#zE¤…¯Ã ŸÁêŒ4Ïø¦§è•ç™ÒF¶È‹8=‡ª9 Ûr°XK#&·U3®B‰T]ݸ-´ÇåP!Zá^Ī÷µÅ ÀU2®Åx@$ª²›/îê/XeJ‘³÷”ìž@c„ç™q â$Œïüž›º?ìF&à.ü˜éÚœ%|nXØ <ôH¨ókKØ RÀ–ƒö-î’_l*ÌWEkŸŸÝ ÐYMhw›Ûr]½@Ë¥RW}sÖq¨[ O‹ã·zSµ/æ9Þv¸ƒ¤»Ü@ìΦ´e*õ;c2³,$—ÅŽ`Úc7¯Ãeûº)G|(¨ñ—Ø85Ä|SõóÒxÛ:È€KNÜþùù˜Ã:Û<›¯,N€Rž(I¼Á,¥62*'žuÛÌ ÂPÖMP‹­N®¸´l¥¡$ºŸªuýÃßÐTöå]½Æ˜ä´Qˆ^»rí¸Xî_ ˘ŠS†…rÕˆ¬t¢àª»ºi‹ ()I\ð*bHÓU³ù ¦…Ù L‘ œå+ÿ`ÌÂòg Å<Êu —ÌîAK#Z“’íAÊBÒP*c˜ÚÓ\|??+{„šdêôÖê£bݦ Ýß K´cÎ7œKœµúýýÕççXLC{!3!s%;ra„ ,¨4º„Hx9°f^GÑé**w÷”~Ñ^–53ßé‹õ*g§¢Sö¬!Íœ3¢ˆÆ†ß€<çáwq2NR'^š”^1@±¨Ó{3m‡ž¼ ôí¾Â*ªÈÔŽê hSë_HròÑaŽiËñp4SKTÀbÂm=ÌmÜ—0!ýÚw̹„º±ºYöH¨ÿ‰ýŠLlÄpਠæÉðÀ5M>•À¨ÖŠöV‹°jBrÈœÓïÛv¨~MŠù1¨ÜSîç´ŠÃ`O©»±Îèuld%kd?¬ÖÌëLã%QF p¿­wÕœñß´w-‚&cÚ#¼…vG¢æIÛâ+c¶q„ÇT¦xÉ•‘.<»3¡¦ &õÚ›òf÷ÝKÐñ,¯šv JB´œî[€ü,5 WNÛmª¾î°ÈxÇQý£Z»\ÍX®b®2*Ö¹f ¹²l<¶UÌMxb Ï媧m&ô\l,ò=j*&ûß5ÎÚ9ÕOðk¹®lÙK}W¿} ¡P:O£;Î 2ÇJhðˆë`e‚.¡_zhlŽæ“  ­v(‡úÆ&ôI uãá†8è®cÏ“Óc+ìOÁ¶L²Ì i6m.ï·­o«Y¿üðòõ¼p¼¶îÉpÖ-z]ËÓ®aÒIx1iq×U â;Ì$6ȃ°5謌œ:1ÂUVwA/tpº­KÚ8ȧtPøc:1 ÿ5‚0Ýì És J[¯Í2­íË/úœ5K?ლB¿òÊRVLêèþ¡;®‡Ú2Gx@£§——o_¿ýíêÚŽ°Rùt—Ønp:¿J£ñ¾Ä 1”+7` åRÍ6† mbßh`0¯Ú(‹RÆlžŠcb…³ÒÖê¸lš?&+¼Ï€<5ê‹jä=”ùå žÂßΈêalÁC¾øÜÌdºŸ”o\½s¢‘Gp°”ÚüG< â‰Xèª~€lôãyÍFJ¹ñ¦º-»¥^N¢¯‡céŒWFöxä`íœhÐ2¶yý+}EÝ: JD|BþÙ¢(‹Ç ^&Q4ÚÂ8ÓªÍéœÝ°úsèJRYSw]y@›¥ÑÍg—ŒÕÓ,}ˆÖiÅuÙ  hÈ“{®”'á!¤ˆOñÁú¡ìÂ#ôÓ äûKD›Tœž+HóXxx. ™œçŒ]Ý[Þɸ®ôBamÏç0^w|޽ pG '÷¶“~Pk„>goóô##xR¤‹#(‰xG¦µm7:e1@E7¨¤ƒýô©F¸äÁ'ÖK6½`‡žÔ¶„KÃr®¯¯¯._YdËB›×±7¯m/c:_øñc:‰ëF¢Á©ÿ ºra͸þ«û!hš/’€iLþôîúUœªàt·ÅÍDÇÇÂ}‰]úÄJ¬‚IÞÝ105-Ý #!_+ÿR ?Ǻ %ð¶ [%O¬ZByÂHç±Ù_?y²·ÁÞø]OjŇ* õÿpÆÿgŒRZЈòPÞU¨YILb”›Š&öUP´Djã¾PÆÃŸ0)2ê ¼ölx’5rìt&á“8ȉ‰¿ÛrN„nùqZ´^|ëñ7ý.cˆ±í‰ýå3l–BA—Iˆ¡Ø1‘OcÇœŠð„ÙXß±£ùB1gGfgGsìÈFø±s:Ís<š(¦QÏó(õó³K7‹fJôD«-ef>Åò¯3»º©~v*~òÞèXŸŠýqGç¤Y¶6fN•žZòïI?üI¡}Œ[Ô$æCïL2M>CFà4= }Ð5¥“¿}»@'9Þ8äôÙ²¯öH˜)ݘi ÿíÃÚ ¬8o¹Ç–aΔ¬zÛC’+R#PN„î†:”SLIôǃM{s@;]%4¡ ÌÉŒ®¶ ??}ÎËŒóè¤w 9Ú´víûj÷ Ë,ûS`î ýrµZüûÂüùe6͈endstream endobj 107 0 obj 2642 endobj 110 0 obj <> stream xœÍZY·~ßäG ò$;tóè+yò¡Àd{#aZ?ôÎôjÚê9Ô‡W øÇ§Ø,’ÅiÎÎJN€@¸=<êø¾¯Šü°H_$úþ¿Þ]}¸ú°àÓ˜ýo½[|½ºúò —0Âʤä‹Õý•ù_”É"—’•b±Ú]½øf[‡ºûbõÛ•L%2ƒV›«òïzŒK&ÊBàØ7‡ÝNJÎxš)÷ͺšÃ~ú“žÚý€—zìË7B-xÎO•ÞÉR‰„j±T%+ÌbÓZ%“I™ž¬•¦Lñ"­'Ì\1©21Í›+–‹æ•,Á‰×_Š‚eY’ã$+=T²2ÍÀBf¨«öý®À=ÎØn)$ËxV.–¢dÂLýÃa¨'IÁÒ"µÖxu?…³2/8Ž Ûº«q¥ÿ´éçŸVÓ¸·(íÐï“Wn¤êšê®f”Ë3ç´}µ«7æ2¡€Ï’Ì-|óæÕ«o_Þ¬¾{ýêûW«Ø‰9ÌÏûÐ Ûiÿ)+`¹ó{ÝöûúxÈlš³"MJü[mÌž'%8-0ù±`¹,¸êw&—*ÉYVBœè(«Û¶9ö†v$üE k´ûC‡! kVWkœ#óƒ[³TZ”Iæ‚Æ@08Žk6"Žs‘£<4T&dK2ƒÁ$ dà7ërS×GÜjÆVÔ9.¥ô¨6ýòÔÙiž¸°ÞrŸš¸M’¸) 8h›ÝäÄU?·×[s Ê›ÌD@&.±¯(\œû¡ÒjÌ ýj°\€d“ÀqK8µõÄ™Ýñÿ…ÞáE¨w~yõí½S–ÏÓ;Iö?Ñ;`,é÷L¬à y´‰–t’R*QýT[­@š oO:H¿šÂ]Ãÿ±zW£G¥'¸Ò†Ÿò±sm2‡ ¥·'ð€ @ÆùFF¸€ XJÉ™À“Bt¹ŒÕœÖi(TƒO«9±?-TSB—…ª¢•à?~ýz:ùM s 2î›HÛ–¹@4YL7Ùhu˜$ÍT}·ËS€wPŠàHj 2b¦!æ10NÁs}+œÙ[ái›“!mR8û,í¸ÏÉ›7( 8¦ö{;î¿¿õ‹¨$¬ÅáGü̸˜3f¡…u¢õó-îK· "ü>s‰Ù:Ÿ›Ð²¾_v;(ÁM—r!u™uc]܃ŲÈEfAKøf4eV È¶A‡dú´GE˜ù‰vž\k=vI©+v?A—„p×C× –H›«×’É”ŠújÎÍp ›k†ÒgÂQ°ä%A´ƒZq×ì«öö SÝÉ‚†ÝWØœº®óÛ,á[QˆL®bý…KBŠÌ{°WTÒ°Ì¢·¾ r€ø¤mðÞI—þ.¶¯AFº‹³ªíKgacª?ê¾é4±~5áy½ßXÓ[vû zP•ifNIQ»¯ôžºôd]mJz¦âÙUj¥OSÓÇs šH> N¦’I7¸mI—y„ê?ŒèÏðºí®3Vwû=•¿¨ÒÁvñ}-¹ jŠÏUw÷Nà夋aßÎ6vXÌe…øS‡:½3õYû_Ê2×·-ôÆt¼Óêm”p¾_w¶£"ƒßOB_o< b"¥GeN˜ø¢òÑÒyQ^’±Zˆ¸"£ ¥3W0}œÅTJIGÁƒu„¿h{<¢Ø–`H*þO9°4)dN9yõï›—ÿ(·kÇ)ÅÚßDhüýqùúƒEWçè*þ<ú ÊâhAFáBe§ôÔ4éõ8Ú÷[!ÉÏ3p/7ä æòà”‚Wª?}÷#By¤ö‹!X}õDž1Ú_“Þéì‘~ÛÐáýbø¨À=’%Ø®"|I€ì¾;˜W. ßhöÅôåãÆfBꢪ³ å~¡[4Aa‚Œ¤´sç/zÉCÌ®þ0Öæy  Qá¡Û´Ø_®ÿºÒÿþYoniendstream endobj 111 0 obj 3297 endobj 114 0 obj <> stream xœ­ZQsÛ6~wû#üvÉŒIÓ§¤ñ\3õœs¶®žN}´DG¼H¢"Rqüïo,°K‘²“Þ<RÀbñí·ß.øù4ò4±ø¾>ù|òùTº±ðo¾>};;ùéZjeRÊÓÙÉÿ<-“S£µ(Õél}òJ%¯gÿ9Ñ2EYÀóÙâäÕÛ‹ëß../þ°OòL$F|ryõ÷+÷~&Ê,×8š‰Ìž§ÒÀ´æô<-Eáž<ÙñLèŒÀ—ÛýΪD¤…Q8¸ÝµwÕÚ>HSQ$:o»—e*´)$ŽU}íç£U–†á{5’^m6]¿ÛÏû¦u3x˜Ó’ëm÷Z¸‰È²¸ËÙ²éÜü™(LÜåýþ‡z×l>:#aeß_WŸÜÒ°ë„×k7…ÔÖ¯Áœ~YÓ‹Ó{Ï‹¸w7T“–IXi?w¿ku~¿ô¾c¥õ=¬˜xç?T:JK‘Ë4‹VxWûØ!6½›Z‰4‹S?Ú!#²´”ñôV t¡ßÞ;¤ˆ4'KÝFKQ2ã›·‚)y¤®æxÀy]·Ä÷²$®ëÞJEªâȲÚUsÜŸõ´ÚnÝÆHÈ‚ÚÖoœÓõ"S@€…Îd^O¹®ðˆ$øi"Ç#-eäKäsËüDõ¼îºj÷„Á)Y ´c4pðÉ#|ù”BÆùÃÌrdÜïqúö<‘šâ¢:˜r<ÃȤLŠx’“aá-‚AEY·þº]5ó¦_=ýìÎBñ÷!ý»H £sLš ' cfY~'ü/€{C†&䤡ԡwÁÚ”2âí8›¾yïØ[YJŽöX¦†$åüÓµè¿sÀ,¤xP݆Y ‘S¨$þçCùX «‡ˆl©ÂL°Uo+[A+ öËvï°›Z‰!hÙW+Ÿ¦SДWÆ*¥jbÂ;WIb9v ±éazS×c@ü¹ïß>ó'"'¸n«!×1cUŽA“RÏ<$ ƒåŸ·H,´Áñ~8}“«&×1ÒŸˆ‘§öì,iØUðÛ â^NSO’Ë6¨€<ª–Ç)4€8‚ pTʃáæ×«Û1 ü9‡qŠ÷»ø ò'Ï¿‘x† Wž0®p\ !î^Oî\¢J¦îôòÄ3Ð}„ƒ3ÉhË„X¢KH,5›­ÇÝ0±d÷ª›WÛñ¸Uó IW“>DBàyáÃõûÌÎ&SòOýu^o{ô§6\±÷˜- RN¨§¡}UHL°[9±1ðy˜ºäºµò<‘.UܓϦwS}X-H›™ä`B¨D´:ƒÉó´ ¨*Ø!tÍ¢FÉ[”ÑÝç=ø€4òøýÎpæŠ0ûiœ^ëÞç÷siR QÓtàÎȇ¨MOTN‡¨,ÇT€4 )Ò°)D›‡´Å"@ÚF¯w8*^Ar ɺù‚rE™4JŸ3GlÒ¾Ô0!ð|˜wWW‹p~‡‹.ú=s\_¼ywùþf†`·ùáF/_ÿm"(µ(8ŸÚeº1—ϔʪÁL(…!ß=@)4 b R8Ù„¡]jì|(òk_AkÃùæð© ¦ °XGDLΊdÝlª•§£´à ˜ª?ÈÌQõíûÀ•u.b̦\EL; êm,õ,«À=iʹ§ ÷ ¬jÝw{6«”¨¶q=Y%Zs…z%™ŒQ‚NɳIì[1އ: )œm¶ov"Ù}Á€–¬Å棢“u,ìú ¶h³]½næíÊ£!µ’=™™‰•ñȲÕY^¬aÖ{‹K–ŽGLê[Û¢qqLå® ­G\LCµ>äÌQÄV˪LTïíÕõ;ûú«ëÛï»v;C±[ØÜ7Äg9!vt@ù/)ÆÌ¡yßh”MW1[2-ÁR•¶¥±<Õ¶‡§Ç&³–~Jèâ Ý÷;™¼‚Re]¢ T¥Íõ çºÔRùòøÚ¶—¶Â¶d’ErPͪ¶¦e™r*†6cðûº,:ìÚ~ý¼™;¥ÜxçHdÓm+H§gèv7ø=uïÚÀ ¦ºŸ‹@„dYT‹Œ”&7Æ€ÉVgÀ„šÇai›RP±[š mæËFj1áÅÂÀ¨µ8L¾^-SÙ> K7ÿ?ÅÈ"Ó² ꞌFoÑ©ì¾Ç&ÒÃß¡"H’‘"jãã²®T[¬# ¤ šé¯-5h4ú8‹›Ú-‚¦j£®Ú÷º ¢:·w‰<¬_VŸ¬Åø¢ú´¦Ôg $¦>5WªQ}ª)Ü•ÓÌ/I({õ7ÖAZØÍ‚4å*Щ@”´÷Œé&û¤ü{¬cY–—*Á.õ˜XÓxßÕA'«Á•*»'d]”ļ@¬è/Å÷•­—ý¹[˜ßòˆø–ÄkÇÓÊàûŽwW7HŠl_Íf¾Úc§Óv(ž7áˆËd9]êON°©ƒÓ dÍlîd'ò “2Û@ˆ‘ÐMô~˜œ·ð†}v8çÝ?ü+ÍýA÷n<Ô¾.Ö=õW°Ù·ú´áØ~ Ö /YÇ$ Ê€Áw7½½ê …@BuîïòHåªù½(pG¸ð–ZœÞâw%rT`ªäH4°/°1%K~)\­üáùÄM¾‡Ên÷AÊ2öÁwÒÑ,–$'Íòaã™Þ&íò©ØðOQ<£ Œ·_./ +UâžY’ê^vqûò–‹ÃÏœˆƒæÛ$‚ü¾=¹ØtØû‰|rоv²«Ë‡vµjƒn¢²ü1Ü®æÇ“«=“Ý&/ä–X T–TÅxgÕb_\)~íÄ;ÇQQcÔv¬%éiƒŽdý·¾ŠíN ³Ò6 xà|~$©G.òó¾ É“ÝC½} "Žûå·›Ë77¿^¼ûà"JNC— aWìãÉS¬ƒ§5óôX³…¤—óØeŸ% ’Þ˜™µ«¸»w6[Ðõ¨?çz±ÝdŸæö£Ÿrx¥7ürç…Ð0Il™…I»ñ¤<ì¯Ò&ÙÇtö[5ì>i{1ý-_àÝñÅìôŸ'öï¿%Â@endstream endobj 115 0 obj 3187 endobj 118 0 obj <> stream xœíZ[sÛ¸~w÷Gè-ÉŒÅ7‚ì›ãd&™zv»¶wöaÝ™Òm©‘(G¤rù÷= €ƒ’åvúÐNw2“à¹}ßùp /“ÑBdŸÜ®Ï^_.ê§¾Ù¾¹ýÇ™ä™ÌEÝÎÏ^‹?›5&2^•Ü­]nÖk³*XÆT!Ýê®]Îê~¹i‡?™­ñÎÌÚTæ*+åd*«¬ÖošfؽÊx©ýü»ËLJ-ü'ÿrsuqóñÃû¿þíÜüµ”™*+æþúT?q•‰ªðï°bØGf2X’™¥·×šMÀ¥bbB2eZgœ•“)‡åðà¶©çÛzˆGž•½ü¶Z¶ÝDDq2žåæ¹)/2»Çõ‡‹÷׿_}úùƒ}ƒí½! SVd‚ã7»Á ¼Sþ“ƒð^^ ÃÞβB£ÃÛÍ0 ¸Ú/|uA6Ÿrãaƒ®‡u›ZØ¢’Ê[ÐÚ‡yÆÂ›]ÿ´ë{%ËòK¦_Ôýð¸¤Æ¥M®;—#¡K¶ç/ þf–t¦$®l¶ólìë­õ•‹LX;ÖPç•ÖèÕÒ~ÒVÅßžJK•³‰ÉPnKµ[¶«as‘gJà&IËÆñn¾z§4ÖbÓ:ßK…kË÷6ù–VÜÙSÿg}L™G±êekËJC aYuOõ¬éÎ}\ Ìßý¶ž¹­¹ÀÂÿl–_¥s ·¯Ãƒ2¤´ég™«–"XöÉ:Œ!ÐÙP™¹W&à6|=ªÌ\íçe<ÄpÈa• Yå~é§Uã-­T(>[ÖS i.J1¤›¶¬q(€ˆ‡Å̓+¢"$ì'[(Lg:$,e)ø4ó©eè뢙Ÿ»ä!¬–L´AÉ+é³…ô ”!»GIЙrmýÔ;à”!è?l 5ðde×õÎby÷ºÝ÷ÇÌ“&öSþA‚, öv~÷&s½¤ÌxAôùAæ’UVŒ#44 ŒÐ÷zfí.ŠÔ%ذ,· ©†ªæH‹ mצɠšPDŒàœ¢xù1.ŒúéÉU[8¯©·‰lQB$È…8kÈåÜ©TÈuË~1†f»q ‚ô±‚€¨{r\¦·7³e½òÍ!äbÝÔ­‹£,ùñ°±~ 4ïÞ¡&b¹Ïݪî–ÎT¦}M×¶­²²B…ªûz{‰~¹š»xhÚ@œm‚’uÝŽyη,ª\ûW!î[WN*Ç8€»ëºï](”„]Ðè#åc!!@¹Tˆ Hë+ƒ“Áui>íùÝ'+tÝ_®ß[µO‚×ÞÈ´ÚâùÉj üâœj "ïIæ¾þéà`Rj)ø(‘AjñþË×5°z«—o^Ñ]2h½Î%£à±î²}Ä©É°çÆ•´PÜï*M]¹Ï•Q“¶ÄH¥1 å¸0>ViÂÀVþ Ž E)ë'(7ž’n„Æ3ç«öh/s(Ñ”ØC‘9â(Øü€N Âî«Å¾N0=dz.êf.F%¹IÕà“‚ïK„ˆÊ½D(éƒh$´“%BK]`ªâ*Ð<¡? üî?P+NXAEOAuTÇÏ"G ¶(ŽŸœ 0gÑ@Q¨6+=êtpø,Sç Âe‡ÎAO ñiв^¶õjH‘,³œc[of ¬džØ› !ªÐ °¨»mÛÌa<¶ù“ë’Šßö€Ri`º=¥„…º!`?JÚ—• ¥ú‘hª›Ï¡Ýcjm™Zm‚¸KdÛ¬ý1ÅÈ´ ÆœkPu! ;ßdÉÉ š´k@yÀ£qôêÓÍíàh)ˆð½[G±1²L1,†tctíJI$BÇN c‰Ð¡Rš;wˆÖhÀ 3‰€Ð¡ÈÑÆ«ÍãÆIøñ šED9ñ#7…ÉñY'+:æéž:oóD‡‹qÔáøxÒÇŒ¯i )é¤oÓ5ŽdÒ€Ïû‚2²¬öe¤"ˆ;¦#•!¨”ŽåsCžâÀ ô´q=Ý7AlU‘‘ÉIi›Ç'Md$…F’™êK'M% =ô®¸£7ØIÂÎêH`¢Jþ¯$ÿ‹”$O–JXøQ:Ýþ÷•dI‰)¨€ÑAIš£ð¾’Œ:ôq%Ifg{J²)II9!V’>G”detÓÀúd^ Cœ¹}ˆÎ(‚‹£t†RRS¥¤¤¨’Ièç)I»g¥dsút^l„陼$Ç&TJòâd)©)^"%Mÿ KNK‚Ì y¡Z3kÉ\ýïjIûj¤þ£ƒÌ‘låÊL•5Zv‹fµ: ÿJ*No>~¸ºòú–TÓf½öwPþ/wá½ø°FÞ“Šø7èb«úñîMRÁV•=D“ÑçoíÜŽö§·G¿µËï玘8?pe¢Æc¤2>Òw»Uïv)ÙþÝHÔŽ¶»ÖWë~0ï¡z‰ïûþA™“{®ÚwØ’ÅÜff¼aâ‡943V¾Ÿš¡ÐÀG#Ýßá%3ðœÒ\–ÊXBséH1§"· Àáz¬·Ê¤"CÉ~ãXšüãïɲHÄÓàÛûeû¶[$#ݾ:w”¯Jæsä4W ä>:K™£úøjŒåÔU ½#!Wnõ è¶­ûåW€pGÒt™­ýx€ûéaýP²DPPdUi&òç:%#©Z-Á6×zÕÇäÞ”lšŠÇè…¹$Œ¢¦ßîfþ'6ÊÔ n]Øa¨R7Öö'ÕðÍH"+N‚Ò±lN]wõø*¼’ˆŠ#—xŽøÉ÷+¦Ÿ#@ÁŠÚ„°ŠoX]–ˆ(Â_ÿAè„ …AžÈI¿¶vÂ\w®¢±è®Kþ®ÈÜ´‡‡îà¿$À$‹½»’5(МòÐc㿬ÇW{¿(?ýb»Ù=.\«"÷ F:¾êœ#±3§%l<ä+%s{H´9’åi8ÿä·>ŠˆøUâX7@˜ê“~UãO[í…›Ök re½nÖÎØ"å½åA#µƒvu™ãÀôš%\„“Q•?Ô›)..œ§ä™þ±ÐcÓYõ§»*ŒÌîmiëtw‡M9;9ºýTÑctÔOÁÜp5õËv'ÜírõÃõZN¢q¢ÝÎ?G ¿°Wyu4©;móòÅ2‰0‡´×Å+þQKˆÒËà·ÛɯgæÿŒÊâendstream endobj 119 0 obj 2644 endobj 122 0 obj <> stream xœµYQsÛ¸~÷äGhú”ÌØ‚ Ø>%®ÍÔ­S[¹\'É#Ñ{4©Ô9þ÷] ,(2öS'3—‹Ýo¿ývõ}•0¾JÌü{{öýìûŠÛ5ÿ×ö~õvsöúš§°ÂФà«Íí™û_É*OSVˆÕæþ쥯6ÿ=K¹bºÐðùfwöòíúúëËõÌ'*cI.rüäòêoWvÆŠL¥¸š±Ì,^HžÃ±ùêBLÛOJ³^°<)xS£Yåš<Q·v-e’kkã¾²‹“Iî7vÇñpÏ­ËDªðƒr°›%KâºãÝÞîÍ™â2{êä¦níªà,%ÃÌRÎ2Yp\©ú íôå¾*wöËÒ¼Jâêq¨Û;»\0žd~ùzýæÝåû› ³†Phî½óþ͙֞„Eÿ2çD-‚ CµíÚBÓ»ê|ƒ÷åt_=¸ð¸*Õ« psââsWÿ~ÏUxKÕZ÷B0UüÀ»²ß5Õ`ÏÊ&W>&ÎhÁF{k¦tîãa/Ë'g–ÍÑ9]0§‡ÓtáÀL…íƒ8+òàˆªÜ"¢'ìƒ#0bÌ&ézç/HMAè«C_ U‹ÀãYȉ±ÚÍ ûæ^šÃKýÒ£»^ˆ"Ž+d.5G›ÿZ×ï«BGïF©bÙAÓt±áO‹RYÙð‹8eN’.¤Œ¡‚ÖH>skOr#g’Œr#¥Üx¨Ç=®æEp½I gF{?áݹ7]]¿c¸Q¥aãúGyhª?›O^_§þ»à:aY"ÀŠ¥Îc‡æò4¼jW>v·Uõ»õšÿ,Jò©L€m‚‹nëÞQ[*™P!ûâåT‡åa_5Í|÷ç]9V_ÝÕR@¾ò(`•KúSf7´}–Û¶Ù;ƒk“STŸzþÉó€¡?-oaœx¸¿À×M*:ܯΎ×1.xM(0"‚edUõcìË툠Œ8ßCÊ¥Þ²s¬úÄš0TçùW-QY¢Ÿ¹åË˲õX–»¶yüòÊ®CfˆlO?ÜyvÊ~Ö†ÓZ8±!@Èš äðÉ\ÒkÎ’BǘÿØîª§È–wW7žH9Ùró÷õå%B=ÚŒ 9‰R9OÒmw±çfçDšmç½½§t¬¦XN§vt†Î‚3ª¾ë®ý‹µ ŠDŽE–𨤽³æ¦sô„qÀÛ´ÎI†`fÃ^EEPfÆ•âä¹JäAWgͤÌcÊ@GXƒ ¨IÁ‡¾C+8!x U¶ë1’8øw`$lÞu òá‰Êz|ZG¶]ÓT˜YÀ!z–YšéX ÇÆ»G]¡\Ël°*¾ÎºÁAS(8ĺ)@s³÷ ,úÒ?Ë­+wŒQYÐpݰ·ÀŠÉü>yr’ÛîØÕ¹®Ä¡ÐGÐûib8„é®/Áøoµ0熴üù_^[¯ŒŒ £ð>:êH,½2¡;ËP6cÅul[”¦Î$ ±I¹Ûú‡õ<Êét¿ÿvÕ;Ô”q]Df)’ÿúö²»ëPöIì8"™$–Ë#‰BûòŠ!÷«¼=•J¸Êw%"[]Ò )K1ØJ…¢óKíü»´Öþ¦7Û-zýõuÎW&ÝŒŸÍ¹€-KõðF> stream xœ­ZKo9¾{ò#„=%€Åi’ýâìaáM| ˜d-æàÌ¡-µ£žÈjEj%“ýõ[$‹¬j5-{v€f“õüê«¢¿Ì2!g™ýÁÿ—_.¾Ì¤[ ÿ-fÿ\\üx#5¬“9[Ü_øäÌd³JkaÔlñpñòõºÙ íþÕâ‹\‰<Ó%lZ¬.^êŸìšÔB™ZáÚëþáÁ®j)dQæ¸zÜvËfèú­û•=:~ ´]›çY!ê|6ϨÝú»÷׿üvóóâúÒþ¾ªD.3ƒßÜ»¨2ø¤ mû°¨hqX·NF#JZìaÕ©£ŒÐy„´7:ù aŠRãêW»T™‰+;kœ"J‹ZE¸êà$•%˜¨ _ë6·UŠ\Ç3›å²Ý9iu.*!¬Ü ¹PE´O·Ý¡¶F˜<ÞÖØ%»b²¨«;DŠ’~s¦ÈuŸ·›ö¡uòçà#£*þù@t»Õ $îµ@ÈV?¤¨DFÀ˜€C»=øs!”Õ©3•Ð:úH\ÿz‰:”„4XÀÅŠNE£IËÞ»  ¢Hß}ØU5¥Ç¥÷bÍ\vè§‘õÝã‚f_öG¼@ÉåÏ„§U?ýôÐ?´àŠí'w“…”˜X›î³Û*£.Ί?ÞèQyŸëºUYA(€°¥Ûøð-¥ßCó98™öowÇûéêí}ßãjAá!³ìw{âÃæ«&‰ û]»ý¶ïwkQ@Eå~Â[ç%\[d<ŠÚΑ QÌ…xŽ6ÞvtέÂK u(ÏyY—›Þ‡(@ƒ&\çŸ2ªyhS‚0“'kE.c`|L ˆ[šñ©Í®Ïð›-Eÿ¥µÙé,VÂénÛÔNÙv±’˜H½~ûñÕå”4$áe·G$2œ›êÇÕ÷ñäÐ0¯„΢1›}¸Œ9ô0ô{,"Ê;ëqÚ””ÖU¶¿O æ7¬ `\¦p¢¿~ûîƒ+ 9´Ds=žƒýk²"«u-*¨·È  IZ‹ÂH°XœÑ£¸1]Ï™¬‹£ÂÉËžrP-÷¸ß÷{!m 3‰c1qdõ)Ÿøørð¥Ú¥2UÑ‹ÊÔh‰ÞÃ7Ø‚,A=–ô~¿ò!­¹¸íWô jÖG¤MAkÝ=–ýÜú’ÃÙa×,Û8'^C€ÄªÐ¶ý¶é¶~{n!…SáÞm—›ãª]}|…ùQ‘ùS\hÙû`Ñ–ùE3S"Ô„‚ Ö½9¶˜óŒÀ¤hBòÀ'8Ø‹(.]NçüÂcY%gÖ¶ò»«3[·gs0‰(Œ>ªµÎ£ßš[Ö@”‰|Ú;b ÷¶l+(~–iS{|õþy㌫ã÷ݦÝb2NÀ¶²¥ÃÒ¶à‹ˆ§P¡$CPõÝcÛ0KmhR­-LÎ:r!ÐèŠè…ï—€²Fý¾wY'­‚Ô=CyÎãé±ä‚ý|.,t}VºL’´Í’yõQ×Öþ håûxÌšF£³¹x¤ßc ”Ÿ~1nÒAÝR»-|Ðl6ß¿•ŠÙe7A§YiœÚƒÅ~ kI¹þìÌé7¡V²Ô_â™ ®b±Î%“¨¦Àf‘ÆûBò:e­;`4rÒªÄÑÊLÛ0'E8änê ì‚5«”˜Œ`RÆ6ÀR½€‹%ATÂÒ݃ÜÖ,Û?˜d…”A›ã³¡¬âè¦õ¶}å):üëý›+l ÿè&/ž…Fd©)\–B‡ü“@‡zŠ£˜·9Œ‘¶'Ç¡zÆ€`„%Š«±X‡bÂx€=œŠõt|ø"Á@mã7€9ƒØžÂ€Ià$fœhŒ:OàC¶I\4ŠG7fK¥¦8ç¿&`5€á@Mƒ. uFgúñéXÓD÷-|¦¬qÿ¥Z7uÖ6hcдÍC±¤øÀ±#–`úIQ§ >% ¢ dÖY7!´ù,yë}q’s&þÇ|óx]¸Äˆp“ÎØ¨*ÖTtª÷D}<Úâùa½÷—òC›ÓZ;òÎT4³mÒfiƒû¼n’ª" Žš¥ƒ`q6eŠÉÃг†bmöÍõÕ›ë‡oÒ6S;±(wöï°âµâ)ìËÈkž %±W*m®ÄÚÒáÐxL(†Ðñ‡× +øûwìï*HÅ*f+†Š=;l|Q>yŒø¡]_lRíôÄÃK=jx"t°ææk· ³QV”‘=Û¡A,ûC#PuÆü¯@¶ º¦ÄfÍŒMÎÜ2âQÍ:Â-FLe—F ãô`£ûä|ÓÃí®D^'˜!d&ç£ sjŸ©É¹á!“s•¦g³ü±û¦¯FÔ®µapÂÒ&1rˆ¥pûÂȱ,Ùe&f³Ö/!dêå„}†ß¨n f<÷ÈCÊJ3QV>©ëTÎ)=WKg)—ÐÝåž%çúІúÁé­Ç©ßýP(uØ»æSˆ·Œ"Kˆ¨’ÐóMÀ&Ú·Òð\ ùsÏe%ý2†g4÷-Å¢?»“iŽg—ü¹õ¼Ì’=Ç8ÓÖç !ü•UæÙøÉ•`hsr儼 ¥6¯ˆ¼ÇÙï)ä¬9ýŽ“7h|Yëp–yçÆvëã}yE%ùµ•$Lrd5•Àˆ·á à_àCÙÆ:#6ÖUj<ÉX/•ûœ¡ä$›3iîÏåq¿ÇÆ.ã³–ÁS©ñ zR%›{8¦éBó™Ë´½ïé ÞG²²ZN&Çл•–ð°Èb—޲x©}*<¹Ôíµd€¦¿¦0²™en?¡Ë ¬Ó×ÈîsÎÄ’¯šŸ§5¥ý~‡þb-TßìcÏQ!vÍa¹`ôV„‘5[‡éæî>•%ã BpÀºÌ¼M>Ø–™Læ%œ\à„`ćѓç‰ô3„íÖ¦òšµnhžª,±fHÊ;Td.¬/׃hñ> stream xœ¥ZQsÛ¸~wû#ô˜›±p €äô¡“8JÏS7Nmu:$´DÛl$Ñ!©xüï»ÀR„_o<{@p±»øv÷Ûe¾ÏÆg‰þÁß«íÙ÷³ï3nÖܯÕvönyöë Ï`…•IÉgËû3ûŸ•É,Ï2V¦³åöìM*~Yþ÷,ãŠeÏ—ë³7ï7_\-þ£Ÿ(É’<ÍñÉÕõß®Í~ÉJ©2\•LêÅ_or>ãKàD}à\ðŽÉgsQ²Âì\mÚ¾®6»=é—°iž*–Ú½W×·‹·WWz¯äLr¯Å—7›æ®«º|”•þÑS×®êõ¾«¿übÏû`ÎÁÐ<‘³9—¬V§v»­vkf„e,Â.´¶½±7c‚ ‰ëhˆHŠÜ9¡}2kœ²Hq­Þ™5ÁDYp\ûó¦îÍY)ø°—ßÞÝuõ¦ì‡ÎQ S¸óÃõÍâíÅoz—,W™{¾ºþ´ø8}ðÙ¸Ò¬', vüõkÔG™å…ñQ©ÌÎÛº6–”p9¹³îó½V2Æ•¸¦u³€b¹Tθ‹ß¾ž£ÉEîaóT=Ô¸š•~5σÏÜIæe}qeRŒl²b^™ ˆŠM³(DÓ4e%¬iÜ%uWõ5ÜÒk0º¸y{»øpyeœ+sÆw Þ7›zWm˜¹{4‡³S|ÓxŽ/†è;ÓkQLé­Ç¡+ƒÚ]™ù+ÿòf]oj™u\Êdâ5îêmkt3w?Œp–ÚeëÞFÄ’H¼òãÅHÁÒ°¨­Y5ˆðh÷ž# ÊpGÏÍÊ(À™ Qs6¥RŠ–ÝפðN›ˆŒØññâvhŸz¬wP)œ2+$†z8û^gФ·jv÷m·­\®Gy½h—"Ó2RI‹Ž‰?€X!É:j–&´tD‘¶ ý‘ŽFáè 7N2¥4-£¼¯W—~FnKh9Þÿ‚»DE›ÞTßÐ!$óY»Á%#iZÄ0%(ž²åhž'ºä!iimÏ‘µ»÷½=Ζn·ý mNÓ’vÜÕåíÒF'À.à¨V Mr/%Z,ÐCt¡I¦){ëË÷Ú ¨G©¼„j£m|™|¾Üe`*å„Ôì¼I |n†G´I†ÓÎ!˜‡Ês“$ÈÕ»ÿõÉl–Ðþ‡:jº^]!BQZ.Æ ƒË{ä`2Fu…ÈCàÕE’’ÜxÁ] „Ë \©uÆÉ¶™rmšÞRj¸A€s‘¢’w&.'EÄn"³ ø1›d“ÑiŽáÙ6VAd…¢‰Ì}¿G6˜éu/ûâ±Ú=¸ú^Ž495›ÚH4²1 Â×m—ýSص‚û¥Ž{@&ÃâÈP?¢­vhšQ|#Àyh´-XeˆKt°‚ÀОô@ªÝ÷7gS¡YŠjàÝ£ m4Si„ûéÛé™Í€ð&õËCžðç§)~Z`q®¢ šƒ;G™Õ´C*$ƒÄFÈs(À'> Ƭ3jYý¼ož•Áeúó¹šËË–)xè!ÌH†ëL“×1.—꾺î7‰0.*÷•LŽ&EHìþ¤èû…’Œò»fvºŸ·Ä~!JºAŠ>øSê¾}D# E¤“ñÈI¡@_nB6Î#MŸæI,ŸQ‘MyÄhøàÝ¡»ÞTƉD"bD"™ Eç–Ÿn.?.ÝD‘dyÏ"Rz­ŽE¤”åDíüÁÇH–ŠébG’å˜FHõ !ÉDù$P|J#F~™L–ÈÄH?{û þyo›(Éœ,O1Hj{ ÅÑäü›‡ƒÓnûø4ͼ¯§|Zpݯ‹1˜Vâ“<ƒ¦ Ï3€IAkÙnêÎèQ'<­¿ÿǹçp òµèwr o¤/B)§'¦Žô?A5FC¤‚T(ÛdèáÂ!É€½É”dŒåHÆh´w”d:: Ús‡$4à±4¦il, ` Å!Ë…0² ˆ~È2Fk„eøÑ?a’Ò,Ë€¨ÑÕC‘¨9¤¤ËŠ!4P ÿQmêIÇ4Ff`yfヌw|ßQ”‘Ù)iPhR þõ$Œ¼8I¢4ȳd䣶¬P9¢±Íðº<*Roê-Ž„õ …8Ö[ ™¬o:‹#“ýƒ¢‘¤1?ˆq‚뮩&TÀž®ÙîkøÒ8c_FÎp‹=$¬«úÄl”`:6&‚¶MÕ»Ï_í>ÚMŸrÑìu55â¾(so†æ4$ðÈØ4>Ü|¨»¿ãú­3røÝþOµ)¹g©òðŒIçD Ô½›†”ÅŽšôó1® Õä¹±ÿ¡`> stream xœÍZKoɾ+þ¬Ã,/»²uK–0–-]¬7~›„ÀçmOŸŠAÖ:?é¡Ý… Á^8rv7æd,º!^oL>÷°ëB|%á%’á\*°³ûasðïgvÊu|—)XúxsýËo·æ×Þ Zª[Ü8L/LÎõ®É¯X¾<]µË¥¿D‚•ÈMí>> *¡»?ü%äøÞ¨¼œ ÒÈKiÉ¿Ã@bØF!yK˜!Zä#cf€÷!(Âzï³#kQrÆÁ{sN‘ÙŽ!¦+›ká SÌBˆãW}-ÀNyh‡oÁ+\S.ÉQR2G©d¶(Ý®W1<‡§ßŽR–|w®8‡GØ|Ùc¿ˆgв» ¨¢BRõTͬm»ïùGM4äe:v±8¬¦08,<¸3:¿-eŒ³¤‘(f9å-7ÓÜÌ.µìHÌx¦³m¿EPæìÔ'òKÊSp:uEÄT¶)ß Ë‰äÕ„elš°h뻟?Þ…dœp]`S³`è#Ô§lk,.‚hÝ]ô©,5kýuºV½'27ùùŸ“­ßrRÑæTŒ…ð0lÚmô™€Œ‚/%˜úâ„9f½yÎ0púEJ”âñ‡€ œ¡«6º…ë©@Hžõ_8ÆÕÐ=.û!”K‘LùgR$…§•¢‹øšËåk.*|JÅü=„‚ÿr–‡.Z¡Ë=9äŒzîÄr#ÔTn-QF£üD·¥Ë¶}{ÓQ€x’9²ÿ†Ñ¦äíz[è³íjjè¾_ö>O¤ÆÈÇÇÈYQ"W/l]»]öªPkJâ“9PI ÄÔ×î2F”4öÁIqÇN²„ªì$T*P-ŽR¶*äÏ,8´Ò•¨gÎËÊ@–”Š*X´PF7äâ£q‚DJ7x5>rR'wPNÞ]Ͻ<ð/”ÈåŠÇK˜¾¬‡ ¦ ŽÉRBÌ`++ïC8·çqÈjE^úq{ûÕfÙ/úýò)VLËs€ƒâ!Aï>VaÈ=U!>ÚWÛZHSŠÀioµ_£¢`ì([3[«rÌzHñÔ(µêjþÈJP4[¹X®wÝôâ~™Ä Ajx¿ï‡oñ´sNR”©•qšÇï+“¿_ô k~éºr›çoKÊÈ„ÚÅÊ’)KÊ“ƒ]ÃÁ‡*cºK•)ØO7·~™ÿ~+2-¡Û´ßº˜3²ÜLm|(bú2ÖÄSŸ²ÀGðK)\õ£‹G«"éÿ–äÅÑÑooà?ïÃÙè¬0õøìäÆOœ :˸ú‡Àæ/ø×Í{ï r)»ämHŠÊe2p\pó#F-DxÄ›[Mg®Ò¸C •¾¢À³šCG PÕÊït]EÈ›7·|ÔxÃkß)üÆÛë·ï¯oÃÆq‡îì18üëÃÔÖ.ÖucÎãnH"Ð`½˜y’ó O¢®sqØn£àlHƒT~ð B…ÎÙêo‚0–›B—R’æ@Ý^ÆJ PåHÜY¡¦‘YÝjê8§(¥§©RBÖ”{Z§ÀéTC›’äc£DÍ(UÚ‘>I~7I5ÉUçBI]õC»$u8Ž$&œR»“pba§OÙã ´ eJàP·ûh¼ª^0tÿÝǨNŸŸ?ÜÍ/¾4="uû¹LUÎLYÏJÜo±£ä¸çsÞHúÈiÏ¢¦öÑŸzR,ŽñÖ±Ú3pn¦…*W mÉúÓ}l”Ö²èƒ îôÈÙ)Š9o±>¤ N’4Kî<SN¦½ ‰è¹Ï¯çnöƒº“ÐãMRÕÏ×­8ê†NæjSs+üD=Å££Ý¾Ýî£ h,6¿,´‚,–µ±,j O`mˆç GÊ9h9M«AC§ºÁZ]xɘ_üÏ®u'/»‡˜‚ž&qQ.ïz:JJô> Q +œRB¬º_IÐéÔÚJc0NšO)ûƒ¾Uða2©[,ß›R‚Ò!'ŠËÁ°BB‰Ô›‡Žó| Pz¨È…µÎ1  ´«HΤÆ4!´`2âÇh‘ÄI†µN§ e©äaõÇ‚R¸YY|9èòå ÝFVà%Ž~¸ŠÈ•MMÁh…bÐK3ÅŒ~Þʃdîè ŠA’ï>ÃX—á!x¦Hê†PµaÃduŽ_ –Šá|Q †E~‘®¹9òæD67x´ûR~qÚ¿ŒøÎó‹Ä-y†ž¼Ðÿ(:冻·gøEài]®¶‹‡È/Ø‚Ä/.­e©O§ùÅŽ'àgÒ´J/AY'¯"½¡ëô‚æÄ8ú®ØLéE>ûÉsôÂq8×âŒ~SBô¢ðÏ—SzÉ?Ÿ$v¡5v9þa/dS£œyÿô‚æNÂTçN£ÙIœ;ý»07ž˜]r¯eNªÌ/'xDX1â¤~þŒ9‹™’‚&œm;v}þ¿"$\•Oý³F2eÔ‹G2>×óÙ¯îÏÿŽýûendstream endobj 135 0 obj 2380 endobj 138 0 obj <> stream xœµXKsÛ6¾»ùºÕž±PâA€»üøY?" Ì\/¼?ùy/ú@ n kåMU½¿X·#X­  !¨k‡`~Ýøã8÷ì.µ“ˆ‘ÜÅô¾h‹²—­q_ ”a—:}ã  ®~RH›ÉP áq'!ž7Ú8‹Wµ¥T†ãg)‡dÒdJóé\2q4\Ñ‘! JƒÅ:X(ã!Xgó+JÆ~c£à~ªº=„KáyàtÌ80ø&Æ}¼˜Ï4å(CÀ[÷˜Ûj%ëb-ÍsìOá9êÔûçRŒRìÅìúxU}o‹öÅþDsÿÓ¦mJy³måõɸЛsx°a{‚ÇùÎð¾cò6¾3<ä;^[ µ”#ʱ‚†h{uuº”Š]ÊÃÆncˆ°Q–Õ;©©E«½Ò8L ¤%õ„“ÏUg7‰wµa' Ì•EmùG˜'r”-ìp¶œÚ\e$M‡äe;䲄 ÁpĘ]c>Á>Œdx×zG¹’rîq^è¡bç¸l×U]¬´ÉùtV–²ëFs$(Á*GTu29ò¯)‘ÚÈ—ñ¤(ÜåͧÙW§ÔªÎõÊ!©ö…ò5u¡\§bŒºà&äÿ¨›©øšº¹RZÌý¬Ör,Ù•j(4ùs#4¶^üRæ7P­ë»‘bÛ ³bŸTë ý’×ZŠhè‚nÛfm8 ìò *RxÑøF¬‘Uk–,Èz1"!‰“lìr&v.w=KH̪ۣ+¨ qµD)µ¢¿7Ç!ƒ#SþJ¨žÄÛêÑ¢#2Ÿ¯ÅÊ´AJ†"Ì ä4Êw¬Ýx¼ß/uV(–™—׽즀Ú%¼E4 òÿwÎ+Žxl­žœ>d™rDóÁæ,œª-¢i ‘,C²¹ ¾ol€V‹ÐyWxÔBmÛÚª=ÐXx·›ŸB»äib5=‰© J£ÅH™‚ÉZïCTq:© ê$¢+\cõ{ç³³O¶zãà쵑 ì«Ú˜+B±/úáÕ6âBÒW¶à1Äsªºë- i´4.0#Áªªå°ëò>D}£-ï8NðÁ´$PŽò̇rmÐa( O¸1e "ÁY/Œol庀gØÞ„‡^Ü7Ÿ<æªMy·©ãöí §·õÐ|_­ìÛ£pwÍÚµâQ;«°›[T3ÞÓ1[*/ð«V9<Ëq.‹7?l%DÒ2ƒÊ˜F¼>–蹆#*"@À_çWËë 6 ¾r.M.€Ôàð²/uõl _¤ýÍfŒl _¹Tíн€§N[ ¦:gn›öNÚJ ™^\|ÞeÝ z¼s…‹åûÅ LoÎÐÈP,k6(<õ>ýxzÂQñ¶’½ cd$wU¢æYòTõ¥ÕÞ,t÷²ö¶ãíN-™E s礆Í\Q2½k»Þ8 s‘ë Ñ´dr)hÂsM·ªê¬o¶Ì’ˆ ´eîk‰Gý§jµ’Õ“Ujx»_4·&!/}c„¦iô¬ë‘¡=¡mTQNò¸™¼’Ò2‹¬¾©Bü÷©­Ñ´)îL–¤*âÎcóYÊ$´»âÔ°NDzøÍ培™ƒIvøÞÄ4»_GT`S«åJm/Ÿû±Æcwb=ŸÏÎËÙ_K§âºû>_¾å3IÙ¬×PJ5œ)ˆ`(LçÊ“ΊŒ¡s#£sÈ(¢ž²l¥!¯L,=ÌqWº÷|UJ`TÉ_áջܶ]ÓÄÍ콚-Ï¿,®.õ ‘‚„)²ìÝ; ø¿Ú¸Cw§Áz¹ªvDOÔô¸Ó‘xx)¬êDŪêœtÂ0D_#JãNÆØiòg‡ãI34P{ðus=¯±Y¥õzÆEÔ¥»†ƒž]ß•å»ý¨YÍ—á¾Ò»`jZ˜¨gjÐÎ3‚j`ªžÔYQýýÁWXhUÃXz ÎTwÕÈ/¾Ÿýõ«ÛÍ&dB˜ï‡)³’·½+5AëËšèöÔn>ï{Æ£* ûÍ#žÁnª’¾™Ánî1ki:Ðó{Yt½íMRsÑ 3‰$zŸV„tž-'©ÿxrÅÿendstream endobj 139 0 obj 1965 endobj 142 0 obj <> stream xœ¥ZÛr¹ͳ6ÁGo•0˜[ÞÖ²“¨j×N,:›ª(#"'!9Ô\,ëïÓèq$k7å*» œ Ð}úô9=¾_$B.ûÿ]íÏîÏîÒ­…VûÅ»åÙÛÏ2…Q%•\,ïÎü rQ%‹"ME¥ËýÙ›Ëm}L÷ãò?gZ ¤9\´\Ÿ½Iÿd×d*TU*\»l÷{»šJ!³\ãêxhVõд÷“}t¼AvíB«D”zq¡+Qºõ¦w—"—ñÚ}ëÖ´i\ûj—2‘–p\2kw,ÒeC¸5¡Ç [ã+8T‘âbgîGÓþ° ïÇŸŽv)‡•*)p©í{,á.–B§*ü²Üú¨Ld2O_Axêƒ{v–ˆTÅXÖ»ÞíP)~ù]Û­LñT™ÎNvž©"§Ùïͺ©÷S1Nhç]sÀXV†æ°ÁwVU|g{‡ \çÙâò›ø”ÔL ÿ£]ª&1¹0ÆO‰DÇ3®Ü’Ъ’¸²­»zØê]ß~.ä¾Φàx‘öÕSwûØõmç/L'¸U¥°—åBù^~ù|ý鳿rŠp{¸TæáLí8ÇÁ‡ØF“b—J‘«* QÜ5ýà"Pˆ2e)= Ü*Q4ÔÍ£›æü±!s%$?fNÖ_‰HXšíRa÷ðÍo«¸Çzò²`‰¸{ž•ŒµXßâQÊŒN>XE^œ2‚*_—R(}‚hjY1^ú"Å:æØ%T´s•·ö5.†? d™¹þÁ¬ür%RzcIí Èt½ÃƒeU,‚~èêÃÆì‘˜5¶yöM `zX üÛ›a_w›æÐ¿†ƒ¯?,ùéó_®>^;ì+Á2òΘü ?9.d=Óm2Ëø‘–>­„bØŽcˆV‘Ähí}Z k`ì‡Ó ÜžVª™¡\_E2ÓàO›©*1Ïi5>xžÏhoíé Ùü{dLFksûïúóÐ dDtÝŸ ¢;¬¨B(#‰ôýÔ% È€Ÿc"g`\¡–s!ó‚÷œªCi!U¸Ú™ºÃÁ’8«ØXÿ±Té!ôE9­0©m)¬Â:W®2@7S»žH½Û!Dz»;x¶ç~{õ÷eV{Í…‚e´z‘ý¶¹CÑšÚ ÇׯÛSÑöp@¤2öŸV‹ XŸM´ ‘¦ÀtÍfVS:ªGwÎ Y¯VNy¸h[•‘‹0–ôD¨«æ¬Î×ÖT`¿ŸH¤)¯Êm¢#c\‡¾—QC3«æ+Èé#ŠÀœtîcÏ{ùŠ\-1"¾{ eLÜì 6ºŒTNM4î>˜‡Ð*áí¯ÒËHá QÂNìžPŠ%WJÏ -ReË3ìãæùvÜ5«fð¡È¤}Ô“V[Rÿköáê›ÝõP}O^!$¡û¡ñ…óDü^qâ¤ð‡åâïàn¡òmÔ0І@œBm– ‰íG`ß]½½úe1t£9{ûëBž½ý«ýëÝß.៫÷‹?œ}¸rOú->9µ® ÞÉUöÀCФTúc >îHHmPÕ1dGCÁ$ÜK°³ ‰°ó¯„¥e„1óÈáÅmì&$^£C⥃æOñF˜“qO±3¸—ÜpQ3€1õ íc"0 ÄT*Ï·bnÊêõiÏùÕˆðÀ¤y6ã÷e>+Øýߨ¿˜«ÇÓë^ôY^Å(ÁØü†ùÕ‹´L„žÊ_MeÓ™#¢„#§ U—'¦Æ™%fj‚S±›y­S[EiëÌ ãÀe‘N_HSÌ›Ín Aâj\œd6Œ&ÅæôóÐñ}’†:Dv-îÌ]šO›õÆ{Y`ÐRÅsÏÌÕóö)>CN‚fÎú[®ÍÌ\æ_±ÿüÛ±0gN"âX{=?ú*wÏP@çݯÌ@IHé,m‰01Ã`¾ «v÷º1$ìoùáŸËËO?c‹ÔvX6ÖÂlâdcjoëÕé7è¨IO°¾DFVÔµ^ÿÌÓÁ¨tÍ—ý’ͪS>¡ºyó+ˆoWÑ)´ŸBÇ>î),!ì$8¦îý§k,f6G„К6s *©ˆoVc ŒýÌgŽÙoý5W1õu( SX§¹´Myø¨’K}êõÓœl=TÔjbk '&xÓì 7a“Êz4úRàÒ6ûý1Ÿ~÷“Y{9OfLl?BÁ£Bd&€ÌyQÏîÙ9LaEƒgxÎ: ä%›Ï ÚPV'ÅåŽe_ß¾ôEˆ8›änöz‰ý˜Ó~úøþÓ—%²S² RÌwh¤´UȱƒEÙÌ$Rľšs9ñÍÚÜÕãn@õÀ+ЬzmQhê¨Ì„÷Õ·–Ï•eAè} Ϧ$%nÞŒ«Û]€»-eÅá2U˜oÆp:\žû ÛõàαK”–Iý12b‹[6Ø,Í÷2k?ã â×`FÈkƒgŸ~‰÷™íÛ5û&ÌË Qê'*}šöÿgôŠÀ* /ÉEqŽ…¦è õI9÷=Š%ÕÅ/ÔHZ¥Ö|²©Ç]ƒs^á¶‹¢Päã— Ù™[À4ƒ—GI%Š·'C¥Î'i¤ÙèzÎQçVY„Ø¡ Ú“ÕÞìî·¬ÏGЯü”,eж MoÒ £ƒÈ«¹ˆ”¿ytµ~+S}ñÚASôU¡DK»G^¢M§Ð;¼ÇO–€C‹…4E ûìãžÙ ëJs³„.Žì·4ú”7ãGÁò5¼ø­™~±ôϱÖrÒ% —° °‰ôÖ‡ò–Dò™q³Ð¡Æ0¶+Â⺫‘g4IɜٙäÙŸ†1H9lÄQéÜL:å!N¨3¾„ d¥Ãw“ïŸ9WÀ¾z •ƒ¡ÿÂ2o¡dè åF±öÏÿ !¿4endstream endobj 143 0 obj 2810 endobj 146 0 obj <> stream xœ5‹= Ã0 Dwý é¢ZþÐ0 Z:§t(xðÿ_§.7¼w×Уë½WhÐOö¯½âlpÝXBê”ÑÞð;0ªÃ$BêÑ*L>_쑲æÃÛ ¦¹l÷²”g71K> ³¬·õÜÒeÐ@¡Ãbø€ž/"í"°endstream endobj 147 0 obj 125 endobj 150 0 obj <> stream xœµXKsÛ6¾«ý:Ú‰àI¹µ‰3ãCœÆ‘§]‰¶ØJ¤,R‰3Óß°@‘–“6<³‚öùí·»z˜R¦Ôüáÿåvò0y˜2+ëþ-·Óßf“—7L€„hªÙtv7q_`SM§™Dóél;9{½^ìÚb>ûs"9‘T¤ðh¶šœÉWFÆá:ç(ûu_¶ëmÑ–Kó™HaÃϸ6²—7\NYF8SÒM$§$ÏÄ4‘šäN±Õ«‰ ZêÇÓ)“DÈ”[ÝãD¤$ãN aæ)ÏIšÒ Õ\¶ÅÞé×´Üïwö1#*eÅ~Ñ–uÕ8‹„J!WÎ"K Ó,fDJû¾9lÝSÑË*xOžî¢ûxûÎÚâ$7a;[ÕaëÝ© Rn¤‰Ç8$>1Ù¶ͽžãotzè¼C)!d~n2Ȱä*2:îå [.FD®Ù‘Ác„%JœCÖ¦wi«íîÐÚ, @@îñÕ® «òG}¢0ÉJ„õ}èT‰¥Si섇eeL‘ñŠr•ÀtmUþTì‹jYœ¬«{ûæêíÛË›Ëë×—]P]£ø›ª«Mu¶&Ñ4?ñä‡eZ2HËq¦¡™ñƒƒW”Дåý| ’e9;Êwêbä,ªÔ[|WVXÛ44Á¡«˜¾ŒMy_aÁóˆm±p})$I¹ïâ²úùÑ>VÀ(©x>ôBʼÅÅe,xñ©¼?ÔνDhIr)¢¶XÖ:®¹¦-]FxF²Ü»8?û².ìs`XA½|·/–ŪXÙTµ@!:ÛÖm’I_ó¯Öš Ä‹FÝÃ5íb[ÖÛݦh Ô˜Å#Xkà¶ùù…E+ÞóºÕ>µ.Š™T¾Â¿4$«l†²o …c„Ò9Ôì®x\;LãÃÊšH¤"‹Éñ®Þlj"™T]_Œ(#*dÒ9 µÎ¢Zç&ŒÔTõd4仂Qa%3M=Ì€¬‹Q¬´æbÓÔ8v² }wu}û9xHR@,JôHjë@ ªEgñÐŒQÄ àWñ4²Ö°“xª"nr`GiÈí8R´!3¯ž  ²×>ªâFðçÎ=)<‚žÇv ü Hõ€“Œè>'ÔI¼OQWCJâ$S¾l’ ÆÒ'òP-ö?ø/´; ö \ž4VÞaƒ°@µ]®4¡áËÐuŸKä(i`æ»®­ÿB½:õÏÙå æcT_ìhhòR;r¸hÝOâÂ#!˜=ªÞcjXæîdfÉZG¿ß±« )Ø-öN H¡Ã!3MÙ\`qó¯1[žÏt4ÅF¢?â3@ÒóÔ 3Hò™€²æÇ|°â€GTÖ½¨Ì§iÕ ¡1.ó+päaox”co yšÒfk˜©C\cþ`£Ð3äÊÞH–98x<’{}ü©¬Veu+"+bÓ‚–ûvmÕp¢u¿4P¬4D^´Ž5`T1=Ìc÷ á¦áÔ Ã|lµêD<¨†Új;æò]½ß6¯Æè9ö‚]AÇ„ù? „® ¨YÃ%~Q=MIèÛ /™Ÿ‰²[üᦠ:MúßáÊÌì<íÀü,óóò‰©kåvêAí]Sv£3Êÿê°lÇ›B‹SÍã¹÷ûÍû7·¯gèH6ÓÓT’I£!ê‘y¬ÊÜiaÝù—ÇXô6:Æ &fÅzîûet<ÿOÇÁœÂi¸°P«4,á§O4š C@Ó<†ÁánK×±23C/îÍA÷YnßÏ®.¯¿»xI++·»M„„ž6¨W`5ø²“?WÈ—?²¾C!U¨Y”FaÖ„ðÚ1Z6¶hq6X´ìŠ1RIoÎÍž›<†Íuá›Ù¸¿6ºq“›À«-î‹}ƒÃMêpuà Î^-v$,,ì96ê,žùn½ƒNƒ@R¯Òí4Nf]m¾º1m ¯âk§ÓÅÔ Ê"¾è?—«Âi‡Q+v™Œî`œ–ÑèÚb\!£‡M[•‰Ë]ôã –¨·È=éTSï "5êÀùÙU·$‹°¸Ö eíBùØBäW¾•Û?ÜØ•±û∰B¨á„m?›ÊS©Â7Û–”1O‰UÝb:¢“‡_ Õø"=ŒÓ™4°Ó2æ §ùLùd4 µGwß‹°#£‹vCãG±ª ±ŠõËÃùõwGÁ¿ˆGwϪâ§pΈñ[(â’}y¿ÆÔÊÀ¨¸þñh%l×°V∀§0ïþ(ÝVéHÙ_ìØi‘Š4lºmöO†ýÜ%åWO\¡Ddæ·ï¸™û2üFçÎSh±,qCûÑpï,LýØÏ¤B ò×›ëáD¾œM?LÌß?¦)­endstream endobj 151 0 obj 1820 endobj 154 0 obj <> stream xœíWMoÛF½ëWðè Öf¿¸ÜEO ,F+Q´ra,Zf!‘6)9é¿ïìwWáʶڢ‡" ÃáîÌ›÷f†F$Ãúçþßl'“‡ŒÛðïf›½YN^/ RX‘ly;±/Lá¬` )š-·“3†_-ÿ˜0"Tž/W“³7³Åϳ«Ùïú‰È.háž\ÍßÎŽT.˜³æ(ׯ׋‚d„! 7ê §œpM‘M¹BÒxvÕ¶¬›UÕYv •à5¥Q뼘½ûéòúb¶ÐÎy'C„Í~K´^Lð`¥öàÃ̧J¡¼$›B@îðv¿»ßïzíÎLÊ„;dwWi#Qó‚:ãAÜ9A‚úPÚÆ¸çˆçrp_ÕõªnÖ©,9E$÷€‰|2  CbŸÍµ¨àŠ8ËŸ©£!K©°x J‘RþèM‘‘¤ Ëø6¸Px³ÝÝ9P ô!Ë­6É8ª}¿3nñ€]â¸Ê¾™ãpiݸӘôÐîªuÕõ–ŸHæ»/;{”?¼ÂnÇÖG‹-“áõjun‚ƒj‰ª1SŒ÷Á9q͘—‘@æ©Üò°ý1:&‘ˆ¥ˆD$“‡Få…J]x,ûùX{_îÚ¾Ì"¤ü¹o7ûyN0ßá–$ð´Üì+^Âój£ðûɦìÖ•m4LS%ðçåoª¾w MĶr–Ñ@†¶ãV=ì-ǨîbþØ]{b›;.ß-Óxµ·¶r`=èjá>‰ý}¦šGšƒsŒšC×îm‡}vuž¼¾p…  Çšk¯ô†f åh ¤ÑTe7”¾@¿°ô ÙD¨JÔ(jÐOaV(P!þ¡KöÏo!ûåÃb™Ü\ÒˆQÛÞþ6b=µ«†w­S[ÄÔv7FƲŒÀ4b~Fg˜íT·’Ð/ê›aX‡|MS¨Àa]yj› øÛ‹wŸ¶iªu¹«ÝÂ&óÐÉÓ5eÐ XNãšÞ»5š¨ÇÃ^¯à;Ï·k‡$Ã>òô‡'\“˜Ålx?ÿÕ~wŽtÊz[@xŸfÉ(ŒÖ<±€æayB4£…á@DG—P(ah¼÷‰ÓöAL=¨çv¸fäf2D¼¼ouÉo7b#n¹D NaÍ 4Ò5â̳îÜ9 CÒ¸c‹^rSß €ŽÍüHüP42´ÈQ„2-#ž Õ×û'›œõšýöþ_Ü#²&¾>ÁT„¥þKÅ& œÂ#ÿC*SϼO¯Æ·œ64LòÐEÂÐùgU†êޛ˸WmÚ5Á/@Wó·Öñ?šÙ7ívk¿‘9­øÁ—lºæZ®?]Ã'õ0txjJŽèÙ2û0Ñ¿¿*–Ћendstream endobj 155 0 obj 1286 endobj 158 0 obj <> stream xœíXMoÛF½ëWðèÑz¿—Û›ë¦@€¶Fd½øÂHk‰­DÊ$•ØÍŸïì—¤D˪ ´Aè a4»3óÞÌÛ%ŒH‚í'|/¶“‡ÉCBœ­ýZl“æ“Ëa`Ak’Ìï'~I4NcHÓd¾\\¯³]cª7óß'œ"Ž™§ùrrÁ¿·6ÂÕ) ¶«*oÖ[Óä û“EÂŒXÛå °CTtÊ)F©bÉ”k”:ÇMáÙ ;šÂßS*õ^?ÿêÂ+DX _ì·~é°°)ƒßÖkJ$ç\î›Ý¾©]¢:…5k㶆€ [g;Ê6Î;E¸óÞ”«ÌUíÒHa’†¿Ê{·EŒ¥äÔæy™ Qxˆ¦HRH*$sŸ…Ïí{¥PZ ´4«Ê˜z$‰¤#Âô ˆ 1g¥)-Ù!\Džr¿'ˆ€ðÖÅ"H+.‚ýóÚwlË™äÁº¶&‹¶ÆmR¹ß” ` Ôd8#GZÆH¦6Ù9zP!M©#W­qb( "ïSeË3¹™]ýèá²¥ÂyVŒÓ#J­§¥‡óoôD´^¦GQç¿(ësȹ¾¹}ý༊H,pÃ(T¡=Í N=æf°Á×::Vêís\žIÌN`è_œÿ!C§§ç˜¡¬Z4ÙYêv5»ž_¨[8§­uj#ú%wýE)éx e³T·™?ݽeYÁoAÕó‘G,+ ] “/qåä‘î(÷ÜA4ÁQµjxØ÷oCõBC>ƒV!–rÐ*ñƒVA¡U4‹ðý— ×*ʶJKwãQJ#<Ÿ­E!Á£¥´–  7íñi2ò"Fçâ%Ät?1¸ÝI¤8ís=63O—.ʲX[~ïçîn„õûA#Æ5'F£(‹?MUzâªã¡ ×VÞykÜÒÐ]e£ífæ‹w„+ƽ£a€a0¦XæÅÊ¡Èû§eY´Ú O_ ë|U„cˆ>­Ÿ\H¥vx½É•-~¤çaIO`i— f„>òó•´¼›{Wy®‹Ö:‹Á: uWúßЋîñJëÿT/‚ Ó‹½ _«\ìòKz~T0¢+tíùþ²d¤âX2hïä’!»FèI† ñ.1öú%ƒKùOxŠïꎒ¡}gлzÍ}ò&í’7»ÊÔu^Ž ‡€’TÌ•~w Š#*cûâc ã0Ôá…­¡ºô¸Ø‚Û–0~<`ûx;Û×féÖòþ³USvÑÖ¹2M`®÷l5Jç''Š ~±Šl³o‘Ó§Ï„]þŒ`sh{՛׿á©~û 9vÕûªÜk¯åB݃W3w›üc•U®õ÷8b»ª\˜å¾2Ïè4a‘Ðn缘È|’^oòº…œœFm”¯Ú)R0QÝÍÊT>ºÕç8ª¸ÂŠê§YmÕÁqóK ’¨.üH»ÌoZ¡Ã¸—Òb³¯óO­wjeíïæÉ‡‰ýüHµfendstream endobj 159 0 obj 1160 endobj 162 0 obj <> stream xœíVKoÛF¾ ù<:@µÙ÷H+$›CÝÈ–éCä ÈtÂB-RJÑßÙåîrm2ŠŠ:ÎÎó›of—aD2lþµ™ì&»Œ8Yø[m²—ÅäÙ‚0 ƒ ÉŠÛI÷€dgŠ1dhVl&gŒ>-þ˜0"‘6¾7“³—ùâ·ü<k¿H°¢Ê9Ÿ¿ž;}ŒÌKVølÁî9œ2m·Snvš3«G‚/Ä?n?×Z)ÕH2ɽ´jËÝPʆϕM5FX`M C¸sõ®SVˆ0M½2÷ïŽïÅФj©Î!̹¡ÿDBjøœ ê<½SÃ|F"Ég$kö¡k˜"™­tÌ5 ¼2—4ͪ5>臅$ 4*íj½¸Ê/‡ÉÝ6õÆK‰Ò}=ÌcU¶{‡+‹ úþl]}l–Í_öÔž™Ä»¦^•7‡¦|ÿ´ ð>Ö§D1¤¥úI_¿ú°¿;ì[«Í ¢˜IojéâÁˆÓXžuÕºpˆ±‘˜×·NÆR:h¾š_¿)œMbäåî°\¯]ÜLèEgíÝâvr‰8á²循·ËµϘéÖ%Ñ\U GZÄ ~t³Š¸48<,—,Ѭ:¦çR…ÎMŒ—9+;ÔJ Åè ]øPTßÌùïN!nb™–[—3¥ˆ÷±óŸÖ9`Sžoµ]­mõÅsì¨D£Tô:,é÷ɓٜJ5a´’92.2aL:¬#äßĈŸŽ;¡2Z+…*¨&“32Ǽ·™*ŽÙä½ÍĽèˆhmÛš¶à_©Ÿø®úe5V“ §dÔžðˆÌ­ŒKÚÑfˆ`šM`I†’†ldœ‘7‡MÙT+¿ˆƒ~Ñ”7Õj¹/ÛQB5Æ |M9u]—m{w”Ty·jó«« Ï‰TF‡ÛÆ « RõTR°Gî-Bkhö(CôȃçÃ>RÀÉ–#GI™Á #O±Àe¡"®sÏÉÔDYå8Ù Ã4 ½®:ƒðˆ/Ÿ4¥,J¯¶àÞ'eúÅSµ~'èžÂÚ=`ï9]!&"%ÙŽúÈŒ‰¦÷Ÿ—aŠt4ûذŽDØ–«z{ƒFD¤!t\ÉŸšÐÖG_˯ù‹"_\øõ)’¥Ò÷2 .6ß^v&(ò¶f²u H¿ü’ï­¿’$,±a£áÅ’¡ÈžK¸îR9 M–GòËëçOÀÚÚ=‰L,ÁÛ£á+9k³GY;JM?—È×!§ž²µù/B*0g$¹´GQS7þŠå$Fê@ Ø_±þT¿§úýfbR=$°Óqç™§‡že’vôX¹ XR{³GÙóPþ ŸýoЗҖBƒ¶"io" ÔaÀ4¯o°^^d—ûû'ó€endstream endobj 163 0 obj 1083 endobj 166 0 obj <> stream xœ½YÛŽã6}wòÆ‹ÁŽñ¢[ò4É&@€LfÓh ûÐ/›íVÖ–<’œÎùø-’E²hÉÝXÌCd™¬Ë©S§Ê×ãëÌüÿÛãêãêãšÛgþÏö¸þúvõÅ —ð„ÕYÍ×·÷+÷¾®³u)%«Åúö¸zõÍCsšôðúö—•Le²€—nw«WêKóŒK&êJà³·C;=õÔnÍg²È/9~&¥y—k®˜T…0—n”ÈXUÊõFÕ¬r3û¦¨XQd%~û¦évýјG5SežåøH£»ì›3pÚ^ÏeÉ$çp}Á wÿ®úâF&“ªõFL¸7oÞþø¯÷ïlh2–qå/ëœQÿtc¢d?¹£ßÉYY„pŽS3LèŠ(råíîvw¯1p‰-›Z²JÀÿ7Ñ'UûÓ¼ª3ÿ(ʼZG÷û®Óûfj5ŸåœU9DýqÇpH@L1Ï*VÊŠûg“Þ;̉’•UˆÆA#ú’×ÁÁé¡éÐí*ºÝ:/xy-å’ÛE4ùñÁAVp¦d᯳Á„˜óªö(>¢­ªæ>”çqrÙæ!ð fÛâ°`ª¨޵û¾$alÜ£š<:Í¿Ø-Ôd7–ã…xA@™µ3/Y ŸPàüìÑ&qµqr(Ã0™'%ËUxÒ»«*b©ñè‚\0!¡Ÿ›r]œ¬Y¡äEdèásæÕ†§AT0HµÏê~Ð 2ØG®#8ây,Ÿy.ËÏéçæ€$ãOžl4¸0ñáP›!/¡ú>f€S N0CÊ™Œ… ~#ò… çøz€L‹ƒå™‚I¹à`bÁ9÷£dU¼ÔÛÞÙeX‹fœ`XfuÌô×=â (TIQŽø¶Š§ZKK Œ A¸Ve§•W‚H•”Œc°eLZ¹”IH—ÍdV=cÅDö¬ý)KT׋ԗóÀ[sEu‘+¶Ô× ”Hc¿Þ£2{*7vyêåՕ©‘H«ø  ‡t¦ Øt‡¶×Ä!ŒœÃè¥'©¹ÖŸy¶h³©·ðݯ–Ž/XI×õ@Éy ª— 4È/UVøDëº;ÅÝëÊ%ë…0×ßË®(, Bœ¿ –~ÆréæÛhVÖÖTÿü+èg\…𵾦˜Jø¿² :4¾m<6Xæœ\ø|×ü) ¡Úµ²0͈äk,¶Açr¨’X\ý=z’ËuÒáÝȃ> ½ïøQîÎÛöÃA3ÌS&ƒÍï‡]Û5C{ø„M–Ë ¼ÍWºÛÚO”áäp”³êPÒþDDg‚h^{eBvG Vç×9eΈ<±‘âØµŸéÁábšEi:Í5¥n¶x9Œ>{X•<Ú8µG&¬úC¿ï}WŒel1ùçQï|Ÿ+cýþ~n¾Ë‰åtŸ“þl_+Lú×:À/¶ÈrÎèiö4¾¢ä‘S™/æT”žF}Þõ›˜Ù2§ æ/g¶€ëHeœP–=dÙΡX"SÒñfáT¶g(Õ³¨ö—¤×N8ïQI•Qÿ5¡-‡3¡ÎöCs|3Ùˆs$²áSÄ[¶„¦ HR q 3Ð}?xÔU±®1ÇvŽà²¢J« ÈÑyK’æ×”…ü·0œõÝ\qõ ¸uŽy†ÌE(;y2<„ü:Ȱ'JûèÃr}Aͦª¼óQ¨g±Õ]Zgá£ý¾P\ÖN3œ'úkÉ­³,5bï57‚26¬<ÈlE÷7ОãÑ©©Ó”Vŧ؃˜85[ãGÆ™*‹dmé'âd¥kÍ .% Úõ~ÒU‘1;‚øóÄÖVþ=î8Œâq=‡žH¼~t΂ŠQ;!©p³Çãד S‚@eàün’ xnÌ‹ð„§W‘²`2¸ï^û6T–á aŸ+iCl¦È|qÔ8…p DHfmô U¡Ø/iùÛzd×ÍÐl'¿2QÐöb›o»íá¼ó1!&ú7ø–Ãìló,àž¤3ÎÄ1o×îqÁkX/*˜æW{nP¾ÔÏÉöj·Ýþ j=#vÌ5[$Fbó„Þ¡.š1‚ý¦x‰§ œ_ª–6(Ù¼‚›~óG÷¸¦LQ"-ßc{p»¿d™~}•”m…Ff¡4œUµÎòÉpºŽPòÆ×Ì®>ø·[¤Ê]çanò߈ ¦IYÐÖôÖÿÇòÝÛ™a0ÎMç»%yœ\4Ý-jü»WKWæwƒ ?ÐŒ7±Êj;6ÓbÑ&›W€ÒTmð‰$šóè+}Ñ}]¦ ÂxË໡o¼d‘ ûÄR¶Õ³Ù¾ŒYzó•¾™®e›í„ÃÆæ]Ö05+‘¬Ó÷h¼ˆ`Áa1Ù~-îL¿ÁúγÀWÂvMð¨žL!ùùlaæ]2¸9ÜS˜Wë`Èãb0;8C†¤ðÈdú·9¿¤¿fŠ\‘àbC›uŽsHºª@±“ýí÷¿gÕlIv¶æéïÖmÊDžt4íÔÉŒHájÁiE ~"ŽÜ,uBæ?ï|{“%-¹‡Ÿä—™¸°)É(j¡}×(g":Ͳ¥¥˜Mã’©¨FhÝ)sãŸcÙtýA…I°… CCzï­ó T‰Œ®ëh%9YGØCyB&èZÛìœd•f ùiæy­ õïe¿œqä­èñÐvz³sûˆc…>` ›¨NªÝõúoo×?­Ì¿ÿ=Ûãendstream endobj 167 0 obj 2467 endobj 170 0 obj <> stream xœÝ—[oÛ6Çß}=¶@Íñ~yl:o ÔX¢ Ö=8®bkð%±•¦Û§ßáE¤,ɱÝ{Á0pDòÜ~мË0"¶OøŸ.wƒ»Œ8[ý7]fgùàûKÂÀ‚ 6$Ëo~É ÎcÈÐ,_ž0þ4ÿ{ÀˆDÚhxŸ¿<9]þ2ºýaßH°¢*¼¹ÿ4vã2B²`HX#8”áˆqI­Ã!' ܨlÈ Òn$÷#©FRâzѳ²rF‚¤æ&ÊmE2†¤]+D´0Â>†ë²š¬ÞøÑl§B–ΆT"êGžçÏ_þ`GÚÙ„‹àqu¿$uLòd¥Ö:”`àhñ+½n®%‚iݵé¬ÕñÀºV„Ðë§¡þ;é !bă@ %7v}_ÝÞW®T z¢cÕÜU›@°ª+{íC¨í"k5†2¤RÀ!7ˆŒê8t}¦s¡i°•Þ;¬´ŠÆ•ê™ K"ŽcXór:ÎSÆsk2HA—ëKkÒHqC‚å~[…Œ(ŽŽ®ÒˆKé+üL¦Óbå*¬Æ4©5Q³b³E®ÁT?W×Ðà«Â×ÏØükoBUþòY)ÄTäçv2ó%„ö˜¨"æ¤úá&V õCM@BªªîÓzs$ÐãK‡?’gè?†B´yöK"ä§á ÈJÌ?Î>5 », Ц™%[¢™&?ßÍzæñ¥g™‚™Fv>˜eÌ DÊQªãýîϼÆùÕéîÝŸëµþûóèUÍ)‰ yqñÛÕùï#ûBP@ :ûæè7ïO?ƒfqI¾.üWëê8ü_Žó^ü{q i;ª‘ê'ã-kxC! µŠ™}™ t²ªO,&…½«°§*ƒ Ó e÷CeŠ€êc @Mª&Ûyyó8Uáðüêçóû±zdWíЦí±›=´µƒW”w6Ýö¢dãÚ1Ù”Õ|YTåtè’+Ü¡^ƒž¯]Íìø±f5Ûa[±(|uÀ ûUÚj>笣_ª„¯tÒïâhý^||ýv'=òÅøùr[µXÏÊédÑÔ.Ü«XßÑ$5´KÄéÚeÜ`q V¤‰²¤]nkwGi—Ѷvw§Ð.±P¼ÿ›uТIÖï ú¨'‡eËÉ‘í(Ï~Øç?kUˆ%endstream endobj 171 0 obj 1093 endobj 174 0 obj <> stream xœÕY[oÔF~ú#V} ;ÌÍ;ˆJ)¤*…6,áÁÝu·Yoð:ö×÷ÌýøšEªªV< ÍŸ™9—ï|ßäÓ‚¶ úŸû½=útôiÁÌšÿo½]|¿:zrάœæl±º<²°ENJ’óÅj{tüüº¸mËæÑê÷#ɉ¤"£Õæè89ÑkLžgÜ­½Ú]UëâFÿ I£ñ›[c,I®2æÖʦh«]½7ÖŒ“Žc‰^{rÎå‚)ÂY"õù–’S¢òt±”9ÉìŒ×œš'Ã#¤)ai*;Gà QYªFŽðä\±\‡B<ÌvŒ1ÂS±XŠŒdv¿¢ÞXSщƒÅ’§„[³Ó×/Ì^¾SþRí%[äzq)áXJ&‹¥>€urÜd$ásn`Q¥hQ - !ìºÙ‡ëR8ÜÃØîîÚÛ»ÖGÂoiÈæêÜÄ=!‰ ©wf6£„'a­º4vŒP²^ܘÜ0 k¿‘Dè@8ã¦tFÆã»?6Û "¢á®½.›ÏÕÞø€š‘)ËÜO?襄d©N¶]:}õöŒ˜#ÀѲÄÇûÔ7ƒ†xð¼[½”%sæMïö­»ÏÂ÷¿™ò„åÔïc •Œ>Åe0/%¬*.L½¸d5®ÃdŒ¿åÅñóÝö¶hªý®¶­ãojn ÝI£Ûu±/—U½/ë}ÕV÷Æ^kÔÝ%ã9õoÊ«¢ÙÜ”{ã/a$eáL»K‡$‰{@ê\ز¶{{1 Õtgì¸$T¥bÆáóÓ·g/|ýæüìÅ/&K™-}×6ªÐjœwºpu]˜üq€³¸Aµ<†:úñ´mcÏÖï4À‰<‰gmF= ÀƒpöÕ?çéÜм'ßvIb7ùÆMðbLªî}±-ÊÀ ,´ÇiíÜ ‘uZÉDX7h(ÈuQ;ó –…N§>Ž8½8¡©OÜçI¼'ïí è~7܇$Gi+O"%b­è.)lùPܹ‚‚ " ©6~<ñÁ€ƒàÄ nªûÊ#!0cöxB% ÿ"Ù_¥B¸sa×’e‹b°;‚‹oš:"~äÍ£¶býv $‹½yYÜì¢qàM¹¸¤Þ–#ýfO[Ÿ Ø’4ì~åQ)Ë#'õ®ˆÍb_k©”(¡E”šá2}õÆŽ…Qf^fpñDve–õr¸Xë/~Ê¢‰æø“*K¢² 9é@eQ@£>;`82®—PZäkŒ¬Ì©.˜~rBuËÎS]àyLu!4í@¯S]¡Å"ÿHcV¦T—¥òÀ°wyP=¦:pIÍ^SÂú´ì’$é)/ŠS}˜òÊ4ÀN)/ d·¯¼:ê.b¢n3ÊËPÑwÈÙ×(¯T÷DdzŽ€B»*=Û;4z\xéð°ðêh¸ ¹ÔГÂëë=M ¯Ž§øÞÀ7¾˜p;cú /p‘÷…WŽi[è}AñK€^ ªùAą́¯ØÂ,‹S; /ý™D܉ݛΠ¯ØJAx¹Ì{«[ɶƒ¬S¨ˆæt´-2`D&²¦š^Lè.-Û×]t—Ôï™Ý%qIÌùžÖ]çô@Ý•jý#z)±AgûD\{à* »ç÷‚öº >.¼²±XyáJ348ñ°îBÜé.¤•‘îBç9Go¡³ºËàå êÐ׳º+³ßqî?¬¥!§ˆ2ÌË®L 1ÇTâÙ¥„ô‘ìÈ.®þ‡²ëåCÞ9ÆEOÞ?£&Viõa¿˜¾ÙÕWd Óÿ®5ƒøhQé`{C ‘¢B–¥üßU=úÄ.ó¨ÐÌñ±#ST´£ž‘¢Iò\o*ïWªN5ŒÈšmÙ:Q}¯ÅþˆšÔÿÉU椰‘ÆÊ+òžÐ-‘ZŠ‹n‹…Ðüà0EÁâ(>8qQ?hžß×ôLb‹14|íþÈ<€Çv_­=ݤƒg!\Ïe³/ˆêŒ§«kÿ9;~Žà(P—[! ¶²ãWô)ŽE\ÂoÏlðöÌñ«Ù cp¡%zæ‰[‡Ä‡:c<ûø<|4Lé‘ ?äˆQ¤:!èñ=d¢ÇgŦŸ‘ï¹Çg$ z|FÀã&çp Í´XŸuþð Ÿõ90 Åb3.´LAŸ­¿éÝõkendstream endobj 175 0 obj 2087 endobj 178 0 obj <> stream xœ5‹± Ã0 Dw}…ÆtQ­ÙÑ0 Z:§t(xðÿ/S—Þ»«ˆ1´ôÞ T¨È'û×^pv¸n,! Æèoø-`!Ñ /þáH“M‡÷ sÞîyÉÏf¢RHcêfYoë¹W2Ò©’6˜Ðò"›"¯endstream endobj 179 0 obj 125 endobj 182 0 obj <> stream xœ½ZÛŽÛF}ŸÍGèmÀ¢ûÆ[ü;›MÍ^Œ’…'ªgĵ$Ê$ee°?¿ÕìꮢH]`aÀ6¨f_ªN:UÍ+‘È•pðßzóñæãJŽÏÂ?õ~õæöæÕ;©áIRŠR®nnü rUŠU®uRªÕíþæÅÛmul÷õí¿nŒJŒÐ ºÝܼȾqϤNTY(|öç®:n›ºw¿è,Md©ñ»g¯Þ)³’y¢djÜ’k£DR”fµ6eRøiÇYËD‹2]˜õrÓkãFš|µVebÆáol÷Á U*‘ifp»³Oø4Óñé_ÚÇv|š'ZƧÇn|(ÓĘ<œàS³±ãT‘H“†±CWmš¡iÕÎý˜Â~²g'Nݰ³£…D’ç&œò‘Òè$-UŽ¿œ›a;Γ&*ÏÂ~ÚÃ8 Ðq“~òÄÛ?‘YÜËϧÝÐýºö(ãìðÊÚ=]©’²HWkçSÿÓÎö/ƒÑT<òæéPí›7jЏˆ_Ý¿¢ÁË:.R6¸Ù\å-u»Û5=˜nœI‚#e–°ƒ­‡ðS–*þTuã!ElªC;Œ €m|ØŸŽGÜ}Y’ݺÁn¼…1ÚÿvÛx÷šÄ@ü3\ª ޹µ¸˜¦Åöm?nAepîøú¶ê6çñ1 3‹„3›ëDdŠÙ|cx<ÅÉíac¥Ô¤aËã‚¥†>VÝ€§ +ãœ*)d<…Cçk„¡!çöíÞâJ9íÁVà\ç)‚Ͼ§6‰Ô‘Æ@ƒ€V¥[µ¿7dZÍ;-ÍãÆØ2:¾ªÉÃáá¶9ĘLEœõþ4 ÚÀ†ú"e’“a[ðe×{48wF(ÿÕ~B‰Âdôðe;x pînà½\”Ø(“”°ñØzrP:`‰›¯zÜ¥2qè½{”VÈ¥]”NSíÜìûê®]#Xï Í0Âx‰H(hßã™ò”‚·Ÿ¯uœï«ºGfsÁmù™÷ƒéÚ¾oàý—茔6ÐUÎMãs FCvØVt„l„QW‹ÙÉȸæ€ö1I™Mí.fy8íÀ»RDJ$Zm>dIFyÁoAJ~º¡z´s‡Ç(4)Œ\ˆ«®ŽÕ}³ƒ´âÑæ‰tùîb3£Ã$™ è@êY|÷j%EºˆQôãM˜çä6 —¦>íªntS îP—¨Ê’2g®†ÁîÃxŒµ.®2KÑO)Y¯¯+#˜J³LCKP¼ôu‡ñ®* }˜7ã¶®†¹W&ù˜«n‰ù#]t›æP ÈƒŽ‹cZzÿo)‘åJ÷ô7|œÓYB>”Na„Ù߇4O!q‚ñiØõWÅTF S=ÏU£ÑÂË\j¬u)“¼(Y윛æ%¥ r~‰Kš2NOçP‚|l¯J¶hû”Ò ¡¿ ØVý£L² X˜™Ú^hZTF%s¶LžüFŽ_ËT””pÜ B3¿¢¶Ñš)(„áUAŒGx{Ö9ljÂS‰ÐLá-[¨)øï^œ·^zÁ™gaèÖÓXÎhþjf.5¡m¤Í3ɽJª‹ ¡¥ 懥Èfb*M> ¹¡é"C’ˆöaïS…I )z"Ÿ"Ç lí { š¬\UÀ»F(·$ÁúÔÛÍÝ×(ûr1&‹ kåÀ®EB,‡ÃÕUÄÚWû^Ì3‚ø-AC”E÷Ž“¬ iæ x+å>€† ÷kŠ)Ÿ;Pˆþ¢œ…ÃÄ ]ó¸E‹2Á=¼Æ)s"±E±ðì¶!]Æmÿ“¶-ŸÙ÷éè Â8â)OR?ØÊÈn–ä¤~ï€A,xo¨K™lŠ… óÀÞV=é ª,IÛÃ܉û8ïQR•¤Dê]Ì›L6Œ“‚˜çüpnz‹8dªû¡k÷hºT.qJû]Òy¦Ï¸é=A˜‰é%UÜR…@‚ÉméŽê/'ƨÖlþEøPðú”#Ó çÈ Vkî÷XM‚&¤ÐÙ;i 5µ—èÙxß ìÀb~<:¤…‚иL\þe¨>™‘£xc9Úc*U€>*vGt%š3qr “ ;¶C`€q =ó<0Òb yziÐ12DÉÉó БNÑ¡Yøõ :|0MÕXÈÑŠ‹‚ w Z+í9…RgP¿¢T,yà > QRÇšE'2gb³bIÏš(v˜"¨-:Í™ c­¢fôçkEý¼{U=œ<*µ«¨ì¹rìk4éq8¦>¨ê8±EC1¥æu 4›ów/•5›#æ>VF¶M°’dºi.¢jÊ—+l™ûªµSŽwa0 BÓã~Ûbÿ#w\åB³±w_'s“ýÐ’›Ã‚g¿Ù”Ò…ý„fb£¬¯€|pn'%òyá‚-Ÿ£”ÓU4k˜à|@ÑY”L뇌jh¥~°Ç¹Mîç°° [6Hªé©6¾XóÂwŠ…\‚\>…\(ã%õ1û…ZÕùR*bUñ¦é» ˨»Mé\Ÿ¯´#¸&M¿¥ {±Tñ®ýcHÐL„XGY é/ôøíͳ…ïÏ]¶4'¤ö¾¯O^W@<§®<æñ\ÍÕÏ®¡>1Eés8ƒšE.I¯¨æ»#¾›N:”¾/€©¤Êx`å`Þ ˆ}&ïéNЦy4¶§Ý}Æ4÷¶:6bOÈH3À2Îe9*É—M‚YÙ˜´Ö‚™û'Ð{È1k- Ih_dfÞ5oÛ]ë…Œv $¢Þ -ö¹LÛW$FN]oCs=£›˜‹&3›yåv‡Šã¯u“<¿ Ÿüïü˜óî&ë<–W®[ÂP~ÝÂú)c ™ÈUá׌À:íQ»ÁL’ß­£2þÆh:.ÓÜ÷^÷åtnd×[¤~ð:Çeµ1‚Às L\;Xà&X¥x˜­uÚ#’m,•Úc.YP s¼Û®=ùúËH°H{:4m·ßÇ5ŽiãÑ¢>VD\Õn€D­ÐßÇ¢o _½ÓÓ[<íº[Òð€«Íû]UÜÜp‡É…'‹ã4ÉX5÷z‡Ó 5 Œ±÷„fª`YÍqdfób}çf% ¤³aûêц*ì”æÙlè“ÝíÚs˜”ôK޹duØêyÛ ÖùâªT,…â­¯_¶Öˆc²ÀbZŸtçÙ Ðy‡Ê„qµ™\¡BMCrêm·îíï2ÃÉ?ýëÀ«­ÛfY ëŒY–5Ó÷U¸\Q´Í'¤3‘…]TÝ‚x¨| *_°4tÀ‰ƒš]Ø9ˆ­Qì}Ám_”ÀàÛ.¨À ýz:@=Áî¿BÿVqºh ¥«¹»²sÿªs©²¥’øSÓµ‡½ÿÅ. ‡Ð¬bÞúqA…U¡í]R¦ÙAù4¿¤ZVfh/VÁÕ”„]}c.l㳄á½ðg}ø|¡{7é´}x‘âÊ( -ºˆ]ºvЉoÚÓZª` Z*[¹ÚÀdÊC3ÕPû€ vþc"  B³øþ­ß™f2F_lÉÀIsöôsÚ/¯ÞåråPäR›[,¦(òÕÚ‰LzÆÅD&HÁn–âHÙ–àT×FõNýþoï~ùöÝw£µRn­ ~z±‰Þ¾ÿnλaøHð7ŒEî~á3„¥þhøÀ|&w±Ö–K?ðÑ4Â5˜i^" ù'; 5ßâb›¦›|dÄkÖЖ˜|rÕ ¾Ôw9”ˆ÷¡ªE=ûgÜîW w1Iédqgx:i`ÚºùÊëJ:h¹w+,XÖºT‰Q’yønråÚ*§îr¼rÈ®ÜG±;&×[ê±¾a¹L=;­ÝWCŠ4„hZˆIà_"Ù}èHÄA¿àûöíO!êȯÆá1#å7?ý?q¬–. '­Ûk-Úeš;Ï„¶š0±ÉK„ /Y¯êÁ—gî³;Jýí1ÈKvåtÁÍ?dd¥þ³g›†›c6Ú5›ÌeØäüË6†·3(l"áb¡­faãï$rþÝgbÇ/º#ÄN‚ À*Û»xåñ¾óÖ_¢Êb»^ºØy¦g8°gû‚ oÔdw©óž­Sx•ò§ÛÕ?nÜŸÿ~|ƒ›endstream endobj 183 0 obj 3336 endobj 186 0 obj <> stream xœ­˜KsÛ6Çïš~ Æ›À±™ªN¦ž¦utˆgr‘eÚf+‰6IÅv>} ɯŽö€x,vÿÝ…ï§‘)6?þ÷j3¹ŸÜO‰k­6Ó‹ÉÉ9a0‚4Ödº¸ž¸dªñ4c i:]l&GL}Xü3aD"¥|_\MŽ>ÎÏÿ˜ŸÍ/Ì)Îh濜}9ýbç ¤…d~T aOÎ32% a8Ñ8ã$ƒc²éŒk¤ìÌu~ݸ©¬gU0aF%¢nÞÙü÷…™ã’IîϹÊoª<¯Í‡YûeR·Æ®€# St¼b莃¿ÍÌ,n‹fWmknÆE{ns›Û­5ÂÿQÄt„¢BŒ&P4—ŽàrÄY"L>LÁϧN׳çâ(’:M&ûˆÃlLK—¡Œ&‰ãÜnG!HgÝ.Kw?I5/‚iPšîÁVçÍ—yFE{û²Nf=H­\³·¯óÅ__¾ÚKãØwešÁ\À 9l¬ç\Ðy ßK¦Œå> µw£"Ý´M…36¢ 0¥!rM ÕÁƒ.6Âx¥½ûò².×»ÆîÀ"¤‹d½‚ mÇLXJÄ¥ÆYçÀ¢)Ê­ Óˆ†’´p6›Ì;‹íÝ®#]ÔL™7Î0ë¢n¼ °>1&C‡Y{ bz0# bÙ>>aÛi«›µÛø°©°ýepD{…¼ª}Ž×ZÒT\‰ŒC*úæ1‡£ºYQQ‚hpØ…Ÿ¦dw“Ué%GeuUl—M^§õ 1ÉÄ@O/)ù@þ·‹q¢}\•Õ¸xò£#=d ;LÔ{ô BÒz>Ûj6ÖC=p¨¥a,ÖkiOŒ½BD$ô7+8%1¦Ê€CªÕ¾MuI»Ê}S¼Ë¯gZ™ŽbœÏÃEZœà è3ãe‹>V=¨ûo`Iœ?`ú¥HÙ}ÜÇ.ÀÀ]KûFv{è÷é»Ë£¾ï¶¬ŠŸåÖË/ªŸÍr½~òÍS*¯«rãGUÖeȱé?ŠX¹¾kh?Ѿ7¤8˜Ð51¬_©¡ Ð(¥æžû¨ÙÔºˆC7¶çÉ^Ó´‡›™CC€3e]Ãò¡ÜöÞZ•¬ÏáâѦã´ý4ùDpSÛ-ùp;O~'|Ý“LïæO…•oÕpñŠL«Á÷įUw6Ú‰9¡úÔžUS¬Z-€i’5Ôèž%´…*hAª—k!z@uZPz¨…øØ"ÁÄû´ t§…p_Bú÷õ©_©Î‚g1š1eÓ`§…g 7ï‰!ôæ%Hd‘Ӓп²‰ÙC=ä4M†ùþ6_¢›fýOó_ûüç© ,4Ø£øÙØ~ ž2+Ç 9ôpLˆ$<ÁþÑÑbÓ&@âÇQÓ -¤\8;z8ÌOcÆ í¾÷¡u;<éÔ¸‡ïmÔ!bJ"U™Œl‹º™÷tØÇ>ÇÑÐÜ$ÝAÁá!jˆ{¢ÚgHÞ!ÂýÿŒDEî Ou‘,ÇYø·\R8û²Í¿ž†./w ¡ŒŠì¸£Z>®qš/¦OÌÏiÓÚBendstream endobj 187 0 obj 1391 endobj 190 0 obj <> stream xœíXßoÛ6~7öGèm-³$ERäÞº4h÷ÐeM ¬AÚUVlm¶åHòÜþ÷;þ¦meIP ØÃà§ïÏ0"Ö÷]­'÷“ûŒ™ÿªÖÙϳɫ+’ƒ)¬H6»›ØH¦pVä9R4›­'/Ηåv¨»—³?&Œ"†sJ³ùä…øIËHލ’ÔÉÞvåvÙT½~’ ŽˆÊÝ“\iÙ««‚dð ›Úä”QŒ¤bÙ”)$â²]×V5?ðŽJP˜R¨Õ{wùþÂêF1…ãA‘HD™Q\·ÆO†HüüK‹8Ê¥öÊjã4!H 6,+¤@>’a× +#—TÁ¸—[;‚ûçªzc„`ŸÆS-Ä ”Q³½s>Q>r$“…öUW×daGœ†$]Üï,}ʽ¯åÊùÁüÑZ$¤ ˃ ŽsqäõÅì·ËkS a¼í[ìà‰“áϧ2xÿÝÅë7¿üúÖØ§(É F£9fX×A‘¦ùº¶¸(ýÀ»vk}û|fòÍ‘bÄG¶-6‰%B™JW,IœYX8¸åC‹ÆXÌÖm Ä”±æ1È" h´U¨dÀØ4'Û(»ê)­òúê܆÷eð¶Ü,lç QÁ} tå¼Ùõ£ ð›Sz®”ÑŸw¥«[ÆÂÙûÞÉx²\n\ *‘Yÿ¡”9sEO%QÑÀ‰¤P¸ð]ÔtÕª68 ¹%¿o†¥ —!Îξm$âÑTlåø2¶r98jç}wpÀC­|æªCÅD?í~kdªºj~¨çÆUíVpÕæËÂxGú¡ì†f³ÐO¦¹ú“*Óäèkgp0‹Sº’ tÒŽÓ!$êS°¬Á¸µ}Ë`»ÜOÛöü9õסÞx} {JC/V«Öõ°5zÀZÊcðç¾éñÊP²Ã²kw‹¥# ݈áÐØ¥€ #.‚kzÊgö`J4YŸUPøAyÞ:—<4hÂô"å&+ÔÈ7ípÊ+O`ž*Eº9ÔtmXåàÌ`1cQ¡¡™fZåÊñVckè)‡½á÷íд¦è¹@¬ ë»ºkê~”¹P Pç”1ÏH[ÛÏœpÚ¾¥2 ¯0–²™›5Îýv7lwCïªS°‘²8¡Wåð[¨òj×u¶Í$’Î3™*g‘“¶vR°„¦Ú¾Ñ€¹se<·ì]Í“â˜çŠäÌUÓž$#o’„9LR‡r=¾½d\ô’ÖPÉ,³ÉÔ6½Òní NFúûrZÝõžç€vغÞÝ®x¨ÖH õßD5ïKÕºvåqah; ‘r¨ûñA™K XLÒAùµj»§LÊç—W¾;bHŸ _º²ûf‚a)pÛµU=ßuõ§—£E©\>¬Ë”5mׯïÈÍ™ÁI‡ÔÈãu6>±ù¤õ‘dУdŒç‚H=––oOÌÅÍÿ¹ˆ±Ýü;¹H&ø£÷­¸¢?“zÿð&ñ®Í&nGÞ¯y½€[Ö¤C‰Ð +€«ÍšõÂ3opï’–G†+»ùèèL¤€a®s`a]þþúê½iÁÓ¸ëmÛñ+»êÔzœˆX²ÃÔÀËXϾ;5B_8ŽS£gq¦ éúêÖS–^}÷˦r{‹Œ°tŽ‹èø¨©dÙ×ê0Çûe»[Íý÷¶±¸lùÒä‚|WV~†ë‰§¶§þKÕá N÷Ãdp‡ÞvNN™‰•$[ãØÚÑøëI.&öÔ"þw]kR —Ò"uÉ_à’Åù‘=(=õá=ÈÁŒ“%ݯþtì"bý<çÐ…ýÓN-âR{H’»}XÂØé¿>Ö› ´iý‹Yöa¢?¯àŠ8endstream endobj 191 0 obj 1422 endobj 194 0 obj <> stream xœ¥XÛrÛ6}×WhúgÆBp#Hô-qÕ:S'neÒLÓZ¢m6©ˆT4þû.€ÅEc;ÍøÁ3+{;{ö@_Æ”°15ø¾}}3kóÿæ«ñ«ÙèÅ`!šj6žÝŒÜØXÓq.Ñ|<[N$}>ûw$˜"….àóÙbtòjzõûôbúÑ|¢2Bsžã'—¿]ÚóÑ™hÍHfŒ/®r6f‚PðhN$ËÁM>žHM {²›o¶ÍÜ–”…Îð†;÷}±ð„qBÍ™ W„» Þ]½{vƒã¼L “LQfO·Û~½í;ô' ¡Ð_iLšd…¦Þ´¬»ÞXYArR›·5f&oì˺©›[[ˆ<½Ö^QpÍв3–œd2XZçÎP_oë"#y<´]Y¯’YÁÑvmÛA¤ÒÔ·£Út§ÆÊ)ÉbÌý]e¿­¡h¹ÿö_ÖĉÚ× YØï2¢â±GÇbË%4“{-ƒò³"D}SÎûCš°,à¦ì0ÊB>Û®rdDÄà¯C-B–÷®b:1½›Î&Æ:‘TA¬llšODb^þZ‚q)•I4:yµµM„%lÚÞ–K¢YRײG«ˆV=JA˜õñ0ps•¾üŒ•Ð*W¹ê¢b·¿Jia~Jö\N hj[ݘ‘:EðsÀEC,2nh› y4&£åõ½ho\G9‡]GùçD>=··*É¡ Ž\ãª1ù;i§‚DBv¦ÿج%#:¶y]ÞVÇ(–”:H´ÔìB*îHKq(âx"R$àÙÞWNC&3ìt¦˜w±ÝôKëY@sZ榮cE0~¨›E‹9)™ËQÐq*¤§¢3ÇwàÂûM»$xN)Q@ÚÃæŽ-îZìw¡hðÓ‡`9”[Š—®-ç—fï¯fS 3Ö`Ÿ=öÎ_á„ŇÆIìi²Hù/F lÇuhó׺«¯—,ƒVîŠ ÏæŽëEõí¬¡¼EºÕÎ_ÿ29Ÿœ?–꣉ ’‰£Daßñ¡DŒwH´¶ý‡( TÉC§ ¼þºÖù ò€þòxÅÝZX0@eŒ«=¦ú.•„ä ö>.Hžpq{ÌLâfU§¹×nƒ„jvwµËÃðó° î]@¢0Å·Ï6N']•¾UftU/Xfh\¤ GvpËÃ%ò_F ™'ü7oWëe=/{·/•Q2>åM‰9K0°mrŠÙ1b"Èy [ØFÕÍãn¯^߈t ¾kdº563Ï ß̪ZtØLñ²]c9ö«o¦‹ ¬#wÛë®/¬<ÇçÜ×åryAàá}z>m¡aÇA Íh»±›/+wícC}v1}ùö1¡Š{ªìÜà Ø}± ¨MW*“åÙ¸³'QÉ$â$•“¹}ž(:·î¹Á×#%o°72î_ÊÊ ú°‰{îo7åú®žw(™tT‰;¿¦Ìú‘™kG<t¸yæn6-xœ&ê«íê¾n›S¼)yÝUåÂÏDŸéðÉz`¾d)k²òÌ•h—EuŠ«8©|ÕÏQ½d‘{:¤Ò„úP{ík÷Î"2JÈ»²¹­ÃHç ¤ÜÙGúäU=Œwà~Òi:µ ?9{÷”%–@‹qü¥FìòüQäø¥׉õP#ÀýÅ]Õ /û35ÄÝ%ï!ÜH<Ý>uïtâ ÞŽ†ƒ¼J‹s@ˆC{ÅvL£ˆ¡!6Ýž–)þ/êÏ8Å<î&ÃXF¼„‰8¿|3Ey¯D\êṘ\8ÚA“µ·oc#™™é¿íº”Hoã%¶ë2(±…ÆÒ*v(±Í fØÝ©<Û’žÂá®^þñ$ ï«åÒo¶¬8BÕâA{Ò $Ì/1¡GWD‰Ð¨6ÈÉ›Êg9&OÖa²ù¡CcL¿:ì1%Û¦]aBÉ{®Ðq;>DƒÔ y'›«¾‰¹oˆ'(0ŸŒ‹ ì<²i¢‚h‰§ÅÊ“dó5ˆ@ÆÒA1JQÓøìsO؉„p¸Úû"ÒFsP_í¶Y”›{Cð(yº^/=X¥\> stream xœYÛrÜ6}WòSy±]¥¡‰ /Hž¯²q•ÖÉJ³å­Zåš¡$Æ3䘤"{¿~@hÎ`.›Òƒª@@wŸ>}ºçó,MØ,Õø¹¹ø|ñyÆÌšû·ÜÌ~Z\¼½aV•*6[<\ØØL¥³BˆDñÙbsñúÝSµëþÍâ É™Š^Z¬.^çßë5&®JŽkï«íS³ô‘g SŸH¦×æ’§I©äl.URšãSmöQI* ·Oß<>™Õ2‘"—¸:ê¥2aR¥.Õ«Ç:ÑËöã™{óîõm‡»æa×èQ/M»2ïr½s–¹eó&K ©.5®ñÌ÷ãº~e^Ÿ U$,/fs¸OjÃÙ´ÍØTks.KdéÏÝØ‹Ë¤ '¬lìà„¼ô'¼ë6Ûª7GË<Éà>¾ÿð·_ÍÆÕÜ»î#î«J©ª]ÁœÔïûóÕ‡wWæ¼9+É…¬H¤yx[;hðp“ÿ˜O~¿ÔO²4É îÜ»­kt¢Pùãp2Âøö¦`3í#H5isƵà\8Å¡(“4U¾½“LÃWú•9ÏÝçÆ9íËÓ´ÖÁ)‰©c½^[pð™O™m ms«ò\f»($¹N)2‘8 =ÊòÜŒËRÇ8f¾ß¿çÏz)O8¸tÒmÐÈ, ·íðî9·k/ñŒ4œÑ<Ø4S¢dbÏieZˆ˜ÓXáæs,e!u‡Of1Ó'¹ êUÀ‹x|Ï=ÄÃ-€JH÷ZmY$ç*Í<~‡Ñò±Ny¡h›x°éÞ:X&êžÛUÕ[Šc@>O»´³Œq ñè#©P[2æóëD.Ñ`âÁfDØ(¾4ë5¦sYøô<î®ÀÐÖ])Xê¾–}]· òyΙ{´°†Õ”jþl†æ!~ ä»c±P'-FãÂõ,Š BVÃ:pÜ a$Jd.JàCAóíãÍ¿¡e ™ =Ñé!e.ÏM=ÆÒ×:HVz€ *BðâÒC(ô)‰Ç!éW㙑V<Ôí²ŽÉ ðQI5†1ã¸ÄÀ7©ÆÈyDcˆ9]²]ÁuÁ=Ocèx›8(Ô rŽ )Ï yÏLî û‚8™í²Þä2‡<„‚ÂxÃóÙQA1é\н„\þ?A¡ÛéQ‰Å²CìÒ¨ p%/HòœÐ€×tWO ìÒ®¢Á˜èNW×Kç«PÖ<³_jLÿšžP(a9Pü¹•ã5"{Ñ_P„5¬PÊe @EYN{à郾¾ØÇB[©Tc8}ŸU‰ãuަŸÊÉ—f|­ ²u#œi$¾‹QM¦;r‚™qŸã=^DÀ˼ h/ œ½… §hÝ÷ Pej䦆 ÇÀá,ÈÛÃ-BÚÙCݰ-3B»68Õáê±Ê¶0«22EÄŸÑàêÑIFÜom,2ﯯ×é¶Ð nØ´ûœÕýìëÇÆª9¡_ ÏAGÆZ¢Öv¨†n]0iI—¹ìœ¼!zi¬š—(( žn5‰R"†ä€$9`‹¦B«zoiL¿¼(ÆbE¾^7m=¸Ü¦“„Š4—¬¤lðTí×Ëó83¦æk§úÉtaÕWèU”Ü‹®z©«~ÝÔ}‚9ÄÃt‡ŒÈø}ûNz ¶÷o°pM?VК6G¦IàâÙœ¤Ôʉ ¢Rê¡}5"ÇdÁ×V¹DjôŸðJdòùБââi›äŒNR6(âK Ê'hÛH@Z‹Ì&;ì—ůÚ¡BüG5ú›H{W©–£±xɤ1š)CµqzP„ëþQ•c:D|N—¸N«æh-§hñ®cÏPˇgS\’9eÓuu.) áö­£ ^ã9§{ýãOW†d¡/äyHÜúË¥^ ‰£_£ ¿ú„aVyЙN®°b—}©ûb^íƒ1+’<¤Áº±:\—…ÖÕˤœŽ"¶Ïã%R¼Ì"˜%ªhÛ7ŽJXÆïnj"ÄqýcÎ2»ê)¼÷§‡I¤šL ¼SMDvö Œ0Ä0Výˆ¥8F…Mk›'*üHM±~Xdê!¶¡¡’Æa›s]A(j5Âì(í)°¸ú÷âöÝÍÕÕ /Üú–oß¼:Ý‚öÀï}Õ>ZLfºÌûògˆæ¿5ŠèL×^‡I¥òýîEÒ~"ÕÁñqdî+I›V}i6x[= ô¸aÛjéºG2ÂÙg:,Äô÷µªYWn’))ÉÆ„VNH* ¸ÿ±ˆŸ#•Ê02ºs{CI„ñù<VæLKz(‹i¸°µ¬„:Wú)ïX÷Pl0¾RGÞ?òýi¨Ü&×Ýcw÷Æj (Ø¡dºy1Ÿh–dŸ•³S𘢂’9JµéP"·þ>QVæ2…V®T$‘Û߮ߓÜ+Óijbüǵ]_Û×ñ6ÊØé19Èö!¥¢ƒ½}GúÛíC®³^è¿ÿs|F˜endstream endobj 199 0 obj 2252 endobj 202 0 obj <> stream xœZKsÜ6¾+û#æf»ÊBH|àè8ò&µÚx×’«v+Îæ@fÉá˜äXR~ý6ˆº9¤$—ËWa@ Ÿ_ÝЗM$âMdÿáÿU{öåìË&žÖüU»ùéúìÇq+BG:Þ\ßœ¹âŽ6y’-7×íÙK%_]ÿy–Ä™(t¿_oÏ^þtñá—ÿµ¿d©ˆr™ã/—ïÿþ~ÚŸ f ®¦"µ‹?~ÈãMœˆn´ž«8‡kò͹Ң˜vÞ›f¨zcöîƒd&¡,`۹̄t»ß}¼¼¼zûáââ7»N‘/aùêÕ‹…vçð3| 7ªéÛÞ”}_îoÍ`¿M•PV*'ï¸3vQFB¹ÄÅ¡þË­J‘è Z¹ßâbA[“a„Êtä Ó õXw“VI&ò,Éü7“ìJÄIãÚ]½ßvÓ±…ˆUšúåIT«[Çi_ NÐ…¿¾-ïë¥MA‡$¸g]±CYMˉµV¸­œ>‘Ôþ®¯n%V:öß–uS~n ª%‹ V½Gµ¸¬îvp{&âlc=9GÞöåaWW“~ nHƒÄ™B Õ%Ê)‘fA¹­AÆÌTp[ÿ`zÔZÉTy…Ún;-çBfa¹-«IŸÂÆ«÷ý®Þ›a$)D¦•îm×Ê~FÜ×Wÿºüõš¶6Éfq¶0’É8Ò©uñüF8W³ þuVQ• føùýÕdð-¢?“‚"ßôDéëI'%}¸«ÇÉä“Á`‚[4z”‡¤¸é»vZ…Äiu–Û*ì^ cˆ´ ¸lê‘>HáG\Þ ÌK3ÕýµàŠO’0í €â§-w¨«ñèœyžèܦ9sθ+džQœ+²ËvëÄNlj†õÏÎä¹ Iõ0E‚È$¤ÞBŽˆ²t4÷#Æ|”dê[ÒPA‘9ß4C79Væ""› õÞe?˜RÜ”NéùîÖIËä?#¢Ra?/p: 6±¥Òfã/û.-§‹#‘ú¥Hó€ eÓ¸ÕÌ·š}s|;ôˆZ(Dʈ!© ÇF)Ç­O€sUsÜâ–TºÚ6w£\¤pšÝ¡Nîµµ>ÑYRС* !~ÙÝvè+(Ô*\84~z59]Aý¦:À>Pdæò8vm9ÖXl ËLóôx \&‚DeM@€Œ'ÝΓ"³qÏÓÉÃó% HÏCîvfo¾R–ù(rÀ~{t8ÔYôÃèñ Àj€W©|dÑ÷8ÎlÅÒq¿_ïÜ`ßœrjk†úÖ‚Õ0\·5U= 9P1§S7] 9B" Kº0ÌÔNN†üªì«zôÅ/Jüu.Îá0s b,4Ù£5m×?`¥Tdû×ËÔ|R2q-pb,É5q!VýV€„¾\Z“›±ê;®ÜÖØíx¬µã O`ʇNB_—žËä´æ‚¡°K±ǯàEO†N†X ’”nܪ᪀¯Q`0Ny æTÔî<`LÞXnLë‹QJj:‹hk8`Kpu>‡4s@<`Ì~¨¿¢)¹Àˆ?ìâ’×Ãõ¯—Z¤r-‹Ÿcö'LéåÕwQú8Y¡ô±\RzðA¼BéSùí”Òè„Ò'>ž£ô •0€gáöT Ãg¡† ]kð}‡€Æ*‰ƒ –”›®GytœjòÄñÔ 0𾬼MÞÁ©+,¸îvucÈ ¡ð4"À)U‹ÿ­ÐSsð€ˆŒ»í Rù’ãE‹†5 ³öCŠüùöÃ×âA˜ü‘[ß—€jµ/™íЗÌÑŽú%ŠGú6õ%‰…iưœ7'P~)j©Ï˜˜š…‹`wŸ±Dò¨ûvwÅ ˜NI–Wf…ýNý1‹B‹ˆXÆ¡¼õt”µÙ*ÆœPD Ä*ö@ƒ¦yŒÅã~2T wi¯Õn ‰Î;%lá`taåýøÛÛ_&¼q¹‡bêB@/ŠCD>„õ%jA;Ðõv*·öMjA…cµ–á ¦6•§á ¶{ s/¬ÇEoF¢Pœ4>·ÀôòÍfÅU®“,Ê(¶5À¿/áiBFš¶Zþì995·ÆŠ<ª¼¹1# !’¬CAŽjÒU]Û¢~ ˜©8ƒ»ã`¶¯1OÀî9Ï@\,»Ð„ímc„Žb=´ˆcã‡(ŒÚµ+­ßÕîxi+eˆòÇÚ¦yä¢Å8¡ ­é.µHu—+-\3Ö‡æ½fKu<]P\íº¾þ Õ÷‘‘DzÁÐT„«àA³‡Ø‹aú©õ@tgõêc ®Û´) ›¬2¡þ Ü{³ó˜8y®K÷IüĉŽT[BáwÒY¾gTµ÷‹ -^A{•®è6²¸u\ÍŒQ8ô £å°¼¤ÞŽ£«ÊV¬à…wîö˜e&²Å¡ÁÜ—í¡1®é½):ËÇ@wŠÓ¡³c¤Æþ¸Ä¤¡>ÍëÚ H(¤!ˆå2 â5hv}-8Xáú–ùĵ\†ÇΔ~,v\²CÛp†ïUŠÎa}ïÖÜ[|i¡vÌÑ­gŒI® øPREº³5Ž„ÀÝŒû®“ÍnÊžâï[à¡Á3ÿE1ÇÛaK«J6Ÿ°3Zا@¶ÇùÕ3@6{XÚ{ AMuøržäíÏ*ɶۿðÍ3UžyëÙœñ8®ÔÚéh7eÕ¼Q]C;ŸîØB'ð>–7Ÿ^¾i ¡öPã äzSg;!pdKhVJÈ…»#†"k^*ן+ëžy»¸5M=á’¯£‡F`D!ìS¯­W¿°Ô¨Œº‡µYÅ3dG+dÇ‚ÁËÊHi½¥Fš“RcãŸòÂ4M}Œøôj2‰œMÌÈÜã896Ü×÷Kžûø;j¦Õ ‹¨®þ³¬\gf;jV+»ag?××D\VjJ7îP†h63jüóŠ&ëÞ@¿×õ+m ¶s>Zï¡cÉ Tœ’7öÙ«‰ž}£%ýÛFj»Œç é ßTg£|߬°¶ŸÔž™ž«={öòjkÞëÍÔ,Ñ*¨ Í š‰ÁCYU]¿%:V™Æ”¿ó£´‚ÏÌI6–Ý•ýöAJQtx©g]dÕ”uë=9ZµÓ“i:ëBš‚ Ûá2ÔÎ9  šÏAY˜¯bųÚI:ÕÎIƺÅQ‘´ÅÈÛ¸©±{Hc@Bm¼ZÐX6(›£ñ³ß„¾&GsÕÖy朩8b3…BÂýà©Îü©”emËóãOÂm×WØ9Ÿ>™õÕ–a0Œð_:ySVSþÖøÌgÅôÓK[´ÝÙ pÊÞDnÐd$°ÕMüŒ:³Áü»dÙ#ÕîkĶåˆÙÄvK‡Ê…iØèç™7C¾$cùì*élôåË +›æ̈GI«}µÀ|Õdc´$wÆú³Î`†!ŒØ4M"Y ­õ·À¦×‡%~£—øê žÕÉH˜Ñº.Þ}¸¸úeGŸf ¸Q×||¼þ ,YèïŸß'üVâ\ÇŽo·…ˆuèSñwÄ/¶ñá ܃o/ß1#5ÇxÀšÑëÒ(¦ìœ3Ž>'j½©:l‰\eÿËŠz¿Ôº*ÿçñi‡¼j‘Ùü&q|ß<9ÕôþŠS–˜ ×9”[þ!ɜ׻‘…S¬¯puÿàAcD'lf…3¥ŸãÆóç,`@uØ«Z3 †Lwä^6dJ¡m¥iËeyFH×üIÇø7†*&Ð9†›g Ù#F3{§{”ô`îådY;úš yq½ù÷™ý÷€L'ãendstream endobj 203 0 obj 2924 endobj 206 0 obj <> stream xœ­X]oÛ6}ϯð[S æD‘¢È½ ]«®¼4uÜeÀ²ÕVbm¶äJJƒþû]’—²Õ´Ø†< )ò~œ{î¹ü4K%úÿ¯÷gŸÎ>ͨYsÿÖûÙÏ«³–”Á Q‰¢³ÕÝ™ý€ÎT2Ë#*­ög篶åa¨ºç«¿ÎxJxÂlZmÎÎÅz2’*™âÚ/]yØÖë^ÿÂDF¨bø gzí‡eNgðIwê+ç»­5'Iý®Iw6Ì9¡Á“/7‘.fƒ\¤éJ’Lä³9ƒ«¸-OÂÑh!<þVès&¼Ïh3•'.¸e³ADSéo\(¸ ‚ç| ã—Þ?T]]õ“5OsàÎà¿ÙÞo[ĉ?¶9Lq@)SàwD×oßÝ\^ai%°¶ÀµŸž?{‚¤ýº}`L*˜ü¤ŒÐÔŸ±ZÈ›"˜Ópðۋב:ÒöEa,žÓD@áf1VœÝ§Ðþp†C±»Áà !Ì<þç Œ¾ èPÞWáß4l6<´Ø¶«äPN®Øþˆ]ÆMCKø¯·‘É †ŽO(°ÂœA¶-•÷뮪š½¥;è*̰©¦Šx%̱¥€ëWË¢¸üõÝëâ[½ü¸h9º b¨$‰8\/å$ãž…ÛnƒÛD€Äªø}eí0A“.^×W‹‹ñº‘…£BÜÜÚ›‹…ýÀÜ $L}ýmªV ­š vU& ‚|Uµ ÂbÊó¨wNöªõC×Ùö ™IBmÖÿ<êì6afkJ„ò[÷NàÈ@p›j4l_G8°ì€8€’ŸˆˆLo H$nÿ €c""ÄRç¯"A«ˆ°ífùÒôÐÁy(i¬=ƃ¢{S\¾*ï&!ŒŠTë èÅåëwŽ …W7ðHI| "kGDÐF#ß¿,¢”ÉCC߃Ž#QÂÁ|HÇX”d§¢äÊɽ,õJ´A¾ÎA=¥H~.×f'uâ)çïû®}°»H  8üá• •r’yW»v7 4ÅIΨA·(±«ÐrN¢&5êú.;§˜î☥í´2 ñ>Xdf…û§µ´3 €yâ^— rY¬šVîJà¨×à@……æêŒzXCÅP©#ª{9(aþÅIéïê½ë9 °ŽLÁô(ü‰`·eððãÄ·6Ü4‚÷‡+×#Âq·çµãZ©Ñqí#Ì´Hlß:܆`®ËÞ4¶¶\ÑDúìf(®‡—ãDk¥i|Qæñe¥8>ªE 70<šÂ›†C?€¢0—lËÆªè7‡ƒÄ â[j\³Ô 2‡œÝ\bƨ®¦Xºlê±$Ò_O¤Ò-݃:J$=MϨUDéZÞU%V[Ô §†?—²Hü#C¤C ]¹‰OP"$!XwˆƒdŠÿÕd]‘ÌH» ç±Aø±yêÏÏBÃéÇ¡P£T´‡€^wsÕ•ƒ »îF¾Ab&!á̶q2/bâö7fñóJg5û† m@T×Óݬÿ 3zܸ ¡ócÔÅå Ë……Z¿=ïÝ£Dœx›Áíc½%MÓv ï6îê¦rÏ=LFåZ¹§Ô¯Dc˸y~ªcºšÂ-œ¡Ë—v¼Y\ÅOã’D&|3.i€Foý…•¾ÖOì(yâ§…Ö­¾¡J,/Џ7=Ööµ/á<‰ŸÇ§•ÊC®Ÿ¬üÖŸÁ³¸·<1’«Ùû3ý÷_k¶endstream endobj 207 0 obj 2114 endobj 210 0 obj <> stream xœíXKo"G¾£ünkK¦wúÝÛî­¢Xk‡eóPœÃÆ@3xÖâß§ú1Ý 3†D9EŠ|À*ª«ªëñ}Õ<3„‡™ùóŸ³Íàyð<ÄVÖ~Ì6Ã÷ÓÁÛ ¦ A:Óx8}¸x¨³¡¤i2œnWŒ]OÿP,Ò ¾ŸÎWïǓƷã_Í7‚£L鿹½ûxgõ9Ò\P/åˆáÛ‰ÄCLQÃÃÜÈáˆi¤¬æÖè)Ä1Ä.J#à „¸5¸ß:{ôèIIñpD"ÎÜýøÓ—{{œ"¸Î-H¾\¿éÜ|_«áîÈ…=×»Æ#a®±[Ö–B*“­ÐF":“!â7íi!ÅŪYíVUé–)*ZOU´VmüE8ÈnœM mkó²Ú-«ýÎ|Á2Ģ͙!F4ö’e^.VåÂÊ1¢$¨®Üí±‰I¶¾6•÷¯xð?/Poa‰„’ÃÿðÒâõÊnó•½=#à)\a×WÜdSjÁNÊ{ÿîûOS£u?ý¯–ö;;3#‹¥ýù“õI²¼œ{ç$»P/cZá3ŽïcàÚ‹L>_)*“H y±¨E7E_ I…c§OÞ}» Žÿ/à?, Mž-׈˜¬j—*á²û¹pf4¤;¸ûÍžùÝB‡Á]À{›/¬>áˆÆÌrCimô7& .Ë.6H]|mÓŠq(LÝß4#ð üBOºf2þi+¡(bò´ Gµ¹:×@4e¸ $a§ Ä㧸©*>i ý2{ƒ"Ê‚c.ƒAŸG[P$ÀC7<\M—«Æ‘?"‚³Ö[î½a,¬šµ0âp]!I¸È0³àëäGº#F24rdm ªž¿ØûjH-oõóºÍ‹­ï!3[”s·-@‚ùVߺ”H$Åyq"ÎÚ[AGFz<4¾»Tl|îÖ3dÖ‘&ŸVµz²2‚( ÙžUëªF×ö¾X˜HŠmýëkäFö-,Z÷,κ«Â+#K!³v¸ÂÈÂxØÔ¸IÂqH­½Öadúh@?§0£înï&6f…KSPî7E õâq½jl…FN-–ßXù`«ÌÒ|ÝBgô™B™9ØGY:¿‘>ø…éï6H 1º!Ì×Y2}n«¯^Ø•ž:¢qVK×¢26í~ÓüÇž¨ë›rXpû²\Í<ÁµQÛîÖG§7~’·.Ýf{×èóëNbE¹©D«¬Ê²Xä;—Žá2¡¿½ªt–Ó^dY@3x¬b: ËtYÔEÂr'„÷‡0f’–[•ÚùºµY?ošÕ¢Ü¸²0s§è¼ñƒNâ´=¹Ž0ø3«/âtS»døq'XtI×öYóm?IB %4—ùá€Éë|ö§d$d÷(î ?w ªŽÞ¢.|BŽ ÒŽâì;ŒÇ æQ›ñÌÅÉ:ÚuáHN¥Éãµ `_¹Ë}Ó°,ÔJtTÅz]YÌgæ‘úCzÞâYèm‹]ác…&S$éÕÍT]½ôd@ww.Pe¥ä1NYdx蜢iŸo°Mµ¡bÜÕÍŸ÷y'TŸVLºúM¾ÞTemÚÕÝîëíºèÑe]ݪ†—dŸ.ïêBÏz±š‡1Kÿ¡…Ý;è%¼ cT{’×Ù1+¸už½1†™K¼³Ñ&þ5¬‚N‚4næ]3 UÄMÙc;Èâxþ tnÚå/;FÓ#k‡.rF@!ñn}oºÛñt:öÈ•,^³j³Ò'‡•,þŽón ËZÙb2œbÑZ±>øÛóÈW7~…“¦¿“‘I^k²ûZ;ÚsÎÑ­–Ç;”¯?V]ºM¶µ^7çè–§>‰kc{õïýêÀ²c-3êa,>¡Œ>8ò;±]] )ÄÇHØuÜwËÚm‡Äða°z‘=áòq§}•<ÝäÀ*És]4í¦ÄÓÒy(g™6ìbŽ`?Ø ˆýøp›;n饦¨Ë[ÌVOÿ«hËø é}âç›j_zº–•_'?ŒõíãÀ47Ýî´´vÓMHïë½åJ¸t’%—gø\üó¢Yy¾ƒWbI̶ùÃuÿÚNy†á§k{¾.v»þŸ^”y/è„AèÐ5É~m¿L–÷d×O‡?Ìß_wŠ8$endstream endobj 211 0 obj 1662 endobj 214 0 obj <> stream xœåYM“Û6½OöGè»j„‰Übï”k+.Ûk/Éä@I‰k‰”I*®É¯ßÆgƒCjÆ©ø–šÃTA v¿÷ú5øy‘ºÈÌŸÿ¿9^}¾ú¼ v,üÛ¯VW?ÜR#DeŠ.V÷WîºPÙ¢àœ(¶X¯^¼ÞW§Aw/Wÿ»ŒˆŒK˜´Ú^½?š1Ê S%ócoºê´¯7½ù…ËœPÅý/"7cK‘å¤Tb±Š”ö‡^v:£D2LöÚ®®•EX½Ú çê`׿$ËEîÇ7í¡µdÉd.âp×éþdç Âek‡rRFÎG;K21[›!9ÚAw×vž$™ˆo_ßÛ±ŒЧ;Z?“+^ü‹*HŽûê­?£ã}íéâ¾îe‹LeåS‰ØWÝÖnÂLdò¿ªssK’'Ik¶.ó&^¼\,áæRßÚÜPšFCwÕ’#IYƤõý Äâb€?¼6Ù·¡ævˆÙüêXÛiŒHLœ}²%®ü«qV<µš{’—*“1SdÔß—4FZït@1Ï"Šw®<ÿ8Àù7ìÝÊ,'9¹wD³Rö´a%)‘î V?&(w/Þ¶»Ö˜ |¾«uïs› 10¹eãµ)R铜‰ 'Ó§)ºäF0úWç2Àa(¥ £JÂmÅÀ *‰¦\Ä ëƑܽôYäóÊÂlWÆCôVÙzAQE\»nNçÁ¸ÀÕ½gìc=ŸøP{pDåñÕÚ{K†töÖ"y×´M£wÀ«K¹áFØí—'”¾>ŸÌ ’(ó$™Ý;‰ÎH®‰ŽøS8*ÅÏv@ðˆ 8,—.Î\h}šÆHoêû/Àuž³â4TšªêØž#ÿEŒÊ0¥bŒ©âq³No¯}¦¡B$¬ÓçFb¦½šA±*3ÔÃÙeE@Á‹‘paÓ ÏŸ j«ûºs —Èp eë&!UÏ€Pàj9_"å|‰”(PÛÃy¨ÛÆ#‡9n X‘PØkÈòðàå&ätc¢çQ$4éýÓ WÏè«LüC Ûw^þstU,éqÿ$æ ½IlàÌQÛ¾öê jÇV^]L‡z²´K¢P¡Ú`=9ÂsÒðJÏÔ‡ÄVØiœ”,ú´‚ø.Ñ91QGDÿõ×–ìk‹ JÒøøÝ‹{/F#4îÛ®þÓ©”×"©ÐNÑ@ŠröØW1*ñ3£êM”D‘ú§‹8¿{I¦jü±=°Pœ?»c‚ÚOÆ©º ž®¿Ï7­7Œ‰Y¯†Á)*Ô0‡±ÆyåvÅ+Ò:¤¤Œ©´f 5K¬Ÿ‰«1&5¦éo·/yJlã óU¾ø™Ša=wûfˆâ‡Þ—ÒMí~&˜sɘúßÒÑd¨‡ìš@^ô˪õX»—T¦"¥¢ëÄûÃO«ÕÍí;{xyÌéÉ$Õu. Wð®f朄ӴÆ]nÅ–[g®!©BD êfëdTal–Œ5À}wŸ†ù·h6Dw [õ¦·Ñ*²Ô#®öN¹ËIË¿iGOj¡Ò/Ê|™´ÖíàÅ|IôŸžôõÚ¹+°J‰…ý KK®˜H¢†õÚ—†‘ç»÷™lzÝLîC72®õñtÐG÷‹9æès«!JˆLE«i&·õwºÓ¡³É0p>©*ú±ÚxH·¯Aôf­Ì’™ks_ãMÍÖ›WËF®fçobl–a8Q°oÎ)_2LË·¥T‘ôOQJ`B¿ŽRPøxB)ÝëPiYrf9e”s¢Ð]ã]MbýU5ú1«ä”UP?V9J‰¬4•95jÏ*npøÏc8 Sµ¾‚U‰Nö• ¢ôïÆ9énï`|ÝU5¦ëS1FÐmôöÜi׬OHDÁD•B\è-F×`YùtðýLgrÉŒ¶¾)7µ6žùØNmÉV_O™ý„å»öäÓ^?Kìo+Yò~ϱÞFDšhF£´Ù´Ý6T0iúý´‚¹ “'ì¤ü½œm9¦÷m‰Ô xôc¯?c«O̬!žmÛ &¯CÊqø‹OŽq­Õ½3k<íÛöíùná(–ùË×±YÒ¨ Õ'5¹½omì}×Z» ­GXWaf=›®ºCí›N–þ¹¦(ñ¨Q~ÐhGW#+ 4¤®ëk£Œ¦…èïÚé|dAõÌ…Óo0÷÷kÕärëTíôô…Ä V˜—5pÔ¤4x$kk'Ž\™R¢ði×µgǯ©“ÎÌõhiåMu{õÓëŸßܾÿï»O‹¾½ÜjÎǵîHÛ‘n·²· ÇâÕ›`õÓ¯E—™h (Ýg¦Y#Á§Ù£ÛíÑåÅË1¦q+”„I¯ÅøjÐËJòÉ ¿éÄÖÉñ§„úƒ+óãFâot{všù"§Å¯É­î­“<™tºo^yHhçùAñÕáì )p¡ÄÚ†Ø.0¼®¾~ÿöý­ÓEQ£¨¨‹þî‚^Šäv¨êƒÛeIí/ây%›9>F}¾À'q‘OT.Œ É m*%Ø_ )u|‚õC9—1ì‚P}s64ÈpAiÀÌ/g¾ØÜ¬¿\™¿ÿÈ5/Oendstream endobj 215 0 obj 2242 endobj 218 0 obj <> stream xœ­YKsÛF¾«ü#x³]%N0/Ì —-;aR®U,…bv+ç°ˆ и*å×oÏ{HŒ,çQ>Ø5lôôã믻ǟ‹Lý±Wíŧ‹O ¬ÏÜ_U»x»¹øj)œ "+ðbóñÂ|€E¶”¢‚,6íÅ+–¿Þü÷‚âÉBÂï›íÅ«·«õ?WW«ŸÕ/9G™ Âþruýýµ–ç¨à9µ§quøÕZà¦(ƒÕ…K†\#KV ©%JN"ŽyNìÇu·íÕ))P!™3á¡;•ôćeD–Ñb±$9"FçÍêý·×ÿ~£äávpëÊþãõËY– $KÌ&ZAœÇiÔ~¡’æÖˆÍZë÷„tæþ´Òg"…?k>ª3°ŸJìb2íj-(‘Ì„;Ô>åˆåE&¼ûZŒ!*$vú´-`2¤Ä™ aŒ0õ÷>t—:rÊ!Göð;uÄ‘ÌUÌÑ›«[m5%cŸ5c5Ü’ñàÉôr´fãÂK(™_Â$"-ø‡‹e2Á­¶2$„ í¶N¦âÀ œŸ¥÷‡ëoWFüË3É BˆÏdßÕ6R„ùHõ&å!Ì.mÊ‚àƒ:ˆƒiîÓa«o!4®ƒ›^úwï7—ÖûBrfWë7·+}Î@ƒ`Üëµ(ÎCNÖ«­Ö&úþ­õ˜…;L  .}²Ëý±mhEæCëúã»°ŒÇʃù>·3r8 ü¼#"´¥9Ù–ã<.ÇÑä²A÷)ÉЈIhÄmo®ÿ #:ÿ†º2”Zá'\(à$˜ÞtPaZR¹°×Ï;ÊíjãjX³Æ’2¦ºN|fŠ|³«‡ÚB.RW Ó›®™šro¥áy€ssßµÆèÌ8j..$Ä壅[ !æÁЦ–ƒ  ´˜ÏiQÃ{ü:ÝÚ…êP\aZ<³Ùä9FÙ—Õo:ÜL »@`+HrŠ;€¨ åHfï‡ÚDYî5Ò™`õXšv-O q~ØLz0ðS·ç>P|nf -¥›J'šw>SùXï÷ýƒ35´ba øÐi}Ø5SmŒ•€à,î½rÔ¡èæA-æÖN&¹TåiÿƒäGÓ(€§6 P²…·ã ë)ìÓ±´."±­˜ÌUå¾í»„j:—=‡Ã¾¶²<ŒQ˜Íeû¡ìîë„^>—Ð<&NªòÀO†—;CXma´„Bæü`êÃN[2ØP™¸CûÏBÜSÝuÞMÕ42‚ŠÂI~Œ6•¿Ð×GË‘—w3m†ø)´CÏž)JIMÊW«Ífe[& ð¯ú¶-»mzâ¢jš=Û@Ê}=MÉõ’!Of«èNp#P©ÎSwlïê! ^ ®¤Ÿ\=˜<ºÔÚšh|DqÞÁ‰^#}ð3ŸâèÉqh4»™¦.]‡ŽŠzgÇ!|£Ôàe¾E“¹/$1;M¶Ì9§Üm5{$õè®0pâ¶Û‹*¿‰“[}ooûcçÆ2ÆÏ•x®0„µ„(ÆèHÛ,Ì !LNºC˜¸@–€Î “°]»¶Óe4|ÙÐ%7IÈq]2O´\¡øÞ—~¢eܦçü‰vµYüx¡þüDÆY)endstream endobj 219 0 obj 2106 endobj 222 0 obj <> stream xœ­XMsÛ8½»æGè6IU„wOŽG›šZOì‘5³‡dŒLÛÜ•H…¤âÉ¿ßК¡l§j·rp þxý^7>/8 nÿáßíþìóÙç…pkáÏv¿x»9ûi-$¬°’—b±¹;óˆEÉ…”¬Ì›ýÙ«‹‡ê0ÖýëÍ¿ÏTÆ—6mnÏ^é¿Ù5!YVš ×ÞõÕá¡Ùö©s&J‰¿¨Â®ý´.Ä>áp§½r©2ÎL©KU2ã6~ª¶vg&Xn¸Â¯ÿsßwÇöÖ!'V,¥–‹e¦Yæx{~ñÏwë«ßßÿ,\l.aùÝëgN/ág³X Í´ÿ¸;އãèç?Ûâ÷á(§á¨ƒ¤²óÁÃh‘0„ O·^9¡nó„ãC M¬~¬>íBl¹Š0º¬GŸh€‰Ûˆj31(À›ÀR†ÊaWÖ ¸ÜÊO<¼E%6õè±÷¬´ŠoôÚUZ…)›ÕmpCÙf!õ1³fá«w´‡‡v¡KŒÉD‡‡¾ƒÊß Ù¹PßV×76uzO w"zr¨î}ò¥1ßANûÍ5žÖê¿¡ÓàEêRÆÔÐzDÖ©u˜qð-¦;Œ3‡JçǪ“Ì›_ÐÇÜŠPfË"*íSêG*}—Wýÿgé[Rö×€ ÏX“Þ!õ™ú~¥Re¬8PÅ7ؘfIŸèå­'î‘0I;ŒÈd$+Õ\¾xÛXÓÙˆä컿Ÿ0¬þ_dX†™Ï’B„îZ,iö$€=ÿô‹è]p ö 3d©Ùæ=1´V>{¶„‘Ÿj:O©öqç”RiÿT¨Yÿäbc U båù hTF‡ímÝ»é[™,Ød`mÒ›ŽS:½n®A&{à ÀÆà:¡m"/W)“<µÏ36PK2’€†r2ú„sEŠðù%ïVø i”œŽÿøåò2k–Òq½z¿ZŸß¬ÜOZÓVûY×X‹´}½úcµ¾YýÝ¥1³‰šò©1›Ê×pÜbÁ›Œ¿Žã LãýÑÚ%­¤­Ãc³Û!ZUb´§&TãÚºxò}T\ú’û¼~ëôì1öU;,± L*A½KÄáÞ°ó ȧsÊKT¦d1&Ä‚ÒK«áIOrý´’G¢‘‰ _xUV?QUòò$Ë99¿ñ6 ÑÓw[Äù«dÉŽa>}•ÿÃUÅþºÂ¦âÙ»Tº+ûž»È“×WKlºµ%[’|WÞ Å”ršv-Áy×òÍ‹.Üd_¦/º™‘¼èþÚ!UÀä§rÊü·cÝ7O¼Ç˜„È}ÝÛSÈ®º0:‚óT´´²›HŸôëÕï7«ë+G­«Íâ·3ûï¿tI;endstream endobj 223 0 obj 2173 endobj 226 0 obj <> stream xœWMÛ6½ý¾%Ö ?E²= àEÝvëzTlÆVaKŽ$g»ÿ¾Ã‘”¥u’bÆRÔpøæÍ{£OKŒÈÛ¿ð»=->->-‰[~¶§å»Íâí#a°‚4Öd¹ù¸ð/¥ÆKÉÒt¹9-^sõfóÏ‚‘)­àùf·xýnýøÛú~ý·}R„%•áÉýÃ/n¿@Z,¬ $ìâŠc aårÅ5RîIséÏ—¾³O9Fг"¼ÒŒ]$\Ò°¸mÜF‚©a­iwU]öÆÇPˆp2¤Ù|tÛ¢Z‘[qOÍ¥3w.o‰¸æ"¬Ÿ[ @œËá2Ÿ«Ù¹½€±<.{»J9éæUÿª çaWŸªþPÕ.G’Åóf“Û·åùPmýý ,"‚ýTÕ;— µ×C”§;6Åʶ\Ø£íÏ„ÿ‰L€\ÚþhÂ}¤Œ¹ÜÄÙg⠬ó_=Ø196Uc°Ýy É„_Õ…÷y*°£´Ýf—˜aGø (.¿(¨.ñÃDbºà“óHÏ;–¯8A$m=»¦@¼ÐxXjºª¯vÅ4PKWzMHšLÈ Å’}á&;L5ã‰!d¬_k ÚµÙ¡Ð+LÅ^Yÿ»5g›å÷®´Qr]ÚQ¨Ò.)TPÕ¤°) ûáÒ÷þòÌF÷›KðÜš® Ý%­¤ f Q=£³DÀ ÐZ¿‰¡Vòޅ‰fsÜ…FÇ2µô¡ò]AU!¦Äù°kËýÞÂm±òÖH·[ãÛ ½ÏòŒ½’AY#Þf;\¤Ìüý@—@ÄÆº4ðÒÅçÐM±sË.(VF’ÊÑQ# ôe¨¯nc¡Ý’D‚ÇÓú€à ÆÕ~Ú’¦n.ûÃÔ<ú&¹OL½Þ/±j<áXõ®'ß>J²´¸€'[K^QY1²\Qð_•õÓÙog#·Üs[¹·é÷›ÍÃï„4,Ö÷Ãâo^MüßÄöIúdìÍ4yóæ1ÐFÈx³÷ëÁ¹ÄU¡à„ÌK_;K9ÓE1§͵nŒŒÆ—ÖH2«§:P§}©¡y2ØYq!©¹ÃÝÙ"×ÞÏ~…)5Ô´3Ö;wð•‹±í~Hé %»‡ÐY[=Ô[/II©R«d¢6i>Ûáï6ØNJ ‡¬]2þ  ÔšSYÕ³²6èÛ‹Ï$e|©Ã*q«¯ŽÐbZÉ—¯&äôj2U¤5GS‚Ý J” Ò|ÛI"½Ï{P'x“\åµâÐ[„ææŸÓŒá)Íp’½±à‘ñ¤Jaö¥PLužß`<×_œš^P*,­|«RQ•QÅïüjUbÉd/ØO$*S–¡”‡‰”Sh.ÁéYþ1㘶ÊϾéíùCÓÿtÿ×ú·“ÃX«Û@!Ú§*|r‚h£«~Êʯ\üËÃOI >+w{³÷úJ€3…š·éÃ\¼›šcÖxæ¡í§Q®9Ä#βÍIt³M÷ݪmÙWõ>À‚Ó ãÕvPngíC² £n×éÓjZÝ8ZdŽæOÄ—Ø îÓ§­ŽÏ.9ëê1¹pgšÏ¦ôú}-’VÍÇþ.K„ S0^ÐV~Ô€Îpð1‰%ÒµÕA‰`È ãÍ¡pgÓÍdhNØÊEÿ0í õ„Ä®øEH%miÎSá6m,1³JÉÜ=w½9͘© ,Ïüæy:F´fÛÔßí/~pƒ/˜¬¡á:㪺Þ,ÿ\Ø¿ÿ¦àwendstream endobj 227 0 obj 1348 endobj 230 0 obj <> stream xœÍZßsÛ6~÷ôÐä¥i/B þà7§q{žqâÔ§L{qòÀHTÄ‹D)$åÄ÷×ß‚X ‘Š67w“‡d ’Xì~ûí·‹|œDŒO"ýÿžoN>ž|œð~Íþ5ßLžÎN~ºæ ¬0)>™-OÌ |¢¢‰H¦âÉlsòøçU±ëÊæ‡Ù¿NÒ˜¥Q’ÃC³ÅÉcqª×xÂb%c\û½_‚½¥â¸´m>´»b^öHY.b¿\ÿT­×ˆx‘¹ó½ÓK9Kså¶2P×Ùoê¨/Æ`3M|.ßCz@rª,¢‡õGŠ™ÎúnUã52b‡þq­H]ìÛOCÞ®·†"ûÅbÝ”Åâ®÷ˆ|; ’³ zvÅ8$¤QUL¥j´ã¢Úï’QÓï†ä×­ cyÊ Gâv†_”Þ ‰>¥}¶O´Ö À:qÛÛ°rÈ—…h2g™T}@#L¦b½~±ÔÔsÀaÜ$äž+»9³Xö@<«±JH_%î|4lÌê7÷=6€g¥ÏбÈ6˜È‘’®ä,‡kÄ1SÞ…‰-0"&­µEB¢rŸO.ìGËÅ|9•î媞¯÷‹ª~ßsQve­ÞÖøˆE¹ ü ÀC‹xà‘[Æcp¦„;FÑ$€hÿHÜ\›d®ÍGÎâˆéÜ¡ øÀR?ì¾_´å´ªÛ²nÇnû JÀZj5åsŸ"Œýª^W~!ï3 J(]±ÏÇòÖ¦pñ.›»¡5[Í%H%‘ÏÇó3¿/¤t:€0s`uTÀ¯Î†®ø€@TÞãÆÙåî)ÿre| /tƒb·²¾OçÝÞNx˜Ð£}tÛ,Z$âSÐ…ž§vh(ÓyzvF~­ªñ¹$‘<´qšjå{˜>ºf?·’Š·´¡YWµñ¶¶ÌKt˜®µ~Ï¥á†27õ{Þ!‰r_ÁG²Ñ¥rP%Ö–GüâÇý¶ÃÜ%½¦m ®DÇ–„¦¨Åö>`©ÿ6$â~í;ñšiŒ• 蕆Œ#‰b½/:Kðtâ*kùy_oÁØëB0•å”ÔQעܿ@¦Í´î»­åX܉ry€W†é’{o½’Utß·C?~º7£‚†ð>’bBGïíYAxtR‘{ÕRrtϧ‹Ù£±Búö´ÁÞ”EÝ2£J§qN9m¶ªZ»½p‡¹5,‘¤ô6-fCUÚ“¬CI,B_™÷БBÔb< ÓàöܧCÑTÅ»µU.™â_¨µ-#<™Ž&¨.\ø4²èä>š¨®•ôbà ¤Íkä8gËÎÕƒDfÃä(ßS¦ÈiRg7á4«üt]S|ëWAÂx`AobV}v¹Ý7¨†‰:ÿPÕHÕZûü ªt+ ‚ö F1÷*÷G¤ç 6všœæ†²ùñt,9¦={Ô{j’â-‚@z,ÞœÎþ~ñâ׫á׳¿©·†à£¾¥ŸüùCr|,‹Üc×çÿ˜ ýÜŸ®/L‚fÔÍé¯g×//ÿilã*ÕLEüŸ~SÓžÿröê²·.1ÔûÍ;“ð2¢Š(cvàoнàs‚ïó[L3ÉJS×·ûØ"ìÃíö+”3’vò#£ƒç/.ž¿zÞgt•ßÏBàĘ»™WšgFæRV^]µÚì 2«ôâ ÿTˆ³èùÙzûžÜ9Õ¾¾*8Sï) ¾ÌaôDrØ‚qh帎ˆÓÄî󯶾Ó4ç¢Yåw- ¿çF‘X—^ªkýe_—sgˆÈ”¶Ä§ Zh¥Â_ú„ÃÈõ~’TÙýÕæ5¨‡®¨Ñzª£î[󽜪C…ÎõHÄPþÛ6åÇ}Õ˜."Õ’ò€*m³QXÍïd‚±B½—x& C"k©iÑé3+0 6R)¡¦ïš¶c(¯„ï°Ï,pÝ”98‡®Ùá9à”'E‚ qZTó¢Ã¯Ñyqdj P á°VCS•«@‹šAì±Áœv@0@­·]á&‘¸|i%Ô÷c Û:rmR!#ÀkÐôð‘B ÈUâ0{!öùýÙ˵YÎaÿ.qŽÈo¬*)–ªNF¿Ûö€é ªjªº§sUsüzîá¶Ö,Ì =¨sF„0O^&uÑ išÆÚ&EÀÛ”ºí3÷ hNo0B,l׎BŒúu´Ñ[nm»¡´,õ£FÓŒê[ ¥#²ˆ\õ󇽛«¹¾"Ào-ÊeM3»…Þ·d®Í5ÔëA¡Ýôíx‘—ë›"²Ûï+tXDQbLûî/óDá™(™ŽÝ×d(ÒÅ´ƒÛfA&\8AÌi¡1C©©™»ÁœŸq:u †IÉØ\“LJsô°gh÷»Ýºr”Gæ KLªŒJpa["¤ŸèYŇðÄZ¥/áÂ‰ÅØÔ ÑK‡Å‘6 ƒµ$¬Ð…£’¬¿;ô ÁÀÑAŒñK¢­sF¸Ë#" Û²Ã@fþ«ãÖ¶Þ{é§µ™b8Œ¡³ØmÛ!£ÒñRmgÎá=­[d«ÓÐh1”4!Œãå¹Å šzr½åGÆd v$§Úý\°-›m_ãÃ+ºu¹´WA±8¼¸Kh“ÑTïWÖ2{‚û'Û‘· _€Å(ü¤|ü‚9š‡_ÿøÑÓ€-}ÁeÖ±‹òw…õ_|ç絩¼È$ŽeÑ@f7–Åü9ŽŽôÎ?›Ýº'uͲ¿t4‹áÜ'[Àùpû¯+#Û»ä›Ó¶+šîÖzRèÖÙùwY5楰£Æ¯+ {žïbé¹÷P)÷"ò¡=äœêïÁÔüO«2¸üªjÞZ “=ï †¥è9ƒ[šñˆÝÃØ¾ê–ùxü;KÖdPnŠLÑÕ™Ó3÷•À1Á¶ÅÙà¾Rê¶`pƒ 1ð…cUà ù`¶Œv‡ÉùÐsxÂà~Û›3 =iÇžZþÊí®?¿Å§„7Î_ï‘úù­}fè¡_sø§p®±~>ÒŠÖú¯snNnGõêÅ©$glè\GrØ:›ü_‚Hî'ÚA~!hºŒCZã(!¤]G qv?%„Ìñèó‘ÿ磀¬³HŽÅà*'˜Ã!Ñ|r,ÑÉÕÊÿ‹_™è¤`¢|ÂMQ~`¢‚«õ«ü’‡~É¢1¿¡ ñKüEÇübêFÕ‰^ðÿ;dÇÕ£Äw0ÔQÃÿ«Äé7‚V&¦ÿ[ÍkiE/²G»ê/•Ü…ÞPl¶—G88¢f”£`×#­ƒÙ½a7Ø"—y–qvÞR‘žæôÚeTFÝ?J WgÁ(á|6ùíDÿùÌ;endstream endobj 231 0 obj 2983 endobj 234 0 obj <> stream xœÅ[m“Ô¸þ¾¹1Å—U»:Ë’ß‚°—¢GB† ðÁÌx‡{™–ͯOËj©[cÍÌn8.Å(mµúåé§[ͧI"ä$1ðïÙêìÓÙ§‰ÖÜ_³Õäñô쇗RÁЍ’JN¦Wgö9©’I¡”¨ÒÉtuö}–<œþûLÉ\”U ¿Oçgß?¾|ù—Ëg—ÿ4¿ä™HŠ´À_ž½øó‹áùLTY®p5™Yüᥠ6¼Pe%$¼{¡+QO¾ù±í®wÛ®^5ïì+¡ŒRÁ“ Mn_˜.Úy0ÍEªrÚ5™ ¥Ê×êa)™®$.­›Ívx99{ÙH0":ÍÜòºÞ.šõ°®…T:Ãõí¢îP‚’>b×@ÎŒ$请mßÕKó‹V¢^m¶|?(Xè¼JܓͬÞmT±âR4ëa9­DJ_ˆ)¢ëǢ͛«z·´"¢màŸÍR&$(Í+r¹vºÐRŠ2“c”Äš£ùr JÝÀ1Åð"ØÉ‰2u* ŸóÎPSlèBÓÒºUðÔ²µÆƒ3±½g½u&@ŸÔt[·]Û}@ßVäÛµ•žÎHWþ yÅê܇´žmw6–•ñ@2¨9ÿ×sZw^‘FhçÍ•URئX*®¬³T æÍm]Jš˜-(À·(n‘û5æÖ¶I%ª2c¶½ê×è¯At|ÚµkûŽNE‘y°Â§ámÒPm€6UmÚ×¥×þå—zu½l~Œf '/ = }–[ôxRI°: z*9€C‘¸šI¿jRKŠñ§J¯êW}ÿ—SrWó´Š<ý¾þϧuôúéóWχ,Àv£ðÞ­p;–ÕbTß1I^$_Ù%£Ôãqĵ9A3ÂHÅê‡S4*¨¤‘FInà¶û®k· ’Xž["ê Iîp’õd¼PŽíïdýÐ~F­0Fßt?¡[¶)/ÖL7à¦Ý4ƒ¯fRhÂìvK§á–Á)¢iïk-ŠŒ”ê+-M¯îU¹Ú«# ß ²j¹ÛŒ¹ IÏ"ð›K§*èBi0ˆV±xK9L=¹™©®ÉèÌR! –…_=ÃC$”q§(\šú³~}”ÊÈé+‹R (U$J˜`”f¬q$J?V¥Hy7‹v†êÑD‡èȲô§ôñ¤c½Ž9·?ú é} ±FÔ}4äÊý¡ï’"ûD„Çx :x¾—’ Pˆ¾Ù¬±qÐ®Æ h­aÉWÖ7ÖÓ¬6Žï¸W¶¥{íG×ucô»éfË;Z‹,c‘ƒ&àe½n\ÏUr‚U7ÍæQ:!_ñbðX]ÏÛ®^·Ë[ÄHUøagÇxueú±7ðÜœuêíÚÕÞÑ¥JŽ%_šblFOóYGñ6bÆÝ˜È°“§6èpäš/_À4¯†À÷-Tÿò2E¶閭RåðfÛźiÐ8Ì 6óž£K7[ªùLêÜ1‹–ªÃûú‹U‘’Ư´W‘¥|`a•ÙïYÿ¡w)Œ`*…kg“‚]_Í7èàã¸=1Œq(²¢Ò +³fýj…g×`AB‹½š@&±°n.SÙÖÍÚݲH~ÁuÊ%&4oŒ–‘KhsÝç™ÈŠe_é.›E&2wrØ?³@›H;¹šØò¢^׳­E@mÇïcÏvš ú§fÄöŒ¡OZÊêÄýc,â!á&´µôñ¦ñNÆùzPeÜ@új>£%ŠB{¯QÝœ5v›íz73öŽ›KSä~M¯ypÓ1ì%J’ëö9¥œÒ ƒ1"#ÞàÆþN• øávŒ“äôMòûÎ}Gd”xç(§íóbI0rX!a¢»»BLÒd÷ßcBar¡Ûâ>×¢Œ-÷åÄáåc4Éù"ÐjM ¬Ë_žëž…œ˜¨3 Òpaêbÿ@õŠ7ÒK3ùaæ> stream xœ¥ZMsÛ8½{çGh÷”©²0A€äܼcOUj“8ëh²»•Ì‘h›ItH)ÿ~@hˆìdËWA>º_¿~ÝЧYÆø,Óø¹9ûtöiÆÍ˜û·ÜÌþ¾8ûå† auVóÙâöÌ~ÏêlV Áê|¶Øœ=ûí¾yصÃÏ‹ÿž9+2¡`Òbuö¬üUqÁòºÊqì_fö®jŽCýðq|h–­Y `ªÌKüäe³mîÚM»ÕIÅ”â~´ÓC¹L5I®ÇæE&YY³yQ³Ên°ß=ìw£Y?cBùîîͦ¼fvuƒíW»¸`œ+áykfæ¬â?õõ‡¡7ƒŠ.ÛÕ~0“EÁ*YHß6›v¥‡¹‘¥…dæ…5—zªûDßRx‹u[4y&½É“Ǽ퇹¥b¹Pn£ö냙Z²,óSÛåÎ2¯XYøC}0N‘š»™ßôœ'¯3wÃ˫ߟ¿º2@˜‹J²JÉÙ\ŸÏº¦ÑT¬®êÌ9eÝÆþ¼b¼žÚ_o=s<·@`Eí­ê.\1Uù[ü4ØesXâô²_™ÉYLsoï&ÉIWí¸:cˆ†2àªqUUOÀªÛ:`¼ 7è§‘“\àq´‰°j³]á½²ª©eÝàТ±ø1äIc j¬ynÉ7þÎí †Ä’ø\w[kEX#WtþuðWg-È!dÂ÷W+T¹Øè=`ýÐêÒQì̬£yVgŽlö„ªz„'V֢ܯˆpÐö‡Þö;¼t=´ïˆ¶)t´6»]·½3w’„ãy ÙO»ÞÒdÍœ±ö#Æ­¤ÿroù¢¹*=¼Ñ óBC‰+â³ï‚Ø=TjRvmÜå î ²jÚ¶«s$ä¢ò3î ˜8dQF`;e!òR‹.íýuЄ˜ÓÁ½7>ãþðsЫÇ\›œâ×ÝРy E“ÈFf‰ºä3ÍtÀÔš¨çy´ZCbÊkv7~ݯ×G‡)@ûæ†ÍÔßÿxñbqõï…ñ1g’{Î?•æ |¯§ÎÓe>I‡š ¼õ›inÚà A!ý®»`Ī¡‚©TªžL]©Œv9ug JdĪ~ ûu’q¶Çân.JÈnÚ½!»u#’Aö6ö>;ôµÔ® lòŒå…·Çó[\A” Ù‘O"¨Ÿ¥ÄJ6JÍ·+ \ÿínwô´²¸>G6,©®.Ÿ/Îq"úaºÛ‹kŒüºô¸¹¸tkªŒ&¬í”Õ"£ø„enöW£Ö/Ÿ@Â|$ù)Pã~"GÊD*$yhjÕ~XY.ȵ(ò׿j–¨²ò–ôy}rAÄÑg'b4¡Cúm‹K›Ú/Ãî2dö]7¸™2\\sä e@Ìé‘à¸c‹SU R³æˆ< ‡:£¦ÂhѨ Â…¨Æ49®gÉ*$ã‡ôòè„´4’ÎQFÊíËdN¸{ܯwÈ:œºx½ÆðÁÅk±JÛÅsKÿiARÃ~t²AŽ·®¢aÚ`Ô {‡,M¶ÛÈp¹ö—[\³)‡¼êwí¯È7 CDE „t*Ÿ¡ß`¶'îÑbØŒ–¬Tíä±;³¶¡ú"yeÜw»æÃÚö¡tÒóÌr‹‚EQ×íGw ÂÒ^G<˜"Ê,¶Æës½*‰?ȵn¥ÂýM›È†ïמ#ñP´<4wíT%5²LêÝs‹jÚØx§uÛŸ®>Ë ¯QÓ«*Ž«*~rU”xೀʋK<}Ô‡:²8zzªØÞYÚu¡V&ƒ¬KR¼ÌºÎiéøÈ:+×u;æå Ô’swÒo«öÖ.1PB|˜ª.·¡öÛõëÿÀy©%í!mÛ/®À‰?è׫£Õ€‰¸Ú[ö›  s 1+Iwõ#r\ăÕ#‡çŽmCŽ6éFJH“‚R©:”?¥I’èºUë[pìºe³F/5eã)qrÒ‰9a»èÌeý ÆL¾A&í°õó÷¦AHñ¾!'gaÍ”t Â4J²†¦u«•vfº ÐôgTYhœ[%«‰çIDÆÅé)Ï€,oŸ& $Ь‡¶±=6-Õ0hˆÓuC/¯ Ò ßç®ßÛŽEAïyªœpj…Òºw Ù†ÔcG-C¾ú–ñ"¡qå&×½®¨ýM TiÍEN­áçií„·ÏñªEª[L 9´‘ÁdÉÔ¡µˆ÷B’$\RÁ¹ð‰ vÏ~»nG[àhhГÙ‹I]xH ËÇàœì T…ÖÉÍPèë¤oj*,螺£B8ÃþM~ìD뽫•ˆÂXÜ æVýãÊm®+> ÂÈAqÚ:\uͺ]âk¤—@Ô¾º&eü‹þ®G”…&̪û‹e#ØV’¦S%´'×'ƼDÍ‚ê퇕_³JtâÕÒq­’Óç ²&>c%¥“§¿îâ¾óÿРFó`’ :,™³À¡º‚ þü[ !ñƒÀË‹\™-ʨÐ&8Omæ'•trƒš ÒdÀ šMdO8è«‹—î ¤ gÊ~ð s.!ÃHõ¸ä´ñ† xK¥n5X§â› ÔYè.¼E!wÿ?øÚI樖L¯)ÕS×DÅÍG­¦‹¢Û¸šÁ¸(TngYé›Íu/Ǿ€ÇÝá•ÇÃ[”Z5÷–#ô)sýÖã$Æ%M[ç¬PwðÅÌG—4‹<Ò)~Jð'¸.¢ôqƒ†ûÜ Dݪø>;Š ³ªtÖÔØÄÇ“HÙjäz¹ÇînëüI=Ù“Ô¥±0JöN&@ªpS¿ †X9-wK è’ è»q—Ú”çUô;€}è…fÞ0S݃ã‚bö¾ÙÞá{ÔuÞaq³Èu …'~¹5Î+BGènݰå*ÐyEûþ;Eâ| þÚá¦m ýœEmŠÀG^™‘®®8¤kô d!òkŒ˜ÅIâý³u÷ah( ^½V›rÿýÏiR ]±ma‡ÅÞ0=žúu@ZØ}ÀÆ\ôžFB¬œ>0FPoœëŸeˆ8†"Ö%ýðBÙ£{N#Ì ã®³žé¿ÿ‘ÑYmendstream endobj 239 0 obj 2804 endobj 242 0 obj <> stream xœYKsÜ6¾ëWLåä¤$„x“ÎÉÞÒzSQ¢ZG‡Mâ=P#Jâz†´‡3réß§4€æcFö–ªñìÇ×_óyU0¾*Üþ_oÏ>Ÿ}^q?ÿ­·«·7g?¾çFXUT|usðUU¬¬”¬«›íÙ+-¾¿ùߙ䆕U ßoîÎ^½½|ÿËåÕåî‹Ñ¬°Ââ—«ëw×~¾f•6G5ÓnðÇ÷–¯¸dœè¼PÜÂ1vu¡*Vú™›ÞMäœYUq\½®7aµ_ײBÃFÂ0QâéÿxsåWL­pƒ§z×ÕÛÆ}¸ˆ_.àâ+mÚa?[X„ã>䵪`Wz¼–»/š3Í“}ð‹À/²J_c¾ï»å‚k쀃+ïg‘~»­»;æw‘Ìdû¿Y¯›Oû¯$4ø¡öc\°J–ÇÚîÓ!Ì•n<]¿ï¼­à<-lœÜïpƒ’§ ¶ýÎÏ”ÒDË}qC–éìÁ~w7œãD8FزvC%3¢*b´E€Ãá”Sý=FJ©Óâ哽™„e¶L'¿Áµ²L3Ÿ¼1‡µé.»¶¾Ý4Ï¢HÆlƒ1 ¦e™¢t×Ôûæ.ÄJSœÙ=¾Õ0nl|BS¯ý b¦Hƒn¨3U…=ñÔýc34ø0%ô7ÛþK»÷' Å ·UÚµö¦U2õâ¦þJ¥K_1 1âÎ6Ä<Ñæ‰.¼SeŠœq7áAœnJÜ2öJˆÛŠ&W¢â„Ø3 JÉ,¸*Ž!¢€7H€ïûùõ÷áJðN‘w\v»¦óÇCÖë”6ûͳ÷¾rÓ•$Þߺ®í|VrHŸv}‹x躹;ì‚ ‡Mž}Õ?ôÑå9ÝN[v°ÙB÷ý¶‚Õš:^.ówÏà¥ÖǧRL©t‰aÝò—((Â7!jy‘Óvw€+ü„fâ6™©S-™úBRˆ*ÆsˆbFrf²ó¨çˉç}ˆŒ=¡ ò”Ú„ð5æ¹,’aN¸ ÂTé­mL 1A8(šb zâœvC§ùõ}D ²a‡oçÚŸñâÆ¤=‡Ã-ÞОÜqtwýÔvsóáM6¡ð"|Ä£¬M§äš›Û°”Ôõ…;çV<9÷Å,ÇÉDF$uq6qaÇ6 b+È{ŠØÏ%žœGR15+/ˆ© qõÜU 6m‚åÝP<µ‹Ž'5 íÚ}Zr9æx@mÏEán®3Þ7Ϲ D{oÑñyù!Uà*{ÀrÓd›âÅGf†ö¡ †GYá:L.Éúå‹cE²n>¼jØ;G0$LÊšÎÓ}óËe Wàh(meE“|é÷™ÙAÍ…å Ìåà%@ÓðÛï›m$h™ÿafCøUÉÁ‚ws¬ƒ[´;¼/ô‰:¶ó r! îèpe¨XÊü½‰$O”éÚ9Ký×ÛU9Ò™ UýÐ`øÈ|Íçhć0}ØZ¸€tÅ„ÀóŒêoëXtL5ʇ)ÿ¿ÏUÎø¿{‚7…[däÊ=ØÝfbü#lLÿ?í¼ÝÕ;Ÿcî=Â×E!˜*Õ×ö_ÃsÁ/0–ªi,¦*ù,ö´1©;¼|iN…ˆÊêü|Z$MöÂy$ 9‰6íGt˜$vŽTÞ çèCROàý‘7Â: XæE™)ö>V½Àƈ Ú'LK®Õa`J;ÅÙ6ëÏCí/ §iWxêµ´9qÑrLyÊl¨Û—sÌ($™·g I¦3‡Þ¢20œÈÒÄìù,•±éÿÍgrÔr> ¨‰Ö5ßxÚ wâNU€ii–ÞüëçßÞÍ3îX—Ž(ýúó¡‡zÌÈ´y§,ýI ãúÃ>v¸Žõ¸Ðáž(>r¡ó”@jgÙY$½Ü»`¸Òòå±íœëÄs}Ž/m°Ùµr–£ùŸÍiéÏ÷‹`És®O•Ú~¨ôš”¥@D£‰±‚–Mä‡åÔ£Ã!¶¿¥:Õþ5£kYB3”«h‚IÍÐ5»m8 ¤œÎeáüaA?#H•Ù—²¥œ[I“Ü &Ÿ¹×« ‰Oø†N?ï¦c˜F*û6Ò_8>GâºßôžTdçvý¾Þ·á‹r7Kv\R8‚{Á“ä†Råúöv×<µi+#æù90e=„äKHV ·‡=Ž"úÅ ùÔ^¬r…½m»tݱà¥v"y·1f}·Cª ²Y?v7‰^J¦3&¿þçõõÒ)fÊfÊÞÔ¡ŠN7“’ÊCG ÷»cgVÚ—G˜)]›G+Áæ¿]Öl§¥àÝÕõÛ*–æð… Ç Ë’fK— ¤ud턎4[¢ÌN4[ÂOh¶F¸†â(ÔNiXm9ÕZPQ“NzQCD[ ¿_Þüç?ý¸¥Œ4—s•k<ˆ¢/Žëx?€žñä{;Ós¶“ÌP™ÝEA‚HlMD`•$4/"SzãÄšg žëÊ·H~ÕH„BT-Å¢PNZ”Ÿ¥y†Ž\å¦Î„ Fô²¯ˆ 4£«íP¥êV–SÙB.fÙÈÔ›æ¡Þ0Äm’ò¿A‹÷‡‰´õÍýJ€CÑá…_m òˆ~€¦§]È©NÁÒHx©S¨:½ÔIþ>ÄFÁRYÓAï9ZKRQq“ÓŸ‰~øÔ«¨ž}"ìG¿ÿqÿÚOçÓ–#mEìG~¼*2šGDó¯•c@§a‡ÇÄÕ{7'ucòKfÛ {ÔT¥…Ê4÷„Z’›L.w§Ã  Ô« eñòfõï3÷÷7líä’endstream endobj 243 0 obj 2405 endobj 246 0 obj <> stream xœ­YKoãF¾û#„=M€QûÁnöîa‘L„`€‰Ç++È!ÙG¢mnDR£‡ ÿû­~VS¤d)YÌÁƒÙ]ï«úªùm’:ÉÌ?ÿwÙÜ|»ù6¡v-üY6“7æ”à љ¦“ÅÃ{Nt6QœÍ&‹ææÝǧr³¯¶ß-þ{#—ðÐbuóNýìQN˜.˜_ûÕ.ÁÙ…¦~©Ûþ±Û”ËÊn ˆTLù_~.Ûò±jªÖü”K"%-üO{³ÄrNr¡ýRÎÍØ,'T.$36OˈRb2šÎ.bŸdl˜…³î¶ÝƬòœP‘å~µÚÚƒ¨†GY0øÕ»¥3ÅýÒçz·ßùã{!›Œp•ÉÉŽË¥}ø¶ÛW64<#™Ì…ßã¶l*»$Ïâr÷`£Dè"X°ñÆ2F˜’üÈX™‰–YcáèLg!/ë`,£¾xP¹µ) Š0¡B¾Êõ‹]ÌÓ=K›’±˜Ã×I–ÇT/Ë]5­Û]Õîê}ýlŠ<ÂñæJÄÇA¨ÛUý\¯åÚš“Ì2ýV€j·ûRL ¨0ðc±ï¦’š4¦j‡…t³­Ûe½YWöH¡HÎ#ú«çPe1*Õöu‡KJ„n·«¿®+1&b5o™¾lª<úáRGÉ|y Iòz¡ŽpÖÇUéȹŠF][ï´ÅYZïl” h¬w}ø‰>üLHôˆX|€Éåzm㚀ùÖU³qÝ ÐŠ°¶A¡ïÑ^¾D$“4Eõ}j.Òùs÷hW™2Ø »¶>ÕÒ@ãâá’ãë®ìÀ¢’ø`¨ÚIòJOü•É yû÷1¶ç½„µÁKØywXzÌBõØÛäÈÌk“MMo›d¹`¨†»ºÐ—%ÕvÛmßû6 ]:ÔÚrç½ ÝzïÛ“DwmßT©cÝa½ò• ©ý¾c(`{tìЮª¿µÕÊw6NYBŸqŠ}aY­®}AcË€vI_ëRl¤ lë2в–õh¿³Hå*m9?öž<ÍFæK¬P©šÐö8`õo{2ÁÖ÷v~YDãöOe Z޵uU9IÒ¸úRïŸÆ€Á€”ú<0úØÖŒšN}vWVÄ(ÎÅÎYŠsÛ£(âX*”~÷ñËíÔu0 ¥–å½v9»]Ü»†Í“y÷ùÓ}ø"Ïb€«ý’üþ'-â1eFcëZWà sÛ® %Q@©\¥^AxT2 ´lŒ(ôjáú”N¸4š€>jÒ RYmA™‚…Þžªö¿IÙìŸm~Mƒ‘úl€›ÍAm8•1å0˜§T—y1”MU¶ŽOLŽŽî»¡ÐhÊ?¼!EÒbsóDÍù˜¬FÑÑk…"õÖ¶ÂØb½:TÉ~Ûªéü» ß}öúX›!Ä<%¡ßdhã[3ô]«ð|Þv]*oœü0Wtbhd,6SÏlO€©üðÁç °4„Af9®ÝÍ¿Üy…Ó߯d<ˆ$˜2κfãø T èsP“¸l¥2@ÁMË®iÊveýÉAZäq—ïW«D𕮿ýâü:³$ŽKÅ‘¡RâpÝ Í€ÐЭýÿXIÈ ƒÆÈ€ )ä í9ʶ& ŸJS7°**¦Rãú·‘hš%¬>=³ Îî5¼“à0 eð8À>–ž Àß8s]æ§¿„ð!”aT‡™%ˆºÃ~spí›i,aˆ×ò²¡— †;~Ñ7Z˜JÃ.0_€`áìÏ2N…U·Þ@­®4ð,ƒáÅ5 b S…I+éŸñNDêc»ûvžé0'Aúó´Ý%t¥ûúÁ.˜h¢K<†éI£¬ˆƒ]vÅÉ…]2¹hÛ²äŸÌn¿Ž‘ Óó”ˆÐ/¥â|ös #(>°Iž #’‘zsŒic‘ ðPßÏC é–c wtä‰ë~µ×8G#½°¸¶¾ÓôÊxµ ›mP-Ú@>,ÚQ4©9=ËßT#g-?jLæ*ÓIw@úCãÎT* ÏV(y˜ÿ Á?“*žS³ö1 íxñFC Mîr|¼ì hÜ8¤z­’^.އ—§Î ~˜/f¼sLGƒÕjÚú,æˆÝC Þ˜|uÚ5½Dƒj³òuŒ£˜lªÆ#@b}{ç›X–áEüvä:‹hrÉNìîâB¦CžWàÇӀP¬Œ£7ˆ­Hf9¿,"â(" oàüœ&м6,’db¨`ð(S¯Ï«(moxÆ>6à–ê‚j„F†ñÝ{ä’¾géõ"!ýp¯Ò4.}Br%GÊ„"<áÜb¬d;ÒÚÜ›²S[z#á[0MoÓ<›ÓÛŽ¥‹Hÿ3Ôë°Çû䥡{¸Yîý‡#~Iºþ¦9/ú7Íÿ U£ºtÍ>¹x*ÛG?É x4éËoA ä.Z».ý‡WÐFI{©Ý< LMn Û.Ü(䘦|¬—áJnr=nµ+¦9á‡Ã¨Ï”zSž!8ج£+U¹]×ÎÎSIѧÛa|ã:úþk¾ÆpÍíX> OÏäð¯`<Ï¢­É—i)ÍýW8ª„m_íÆ5›)œpn®;EÈ«ÇEñt÷š£BàšõºèüËÇÙ¿ÌgVÎIF(; Ë Åâ{ÿ:ýÞ û*I¤ÛçÄÐU`†Î~„Kn’N(óa«[sESËu:rпqŽßš@à,kçýoM}ápæÚl¶˜üûÆüû«:ÒØendstream endobj 247 0 obj 2344 endobj 250 0 obj <> stream xœX[oÛ6~7ö#Œ½,-bV¼ˆ±‡`]½-X𦩻a@^[M´Ú’#Ëòïwx§,:M‹<8&yîßùަÂÓLýÙÿËÍäaò0ÅZæþ-7Ó׋ɫkLA‚d&ñtñib.à©Ì¦‚R$Ét±™œäìÅâß Å²€ß«ÉÉëùõŸó‹ù?ꞣLa¹x÷û;}>G2çÔJs”+á«k§˜¢ 4*…3†¨Ó“¨Ð'·]½©ûú‹:žc$¸SYmÍ t`òŒ$áÌŒpDÌ W×çoÏçͯ´uÌm摦ÜTJ:sâXC†×ÎŽ_; ØLpÄÍ3ÜÚßîûí¾ß©Ó R@(·o,®• C$DA¬ìã\Ë$Ê©—ÕŸ´ îŠ[Y_Ùƒþ`Š”˜HDHΜXëÆ‘Ü¿éî*ØäÀ)¸NC¦Z£ž(3úR‰à“™Ksœ&ZÄ ß,nõ£aîÕ/«Õ¾Ó‡)C‚²ÜÊoNÚÆØÅ£Þ®Û}½6Þò·UG ì*¥7Ú¨Šªsᢽko^ {–e¨ 8ÊýeÛWöí¨hûû²·†`饻ֆ *s6 ”ö8ê±LЯÇB'ŽB2 _4«j·ìê[ý…fð?T+[M™ô>šX(§dT9¦Ž­]µ¶FŠ`ír¿©ô4C9Ë]:z_ Ýàt—«¦"øµ®o»²{Ô(ß¼¥O9|ªÛj ûòiÚÞ$IuJ–GIz¢äv(‰.îÔŒ€Äô‡¦Z%¡aúä›ùoç—ó7Wˆbˆ8±²1+â[gÇo0ð“šW¸†ÜˆdÙó@Ò>‘D9@ œA$ÉûQÚ#Á£nH†ì¸FÝïªnf2¢17CÞ®'ªF ˆ…6©›åz¿ª›;1hæÁ ¡6*Õ•€kŽSø„jd;”…ŒÜœüaŽƒVîÃòŸ è#éܯ¾XwVݩՄBª1¥:ÖDY†éaÛª‡Iñ¹qÅÐDõ ÷6–·c%íÞ=˜‡ªI „¸ÿsÄ‹çô¿Ž=øï›±}½ÖB@á`ÇfŠŠ0$¾¢K#?ƒÒ r_îF»: Ü« 6ª.+¢æC\4^:öÐ~¶©QêWèæE´4-—³ó=ö4bYæsùË[Cz ¨„ûföxåÄÑàƒgÇoŒ°Š¢š|£(¾ª¤*b&ojT‚Ï„*^¤øN ª(} ªlZqh貫ËÛu•ž<„¤yaÈâv]ïúg¥ñêâüÃâÊhŸG'ŽÈ«ºrvüÊ(‘9ôyâÈБü™$g#æª31f®‚'‡ŽdãLÊóî;¯€©dâ¹èOéÆ`¹— ðËÍVëgPÅÔOèÇ—ÖOJEç Ö TU]ï —øú|´º¨o|•q]D‚÷óæä¼—7ЛfYo×¶U¥ö-žKé òh_bîÇçíV ôÚX: wºqÀÞQ¸!.xnÕ,~kÕ.#³<ŠàÏ–¿fŸR˜ñ˜Þ½QAÝ—¶È¢ÂM`vÕüÔ[½"pÿ­†Q5–ÍøÅÇ0 ód XDm渊nî×rùƒªûS[á"0 Ýùvêæ¡ÆLvf ´±âGƒ3ŽE)–Az”†Z—Û‡ë)3‘Ù0ñ(U9=µ±¥rv%_§=!°TûH€Áë¡`Ú]ýÅÒ=ª ÛŸNZÖumg)• 7ÕnWÞU~c>…R¡Œá’Á ¡Јê†0_1 Hœ{wþ¶ ižù¸uŸwÛr©#Ê‹κ÷ûª³é ¬:[BÇ3XL®–mãj‡Ùh˜@o¼àïRƒEes™ÇÃå×w—‹ùåâCr*ÀùâÈHî¥eJÝpKü1¥!|°þ)Ä (`ýƒTˆHèFCÞ×Ñ¡@Å÷ lÒó}Â7ªÐ©mìˆYX4‹R:õAP1‚B¬‰ /Û®rß pxS=àrÄéH”u㊜ÇÑWݺ³µtÊŒ°]ÁB°Sv ã­&UAÇQä÷xNÂÞÕ¬l™ ouß4 µ €cg¯gáX¼µÉ‹ÆSµ´Ÿ à0Ÿ3ªõ£Öà72SF|oá¾›èPlœ~y ¦jû4æ¥aç/×ëPË.©çv¸`Ò¤øË€¿­,?çÑW¯¾Ú¸¡!‚s~hTá4ŠO0À•&µöhÄiƒÙ_ã´¯?^ŸÏß|è 3¤åߌ šç“Ãtñ¾Ã 8,w.Ÿ0^Â"åŽro'Ž÷Ÿ»á—;.l,â‰QÖH*móÅôýDýý.c©2endstream endobj 251 0 obj 1789 endobj 254 0 obj <> stream xœÝXËnÜ6Ýú³L€ #¾©îÒÔ@ 4©ëLÛ7òX¶•ÎË’&ÿ¾—ojDÏØ®“…8yyÎ=ç^ònZ <-ôŸû¿XMî&wSlÆü¿ÅjúÓ|òöSAeQâéüzb?ÀÓ²˜JJQI¦óÕäÕûÛjÛ×íëùç #ˆTÀ¤ùÕä•üQaŠH©ˆûË ÁÞªÄnhÓþÝm«Em`HH"Ý/ªuuS¯êµþ‰ $Vî§^Ng¥â\½=—x {´ŽyÆH¤dÓ+‘²ß¶°Û•L$ ¦Ìˆ@ÄΜŸ¿{ò³9„b[ÀT,‘`ö»~»ë;=—ÂF* Pé¡aȿؘaJêOd‰’É YDi€pÙtæôX!\ ?³Y/–»«f}c`”pÀªZ.Ýv…Š+¨&ˆq7¾®Vn˜CÌœùåûzeb!å`xíâ¥ò|ö·µ Oa»¯zHj¶öiGYÖ(a¨ÀÈÐ`šº¾ÞnMd † Ÿ$y&g[hÚ#›Ÿæ'ggÿS:8„#%?‚E~^’a¡$3LG1ü…aX 3ÛnL)ò²t×Ö]ŽdJY€ iŽ-mgç¿`ÿ8?ùt˜eNöYf:˜!Ëðe!B'€‡ž6×ÎãÁ£ÏàѨw.{I$(÷½'X ¿ßYRçr×6ŽJH34¼ëêvvUÿ°¶? Œ¸?˜ƒx¸v1ÕAù‰¸iötÇÈŸQ%A†tª)°ØÜôf!àNâ€g[Yk‡ò“Ѧs™!dÔHç ¡2bgåÉD "GÂeto ©Ä7ýøÈ™ža°{jÈ«!¯~±”IDÅ?­¿øÒ*Ã’uûƱÍIü)|ȃ„´õÝ®i ̉ …5—#©…ØþYuQ;$d,ÚÄ«PAüÚXMA/À“‹zÛ»˜ð¤[²áçâuÖ˰,u•xY³júÆÂ1ŒzûÎ[ÙŒð5°²Ó§óÓ?ŸneG VΠ6û –G+£ˆûV6ø>[«Rh¨BEløÌf Ó$Ö£ÙªCÛ7¬'U«œ_1X56›‰UQž³ª$§|î̘¶M°†¨àW8f¶c‡²¬_1:f‡Ë¼_AMûU"ûÌNÏe²{êWIÃð2~EÔãý ” (a%)+©_‰Œ:ž† 9‚ʘ½Êå8 8͉ÿȯ }Ñ¢©aU?x)²¾ôñ݇guWûEâ¥Sq :¬ÙÁ®‰æ%-Êrª|Iå©W[ŸN4žž{{h> q0„ øªYT!ŽBC¸q»%vy Õ]—'0ó;Â,¿Pƒ“öïz³œ9 ‚2 Ã1Ý–ë°4=ŠŒ4ý­AF .Mø°\˜uYäCbŸPkêý¶wP+Ž´½ØZ‹p ±j›êri±ã`ÿt€Ý¸„}³ë,á%œ*½Ín50‡õæ®­g¿ž~šQÜøÖ Šc#›ã*&ì3Wf;²¤#)N•cÅ•‘rëeém/lÔZh¡åøÎf‘¤îšQe¸ Y&)ðˆŽ™D¬7­kKe,l15ƒãAnz•Úʪ´°”ë¤õÒ†ŠQ¦Ò¶ÖwÆùƒ¨}G k÷ž"áõfíÉepp®!™H•­ã–ĬÛÞçYÌàÌ×ijPõxxþs`»,õíBÜc. Ë®6Ã!\èqhš¿T­^È`iËB"^À!/Ûª½ØÙüµI6ÃÐð Q¦×ócûÅÀ÷LI@Õ³|M#{¾¤€€áK8Íñ«2mœ†¾ÄÀå¾/ Ò³ò»%/ LG_2ý»D,æåÓ•‹*Wé‘¡r‡XæÑ'–4“ã‰r}ZA.Òäóv,‘POg¬Ý*™ºÙ½êiGŒ‚@h/ïUæUÄ4ÈÈ9Eï8sßó²Á³i犉±íºúzg|‰é-)H½ˆs!Q>ïÖ‹¾±IÈáàAðM;ÞðáFÀdš~4!‡{Üvã;}ŒCZ­8R¿VŽÞhÀôÊÜgFK ¶d‰¾¿Ó;vx£I‰”žÌ§¿Oôß?B6X×endstream endobj 255 0 obj 1587 endobj 258 0 obj <> stream xœ­ZKoÛH¾ó#tL«‡ýâcn™Yc¬g-ƒÍh‰¶8‘D‡¤&“¿ÕìꮢH)Þñ"Íf³ž_}U­/‹DÈEâþáßõþêËÕ—…ÖŸõ~ñóêêÇRÊ(’B.VWþ¹(’E¦µ(Ôbµ¿zeÓ׫߯´LE^äð|µ¹zõó͇¿ßÜÞü枤V$™ÊðÉíݯwÃ~+ ›j\µÂºÅ?dr!µHà‹îƒK#3øL¶XšBäÃΧݮîz¿Y¤S9lYªT(¿óýííÛ+·Ó$"‘Æâ·žv‡r_M×?½ÚÕ÷mÙ~s¬VF¡ŸÚf]mŽmõéµ{¸”µ€ÿõŒ‘Ècƒ.­¹Û¼ëùƒšcÿtì;<)S:Å“J·VPE¬¼nnQZg£`ʾò‹^¦Åá@Vf¹Äµ ”ÌE!£'àÌÔ‡G4ƒÔà ÿ¬y˜ž2¡Xaå«[ÉÀ>q¥^»¤q©Ú? o*xU§W¿áF™\Êw*e÷f·óÇ"3ÖžývµAY’ù~P Þ+’ìü—Éà‹"ÑÑb³VÙV¸ÑªLáb;Up›v)£¤Û;„T’ÇýƒêZ‰ÂDÕë?ðƒY®Iˆ28=±y¡>@t‰áP·ãtµ­½•°”–~ Ì’Ò Ç®z8î† >³xBí%PB븂é÷ãaÝ×>Pm.Ò»_ë~‹4dŒ™Øi?wOåÚ竲ˆI9ŠþðžmÙT"4éù;lM…LãVŸÑÞÀ¹Ð”iý¶ì½O$„?BiÞV_Žu;£S‘šÓì”É ²sd:–²ˆŠD—9ãÒ¥L¬‘MÞ5}õúJæ1„Þì#¸J2ÝwPœF…¿n›ÎÛA M' È…Ji9’*bxÖ‡M½.{Ÿ &t©y ð` ”^ó‚1ûî¶fO R*CîedÎõºò8¤]úÆX¼é(’ Aˆ¸ éki+‹XCvƒáciXø|zÕ—ŸQ icÔW!P ¥zÚ@1¡µi ¸à4¬²Ieu€òéõ5:SÙ±¾ãƒç«CÄ:)s9» `Ârû¯(/)! Á&Tæ$ºɨ?Ä[Añæ1øœ±/L/à·&K9~÷Û¶ò™“D‰©¢)ž9s©½©ºu[ßc€f”}XÕFp"?3š¡ê~_|N#þ1ˆˆ˜“¡_H²Ñ~EçEd •Ç&•c,<8iŸ«P%Uýôï ÛGeFÄPy*½=ᄉ֠-L³lR0‚ÚÚ*µuŽH͘ œb„’-”åüò͇·«ß0 ÔE®Êý„ô‰ÛÏ,ÁXŸ.&u¤N‰ªÄ0Ì8ÉL%”d,„Ð8DúCg&d¾Ü þ\µÝOX\w§3&zq_ê=¢eAü츜ê¸eæ¦z(»þµ×Tâ1Ý÷hû¾üÓ •§ üArNô˜¦êyªFTj§%9š8áE,ømi×HŽ,ÐåÙ©½€Dšç_ ±”š ª½ ó+ñKE°‹¥Wr,aD sªoûµg-3“UmëM RNaë‡)™¼®À¾Ï}éÐLKFw\Çšhê-Õ5;gh=2´À4IL¿7ˆíÚe,+äß‹Áœ’0F v)q-%ÈÚWå¡Cëkßeh”l1“s Ô_×(K(6xsìÚ•)¢þÝå«F»z_»›‡be &f&Bqti®uP}S£Eš¦ŠßÝýíæã,ÖÂ7ó3@k¤PÉh§­'¦‰¡@Vÿ¥&ØÐ¦—±@‚•QP¬|P@¤¤IÌêÚ.ÄOFJ´Õp!O½´£crã¤`œšÃÉÿ/Ú@žìZµk4£uš)áÀp,ž™²ißøIÎê xÆr\^Û•OxÜï¾!8$"±±U’7Á™k'‚$ïH» :•ÍÄ»mD1úÖ×nŠ¡”늬ÿ=bï¿ð£­GN¹ä¨AhÒ$b™¤XÜ–S„')ã Ç3¡„a9“9’Ml'`T§dŠ»`UM¾ }?›Å(^ÛF2~›R³¾Æ lxÓ­£Ÿ_`É9bÎüº+#æt‚W @N>1Í碧£DÐ`ãðE»ŽÑ7çÇE‡°6@¦-Œ¾™ÖÛy§c"æ¦ð¶I­eÃ’n_ú}Ü+ÝãoTÕ‡Bo8~&W˜ BoàïÃêOFDó.Æ}\ìÌØ€Âg3E`,J$ÀÇXÔÞ6@ìaªÞ”žÀ@c>!0X*ª—§³ óB+Êp¬9zÈPvÞáC8¥—±9S¤9,Ä ©E¨Úz8AÛ3ƒ– ¦Ÿ³øöQ?_#=£‘Œ]£ðšèáÓîˆßmÖ†®ÙGÒJœ{P­A¢Äê &ˆå¥„BÏ(>O ½C&Ì\ïÀæÊÓ|Ø–m¹†@÷<'’Fˆ…£1Ã쩳ööEÏrÓžw·›ÓÄ¿lÛ¿’\œø‡)‘qM_œo‡d5ªÜ5Él˜ž:5ç¥vìT3çÓŒ£øw|j„šcÜW˜ò×>+yÌËÌ-N/ †¹W©¨°Œd!lAGÑqš½Áàc^ϲºl%¡oU»j_ÍœÞ3V V,Æž lò–d1vPüa[/"lSÎÛùðP§dÓ¿§ øÉ’÷TÛx…p`2Ô„î…8Ä%O³ÑüÜ«äiF`FžæàY÷[ŸùãÎmö³JuÂßBƱ^ômhæí 7ó·æˆzez&ÐùL™Vï·1€ë›ƒ´M  ±ËÏ>šøÅ * ‰Ÿ:ÊÛú3‰Bd‘±Ê¹‰[œ0¦Yî›ìïG_ÖuÙ‘±ùù£tiSÆ”ÜXž„#¦DÊ‹´¬ÃüÁL|ADñ8ó¹ó3IfÊç~ý%aÆéŸ‰WsÚ>Ö‡^J-45¬Ü Q 2 ƒX'Là¨2”È_{É3‘ªÑS÷Œ¸Zã†U_kÆi.óK ýã¢pQ5Î1cwô8å*JÇ]ß´8‡i2¹ÄÏæ'5SHdô–]uÜCo2â…aÑP3“ÿU#Žîðv»jMC"HFw§aR5 ot긂Z,Ál>AAEd[icã_ÌÚ&‘ï±[ã4uWŸ¬ÝíÀ½s¥"»ˆWÔ3wÒÅðbi”á £]Útt2ù= ¼3úIʇ·ïVwÿ~'2þ…Éémæ2%€èIAr— ì‚à‡Cí<4b]»ø›l%Ç¿ ¸t)x (#XAè“ìê lëò~v]HéÂú®|µ#£ÜkðÝ!b !QÄš«6¤ûqr,mˆcñËB›ŒFý~¦dùH!:ÒÉðn HtM_ð÷_þ“…3ÓÞÄ:ºi/К³Y„~{N"ݽ¹½ôݽ=ÿ'\7«Å?®Ü¿ÿ‡ä7˜endstream endobj 259 0 obj 2731 endobj 262 0 obj <> stream xœÕXMsâF½Sù:ÚUÑì|ä¶q|HÕ®í`R9,{ Í’€À2vjÿ}z>%°@ÀºâJq€jI3ݯßë7â!ÈdØ~Â÷t9x)ý:Râ]Ö¨`ºª‚+Ô#š ôza»Kª†O‡Å&Oð¹–ØªUU.×îüÉ¡Îb©ß|Ÿ4m J×=ðªÊz4Ø*ªõtDi1ôUQ苘@¯‚c°Ï:Á ­Çµ ò¼3c2É¿ÞwŸ-ùD‚Ðïn$2v€¿AºTƒ‚a’è4ʾ_Áðvcz\ï„Aº±òç¢®Š¥c~ žê9Ͱݫ5’÷oe¹Ø9 ¼–Ù»÷Oƒ³Þ·Î?Ó2vx[—58&NtÚë¡ã‹Çñ¥g,ån†:Ȱ~ÁX±D|9„ìc7º±âíªÏh ™=‡½•)ÚjÒ÷¬{¼¦,aì Mɦx‚'¾<]®IS  ’¦Õ™šÂý{í•ýÅÞüÕ©þ¥àt-ÿk«Oû{^Ï­¢ô¶ûí{sHyÒŠ&͉ <à;s'Ü7q³FwvŽà>7‹ë¶^e\×£ì·ýü ¹Äendstream endobj 263 0 obj 1140 endobj 266 0 obj <> stream xœµXËnÛFÝ ý. špÞÃeâ0]ÔˆYAQ$]Ð6]³•(…”äï{ç=²F‘´ðÂÆpxŸçœ{éÏE‰pQê÷ûn=ù<ù\`sæÝ­‹×ËÉ˦p‚ª²ÂÅòab_ÀEU’RT‘b¹ž<ãêùòï Å©JÁóåýäÙëzñ[}]ÿ¡ŸŽJI¤{r=ûufîsTqAÝ)G\¾\H\`ŠJð¨N–àFSV!ennõ=…8悸—7;û.=–”ˆ(ÆŠ)ð‡¹8Ÿ-õMBRÒ»¾Ûô»¶ß«ntv“žR„¾>Å )æÞY¯›þéû\!BCzó¡ë1)˜;Ýú ãTù¨w­»H˜ ‡Ýneb„û÷W]ß eáxóàÌBáñ÷Ìöͺ½7UˆÇ÷·ÃÆ‹p÷®½ßÖŒ*ÜHØUO$§î|IïÛ_ún×mzc…3„)ôólÌÐmˆ0…ÇäIà1ÿbì"Ì*o¢ºævÂN:âÃÆˆÇ$!ó­K†È€Âv0ÀDcÎ~ÓGâª*EhǸMó‰Dwço Üøz"l—®”!ÝÿÀù ó>G*:wEÄUÚÌÖ€М¯BÏhpïá ç‘—.F„‡÷ÇG‹èHlùWëHBDáâ¦÷÷Ò3ï›Æ(5¼p•”–³]?îÚÆbŠ]8: Di¨lãyÆpðØØ¦MÛ¡s|ª@kB ƒÉ$àù|ázÅc[fsWj}ë@‡ý]„}…¨ª¾™U p'"æ3ƒ«)¦sØDtnZß`¢Bé>úø@AqЛÙüOAÃé¶ù«u§´ŠÒKUЛ*DöÂY&5û8Ÿ9›’gl‚ÿ`SÛDY'%`Þ›RâU:«ðãåã¢L2ÿ»šÁЉcH?ÈÑ*Þ§çYõ¯@©H…Oª?h:¿Lý1ÈàSõׄɩ?m˨?ÌÜ#õǺÈf«•«<&Áì¾wnÞî–U 84PàÜH :àÀÁ.c9›ÙW}$aöT8ôtøgÜ6w­)#S@ìËøêövh¿tͮͶ}J%{2'²“}¾˜]Õo>,ê›\g¹LÇ’e^U4?ϳná´²Œî¼3K ó&š?A=~’&XpNP@g Ô‚ý²˜kIsQúºýîô–ò’>©²!44UùF_YuXQOòݰYei È…Áb®Ü¸jÆ6KJ¥#Œ¬¯njÐö8Ÿ®]Sÿ86µ^8 %¼9¿­Áßô°…|…IÉ_ë$F¿ŽF< ›µïÉ0Œ»S9dgJÎ`_‹ò5ð=Æ$1`}´qzõ±—9Tû~úÝ:YžØ}|?Öõ›£wI‚7³~¸a­g/N‡uº®á8$rƒÎË„ÒËuœˆÛýÎô >/HÌ «kX(Mî´J廵ÃB8©ÎJ˜v$lÝxÁŒ s[U Vo?2eàÖŽÉôž‹‡& ›aÊýqRûš6: &øh‘ü–A\bÛƒ+×wÇÁ2e”?IqQ¿©ßÎólQ\+JäÜ£[T ûòé’*¢8|ö~zUQä– §J\†¨Þ MV|^om VY჋Eˆç•µ*/]@0Õß3,]@ a«Õ…Òv}­+6r— õf—‘ X¸d@Ÿä ôOr€"¾h’[©`¦ñ¥ºI“Œ®$3þ'tE ? ƒ¬@K„X¥Ý=ø^©Vc¿fH²8³fˆy¥3 (ãs»š½[Öï–Ùõ‚éÕ;T×Â+¬ŸŸ‡»7ìV †Îíðìb¸C !‡pßæ·kvæj0Ï&±.In=–Y¬k½=Â:Ì®¨/g°NS²ü˜äPq$¦û¡ÈÁÓ”ÈIšn¢?ªd1úñ­ñApÏÃÊx´˜ÒÿO‹ð<*uŒ*÷e˜þCâÿ^†ëeñ~¢þ Îݳendstream endobj 267 0 obj 1498 endobj 270 0 obj <> stream xœÅXKsÛ6¾ëWè˜ÌDñz“2ãØ®¬¤Ó±{ d&Q«W()™üû.Þ IY¬ÛiFÙˆÝýöûvü:,æã¿ëÁ×Á×!¶kák±^̯§˜Â Ò…ÆÃÙ§{u1””"M†³õàÅ›/åîPÕ/gA¬ 6Í/ä/f SD´"~í7»¶•Æ~i[ÿµß•‹ÊÀDú_Þ—›òsµ®6æ'.XùŸf‰pŠ8Ó~‰k³öz*ñlà´ñyÄH¤dÃÓHÙU½Ù»­´Q°aD"nßdzuëö5aÁñ°ÃF»o±]¯ËͲ^‚G<0©Ë}em\œ2î×ËÕÊâÀS’úÅ£ c¤x„k~¬—Õƒ?ËxÀ7k aQ,ëe9_yc‘„â§z»vh!ÌE°vøbÇ JsßÍ’4˜>NŽ Ž)Ä‹˜‚ñ|^Wß–å¡êDS„éøvbÝbˆÎüòÕøý¤^Hƒ q›5u’“ó¶¬S»UOzÞ\>‡ŸRwñ“!Üæ'G¤èÏO™ø¹«·;‹ &F\ªÚÊ(ñØfI#Êtž^-÷‡½œ‘ ‘e‘Eo"ˆ"Haõ e3OóùæòÝí¬3°&hœØAŸ õÿÚ9ëm<ªþ÷ŒÆâ?}©íYi}ºUª‡ßÊzS®][€Œ‹ØWî óº¬-s8?*õvQ=ëêþ¥ƒŠÁX–ç§LÞu Š C.š§«!*–×Û†¨²ÄgôU²ƒ¾Åyúú&™i¸ó€“ýáþÅÞAµ\à"ôN½“1H>ßå&è•Æ´wÚ[nvÇòu4b>£ªÀcì5òs²[Îú”sã÷¹»·UÃÅö8Æoòv„SfTù‰ÅÄãN–añ_ aÈ€zÜRž”!‹ ÅZjPß­¢ AK8¦ö™*,ÔY['ehÆK³ùDkƒÙ‘v«é.jÝR¡?û«Pã– üó.˜sÄò9È•bh±ær…®ýH®2oɵáX&W–çÔÊudsFµ‚!ç9;­cã]ýÉÜ$’KúSúf"ŒIðúå4óÓ&BŒo  8r®Šþ ” Lb… ëGŸzñaú{[P‹íæPmûçJJ!šn3fØÛÚ¥iÑS DNEÎ}±€,ÅEWö.4¤O_h^±¥Üó²’âÙbdº„¦‘‘8›„ùo ­ÑV:QHB±FÑÔØÔ2Þaó´JUky¨ÖÞ;‘‚[î} J«Èf{ð*`it_n«ãƒ;pgiX‰^¤#:'ê|&§*"±= BÏ ‘ž»|ʔώ9ÿÍõÕlr5»uSˆ%ÝLý¤Hz¹~3yûa:éÚþÑITÃá!²ñôÝÈ/Í<Ÿõ/.ý)@ÿ"®À«Â\˃U7**áù1 1<¦„$<ègùcô1Ò²ý¢‰¾]•¼˜ÿ |Ї<¾­¢|(ï&o‘/Œ,Åuñà —áýr½[-åa¹Ý¸’EV´I XÛÚ’“üðe¹ùìªÉRÖ!ÎìŽÙÉÞ]íqÒæF`ÞÁ™l²´ín®=·¸ŒŽ//}ÑÃaq[û~š%s_ú©ŠìóÅ‹*jïLêirîåÜí¸ÝÃ?Nü­˜ tö<ž†ñ» +?\‚Ã%t‰Øœ˜w6»Ùû¦§€1!Ì;/JËÌðled¥Œ œ°ÆÛмjë÷îæúÊŸ %«H¯Oœ*{žšÝ|GT1Ûkceè?|û³!Ø Ÿk –33Rö.£ÿ”ÐeÈ“D˜™ŽF’8;Í×|™Žãª ý§»)¿M„‰„hÀ:$Å¿1j]ðàO* ʳk†™T‚Ü€›ŠLúß(Út3RúÛ\×½ñÖ«ÿ«žl¨â8Vž ¯.O˜¹VDK~TUpW.ÈÙQµ%[q†-ìD'³á¯óùŶ™:endstream endobj 271 0 obj 1581 endobj 274 0 obj <> stream xœÍYKo7¾ý:&@Åòý@…ÒªEP've¹@àø°–6±Z[rV+ý÷¾¹Òn¤´=>àÉá|ßÌ|¤>0"#lÿÂÿÅãÙ§³O#âÆâ¿ÅãèÕüì»a0‚ 6d4ÿpæ'‘Á#Å2t4<{!ñËùgŒH¤†ïóåÙ‹WÓÙ¯Óóé;ûE „UáËùÅ/Î^ #$ £ ;øÝL‘aÃŽvÃ1' ¶Q£17H;Ë»]ó׺z¬½9ëøG5©DÔÛ¾ºž½{;y3µ¶‚ A’ÏUáIÎdøðþÅÃꮩš¿ç<5›E½Ü5õû—öã˜p¤4£18LOÛïaµm½ãÝÀŽ!FÌZ‰@Ê/¶Ø<>Vë%r‹1¤LZlrw×ÔÏ«ª­·}QÅÓX‡¬ FÉèuñüõÕ|ÐM„më¹ïªâH1MÃçDÜ "óš»ñ«ÚÅ–€BEãpÇyf*yóîö[g @KùðT}¬ƒ)3™%ÆYr$IòÀM–Hhƒã©oâýÊŠX羸®ërÓ=Ù)ÐViÀžd»µ›léLâ‚–¤}Ð ÒÊqÔêúmĈc„ a…ÅfÝÖëv;È „¶æCŒÑŒëµ÷‘Ù ¥ÙÇ•'£Hš´s{¡ã8ãÑlÜ „P&<}6l]9íðȹ€7$ŒTͪº{ˆÆà%±V€Ë‚4NkÆOn”"ªPuã‚a„lˆƒ.ÒP¨Áñ 6jîhR“ŠH5Ëíe(> ‹h½ŠÑ¡F“¾(Ðdø´k=å9¶P¹?¿¯œoT!’™µòjá̸¶¶f¾qdtryÕÖþ$b8 ^=<¸QŒDÞíÎç—G$ÜN±"=šºÝ5k¿çàm‚­Ýä@Ä3?¯êÏ!cH®×!d–8)d?^¼Oßί|FBÅá âº]ø°1¬ç¬dm©ˆ‹…†”GHa~j Û²­)u)|<ƒ!ì*5‡Ê}?«Ç¶õi@²h=>¯'çç.€9§·˜ƒ¤'\ˆ²Òþmb¨ÁèëéO}ž0èdç±%ZÃwz[¿¬GVHÄp ͿƖaÄmZÅvHB”ºeìë ìv}: ÕŽ`fXG˜«¢–œ°ã`_Pr›ÿZI QdOKÇü§ZBCIcú¸˜p…ÖCŽF9¡ÖGä„®]^9¡€R‘”‡r©E§Ë A­›_]W^>¨n!.¹·¯Æñ³e.'ÿp|ò¡ð0HøÅ@›] qØ¡hZl> Ù'TŠÄõ44.œEÜꃳƒ¹ª§ šPÿ¦ñ^A_g¹}A8Șk:Ñ©Aqâm ’,‘xÓ(Iæé×J8Ñi¯W8f²O™è,X’2yûÞ¸j±ÎåAÀ1x¯²K¦1·D«’É3HU(˜Chn‚· ز·¶V{,A$3•êìn[{Ü,ÄZÍ¢‚xÇ¥ ¦¹´}^µ÷n.ÔªLÆÊêb®“€ $]âñ¦YFót¦jøŠ…îˆæoK'Ê`lzŠ4vW<ï~4¿A_å¢s·‹ & ÏWíäLbËpÎWpV»-4;¤…ÌÕ݇&Á"šZ†­Y®–ÛMŽh¦iÕS½Òè(ýÍ.pÆØ ^Á™Eµîí0¸¼¦”ý…!‰S€onnátðÍï“ÙëÉ«óéím_ÛÀE¨Ó«¼:÷¯îæEKÉ›«\éü Yts9»¸tm»ß!Ø.bÑßœV,¢hÎmS-NzxšÏ&?úªÇËšs´·ÂÕ[ó“ÄÛ›ªùÓßßùj˜‹Ìjéën—BÛ“e‹±‡‡„uŽpR^'ΘØäе­Þnƒ4âöZŸÐKù¡3POM¨ÅÆÞ0Ó1B6tjæçûz]?Çk’è«› Åu4d¼)òÁá·ô9áâ%h‘_(2¡Ñá\¤V±"ÝßB[I›.4Ï9)cl6æÎ· Í" òÞWϱ@òRr€!X6®í®zÆEßpÕ× CMÊLìÑ@»ð:Ã(b¹LÇ×Zº¶ƒèâЩ`U¬ˆ2í•q°tÌÎ@ƒë5¥h¹š_\nC(ˆÜN×óËëùÖn6Zí®8¹X2ê>ßg0ATŠðË .4ÙQÖœA¬hëðCËÌì3tzМ:®WÛíêc| ²Ö‡AB2ìÑ~NIVäÔ Ô0¹®ï¶Y¦#bßL~ú’ˆeþþ¿£…Äʈjäë_7Ë÷ít âRÅ"À¥ò+zÒ2¦©¬=n‹Xé–ʯtß2¦|œ a.^JKüEnE——³Løt'¸Ìçê¾€ãOP¶lܦ‡ë̇‚ø»Ã‘‡_aüºöí„yØ:u]›Á[Yj¡çVíÿ•$ö¡›ZaÊ¡õÙß7ر7W–Ý'% Óùè·3û÷7 ²,endstream endobj 275 0 obj 1983 endobj 278 0 obj <> stream xœíYßo7~÷åÐ[[ b–\r¹¼>nâ¸ÏQ®©n¤u¬«µR¤UÜü÷r‡œYíÊr¯-8ò`€âòÇ73ß÷qòq’ 9Éü?ü;_}<û8‘a,þ™¯&ßÍΞ_ËF„ËœœÌnϺäÄe›ç©Éluöå‹»jÓÖÛ¯fÿ>ÓJè,/`Òlqö¥ý»“¹P®T8öc‚½K'qh½ýe·©æuX@‹Â*‹¿|_5Õ‡zU7þ'Sˆ¢%þÔú!era´Ã¡Bú±ç×VN`Ï íÏ<Õ*ÖêÉT;Q†‰û°ž4¸®·Å<¿ÎûwV¢Ô¥LU!T÷ýÛf×ç/.Ây°Eºð|Ý´uÓîî—»¶[«ßÔ8aüô)l^à'«UÕ,D¸a.¬K—Ÿù¡B8€Úo›]¸¶¹,âÉ×ÃÛh“Pö·Y6üy!Ê2ðvâ$KmÓì»psYŠ2³qÙ¦ZÕ‹°€23‡—m½Ú‰Q •RÂÁÝE¨‹Í¬ 6 ˜v3 /¯NC:?OýÖ%ûøÛ?€#À¹o7û6àœ;žÍ³kÄÙØ„óÛ ®  _Þú1çÃ!ÍaE?Ûv§RR8 çf»ÆÉ"EPÜo믇ñüòFHJ’j»¬ÞßãÜ%%†òY¦ÃÂn!<:eÓêm‹S!ãàg?T «]¯q•VXºeކeNƒk*Ú¾‡‹¢¨ÅúT”£ H qJGêÂ$¥°y)Î4Õ¡) O”åÙ§è—J½ˆÐJJžtЖ…ÏïnèüòMx;štßpÈ/Û¬ÛP$*šp}ÝÜ!í^‚¦šLÉ¡„4l*V5”ÔCh9Œ­ÊæØÆ`©wm½øÃè–ÑuWk9 é‹w„}g†3ÈÄ4H!A쯾ŠíN%cùã]ÝÔŸ¢zæ©”;ƒë¹É¦¨TX äAÃÂ5å÷Àj(xæ?Bh»\®‹^-¦àºÁvsMk @ã>Qùă­Á³Z*”=_õt‚ºšãE ²*wøqV$Î\6»v»Ÿ·ËŽy lG*Óİ1™K"UŽé?“úSÀÀÉd ˈ6¬»Ûsz\|zäe42g1ÁS:¯º) 1|=<&Jku”A >›£QG‡åÈvýZÏ÷-FECöQD¡jPsÿ@bâx¹þ.¬ ¾Éi 5®ZvÌˆ6V|LW‹Qq"#JÑÞ"QçÌDJ7b ƒ\”*íýy3´~õPĪÎGål¨©b6å^svªq°ñعáe Ú\Ý µP Ôs<•ÌÒIWõnOÎ0Wq7˜²E™#Ù’²…åô±ŠçõVº†Ízž5¾déõ8·hžÇGŸxCólŠìnG´ßÛý<*Â1–ÙÝU‹õCw¢CA€§™£×í]Q(fàÆ*j^¡YÌ}¤}G§ó%¦÷_uLb‰INa£)ÉÖ·”·ò É‚yMzA E¨7´óm]aÞLÁWù§çø¬m—) m%eO²¨Êõ5ÉùœNÀž&Ôܦ5ƒÅ §vüÝ<ÑÛê}"ÚTèTÁç/#ÏË×/Î/C‘V†?¢?˜ª¬ð^û‡7u,p°3É.…ÅnišŒwP6XÉP/†tÈ(r¦qqÏ$U¨Uî™öÍS]ÓÛ¢oÒ ›$X§{@~ú_Ý#Š]©¡Uÿ“&îòiM"ìÒÝDïW²Ä(ÎS0Q0I:Ô+4ØFB°•=‚ö4þLL‹{úãA¨ ÓõW(TÿïývTß°ÀQI1Öõ“”ßA? òL“ê¤~0R>ì'Y^ìdƒX°~sœ¼ŸÄÎ`çBÚîõVM!„¶‡ ×CŠ÷“„lÐOê­›úIVH:m¯Ÿäìa?)Ä,¼qI9cW \/k/ü¦wïˆõx¬¡ÄœèɆ’Íÿ¢†’Tÿ½†{lü9 ¥œ”7”(OSC‰½SŽ6” i|çV³B?ÒU‚bo$.9ID9ÞÓ9ÙPJÇ:ÖObÆë)›ónÖ BçìŸ×PÊ}8˹׋eûktñòÕ I瑆Ò4þL‘¹x‰IÅž:ƒÏâÏŒ~ [þôU´°“Ùe7C_ e¦”Çí—!´_E¦f±ùCýŒSFÇHˆ1aÕP1ÐÆŒJX‡$¢ OMµø°“¶ÃÙšž¤©YìEý¬YúNOøÀøRO,‰o¤ ¢Caf‹paÏËaÛÂ=Ðû>Œ]³ËàÒzùK1N†U7ˆû߀õ¶ÚFÅt´Ù³îñ×7¼Øré÷}ŠïPˆïSVQ]ÙKï)`˜’Ôq¿‹škyŸòóHŽìcë² oñ²>òö‘üòñE îL–í:¾$ sø’TÞžÊõ®wÒEÍøæeZž=ý¿€¡ËœðAÖ#³ž/òùù:¸ã‹ÙäŸgþßoÛ³”endstream endobj 279 0 obj 2182 endobj 282 0 obj <> stream xœ½YMsÛ8½»ü#T{ÙI•…!‚µ'O¢Ùr­'ÎÚšÝJ%{ %:æD"ŠŠ'ÿ~DÝé™ÙòÁUH4º_¿~Ýü2‹„œEöÿ¯¶'_N¾Ìd¿æÿ­¶³–'ß_K +"r9[Þ¸ä,f©Ö"W³åöä»D½Zþr¢e"²<ƒß—ë“ï~X\ÿcq¹xoIŒˆR•â/—W¿ê÷‘›DãªÆ.Îc™ÂkÓÙ<ÎEÖÿRÖö0ÂèLáî¯UÛÔ[÷K ™‡·wv)‰Ê#oÊW»d„Œs‰+E[·›RôK‘ËðøÅ]˜qžùÝßÜó:/àRsè·‘É`Óº©ÿÚŸ®r!#ãò}o”ÌüñK»” Åì.úë}­£A‡.Þ\,¯®Ý¾a¨âL¨<6Ïùà¬E.|P®«nß_$idü+ºûÞF™‹¢é/]žÖUW5uÿ€Ñpf¸Òa_ÕŸ\P£D¨ ‚*µˆ\Ti\ tšÉô ·ô1’Šßc‰Ä„µªv¯K5l|üuÍg|4Mãåº_‹EBG·±ÁÕH “w!I€‰÷n&L¼»/¶ýªJâá §·5ÃÂÖMy×á r¶6Α aŸòq‹>Nówm³E#L¼‘…sr{‡ìÚòkÕúÅZHJ%}ˆ¾I좯œY-z1"ùÇ‹ËEoÜׄUõ¾k+‹² d']èß÷Ž´q.þœݔ…ÇW”ê'\ä²SÇy”,`©bÁmÚ3¤7­n.›O F2ÖÁŸmY¬÷HJ°0È4ëç½Ãª¶‘×Þa Îe šy»¨û§¸-¯Û6‚Œ’h]–ÎàŽ14sÑóv)†¥i?ïwŪDNf¤Z¬VM»2Ø|C–ˆü»ÅQ†$"8V{$QEÖÖM‡f¥”˜ŸFÄ´±l[8à3`DtåiDÑ9“Wíó£'«zµ9¬Ãb°–´†´í—¡D&äÇ;g”¸ ˆØp6|¸¯V>F{‡º4"瀭§„œŠ ú'²Xÿ +˜²US’õ™‚D &}¤›Ûä‘cc ò«±1Å™#zIYžªz:)˦+baÂù›·W7—ý[H‹pµ÷SåðÙìÁ|ßìK¤jI™°ps(1NŒeÝ…s‘kòÍò½oÈÄŸgø°&Ê'Ögctwãe7ÏÂò4aaU–ƒUË)xnŠ €—¡´)Ã墟ÁhÕl·À ¾¾')ãe4Ť£–ÑËí¯bHñ5mÑ~C¶I=“Õm×âa ­LÈ‘2l )G,ý—©Ø‘2"ç#yâÏ»zýöü§^Ù¤¡¤Û,q||¬¶Å,ì›<ÖÑœÇÜG@¦”Š„¤Úo±Ç!oƒg£ˆs>™$/Ö^N@%cq¸#‰5æAɃà%á‹«r}À[Pu°ì¶¯ÔÀ—äè’`ªH9—~|õ·ž“ h’–w =ÀÆþ#¨À²t>*5šPý£#‚,¡ð_Þ,Ʋ…æÒôP»+žaø$ ^—oP¬ù<’ŽÕÒtɸjeœ(bÊÄ¢õ;í\m[¡²°:=Ð,*`§Cüî}µq‚KE–ôCwàj;ø-OÂ^¬%9ä}žüOÕdH®A…³žêw´‰–p žOÖ£aýY›M 8•½SH‚åâ§wSˆФ¤ª0-k‡¢R…m " H˜;ìQ´Y öb“>R¤dèŠáÖʪÏQ¦õeƒz²®ÚråjÏ 4&£¡)´¾\ë4˜LŠˆð¡­º ýó;ËNO”„°~@Ámk0õ_¨ãÍ)AÝVà7‡xI›`=â]B/~]•;+¯9ý鉶>Q½šžè/Xò±–2¥+![ôÁÕ•1œúLe—šbæ± W·ŒNâ}±ä'y¸NAëò®8lúÝвHÊ®¨ ‰jT2ê{Ø‘s Lb+lŒV#i@ña³ Ì H5E éK˜±­ɧ5ÞÕvx SE‡9hÈÐuÜcÓëä»f³i0b)Yòàý’-U©u¿ÖøÆEQw:‰jÖ ÷‡'¼6¬êñ—–ƒßMéÁ¤èM°v¦œ²Ÿ¨ÿ9ÃíùnW|*Ç0Érä6R9s°3 cdƒø?pÇ%ÆÞä©ÃÜô‹É›Â±n*g¶¦Úª ¬;WŸ8›{¬îõY{:ŽGÃ&»ÕÄza>!…¡’|g+"J«c¦ŸƒýÚneÅÓµ·Ñ?“¢¾éжó°Õ$¦9Qo¨ Ÿ£ò Ä fmªÏ^Ø0Ör‰Ïå°½§\SnÞbÂFÇ,–…ŸI°Ã‚¦d­2$ÊŒ8¢™š£~;ú ~–ºóìiêv9ÊX»q2i«gp,Ù&›‘ýÓ7e—[U§(¡ iŽdpßo ¦ÉG·šýõÙcDk>É ó.‹ÁÍ»Xÿÿ›æ]`N4$c#‡hcsRΔ¬¤y×䀩w=í¥yÐaë‡Ö½lÖ‘á“®ýv¾Zž;äÞ·šdÄ Ç!jl„µÙ7ˆ–lm¹-·¾çOUØvšõN¤¨ò„CÎ’IÅa;ä,8î·±H).pÚ¢×î·ûò˵°Ä„9ù„:#ö é zPxpz B¡‹¥©)/ÿìKÉCµÙ YKÕ–s‹2„XB´1™°lbÎ ?Åo=s QÕÂ…yÆçו›O}fèÊzæ²1%j±ß—”¾‹MW¶uÑU_1䩿!0 ›wwÌ¡¡L6Á¨¥˜ðð ¸ÖÍ9Êl6®û×BàF& Þ;‘*ªc÷ñ¢Sò¸l‹Ê74ŠDçWc­z¹­fâÍij#ç˜F°Dܬý™$Év_nîÎ0|½ad`˜©µ ò|ËøWÍIzlÚ5ñ|758{²+âLrôÅM‰Ø„Û»ÝXÑ•…#è!u=ªÑ)ñ9¤þÜ…%²ÃkÉ *6Ø ã†Ïuœ=Í.†eכ̤7µŠÐ»gMb€E=­ÿ$œ¢ À‘Σò/Fš8¿¼Db‘ü²êÖ«’¡*„VÃÍÆ>¾š†yîÂOT4Ð…ÐøóŸßÞÚrXt®§9¶5þÁ|öÝîõÕÛåâíòfÊ œœNBš„>>žo ü{TOžý‰ÓRÝÄ/•êJT¦Tª8ÆPí&o?êïnÐ !û8R¬®>) ¦äÿŸH½»¾z½xóóõb2VƘí~Ö ¿ÔL‡ÊçÂGÀ‰!±é©ä8PØÀ¥L~ÀY50! 7ð™ &? ƒ§±vñ‘ÎDîS2Ïàú…°xûçÁbª³ûCqaÇÿ“N±0}Áé–£žKß?½©îµ¶:Q‰|&øÇœ°XÎþybÿþ ;žhendstream endobj 283 0 obj 2660 endobj 286 0 obj <> stream xœÅWËnÛFÝ þ¢›:@5á<8ÃÉέµà¤i$´‹¤ J7l(R&iùûÞyr(Ò¶Ú¢)´0û:çž;¼KR„“TÿÜÿî°¸[Ü%جù¿Ý!ùq³xùSXA2•8ÙÜ.ìœÈ4”"I’ÍaqùÓ§âØ«öÅæÏ#ˆ¥”áÍ~q)^é5L‘9qk¿™%ðKì–šösw,vÊ`ˆ "ÜΛ¢.þPUë­Œ#Îqî¶z½D2Š2&ݧzíå{ð™BÐ:æ%#)‚%K&Qnªý±êìY:ÊäpbI8"öàêúÝÍZ¤ ž1çèãeUnÛ¢ýjÂÂ(Ã!âcÛìÔþ¾U_Xã.¥D™Èq²Äu²k‡¢Þ#cŒ"!ƒ±«í¶UeÑ«ÙhyŠ|¥Wׯ7¦ 9Ã}œïn^¯7ë¹8 &YæÎ×K,€ÇLh7ke@Á "<‚´³ß0h¥ˆ°÷°²¨ *9õ¨`cB; $0—9€‘Çóƒ ÖÚͱ<@=o7˦vÑ,Æ(ÇPs"äŽõyø¿5Ž Êsá?m],[3$xÈÿ”T>F‹%N¦LךãYWUÙõ³l¢šDp:‚ì¿cÓÛ«7+Ñ”ô.L×Ï_0$è'¨³D˜Ç­ð-ùæÓ±–<ÎãhÐ3|£DËÛ˜oÇê\Áq•^…€ª@8  }û —>ïëQÆiׇ¿‘~y¾AÞ˜†¼mŒOÑçHÆÑ-#(¥ôÿâ›MÆé´O:§o|à?_ßâ™Õ·œ™ƒ]a.6Ô»y0U\ ‚9£Œ#Ï«(”ê|%H°‰Š‚Øa$Šº‘(ú£`—á•‹"<ɼNuÆ$ÖŸœ¡fjW^X\²Äó˜¹[›ˆù:G¾±$ŸlòÞ†œ:;¥}ˆäid§‰lF¾OCËùSL9°ü±gL®G{ܬUSÌ:>}6ßü|uýô eµI~Yèß_Hendstream endobj 287 0 obj 1227 endobj 290 0 obj <> stream xœÍZ]Û¸}äGxûÒ 0£•DRѧ|¸Û n&Íx±Xlú ØrF][r$9³óï{I^’—#Ž'Y´@‘‡‡"/Ï9÷ÜK^¤I¶HÕ?üs¸ø|ñy‘égö¿Íañr}ñÃûŒÁ“D¦2[¬wæ²…L%c‰ÌëÃÅ÷¾þ÷ËŠ¤’¼_o/¾¹|ÿ÷åjù‹zSˆ$-ó߬®¼ÖãE"EÁð©H„zxÅÓ¦-W\&•~³é‡ºÛ&êµàIÁÜLï›z;ê©ò„‚ãã¶§á´™Ú¾Óo…LJ.3|»úƒzšÃç¥ûütÛ¨‡™LR^æø°«Í—ʸ›ÿÙÞŒ-Ø” +Ô³f ÷4¿7›ÓÔèUp–é–ß;$¸ô*wS¯Í2ò<)xÉfß«üÃMÝé‘i’ûïµÝ• bV%¢ÌWKRŒâþ´5s—Iácuz=w‘d…›fÓlOƒ g,`çø|Û<ëZÖ,©D*ñÝ];Ýêé=Õõõ%î‡LoC•&Ì?„€Œv}©__=ؽ“±õfÓ's4\}Ï…µù¢G²ËÊ‚D¢,+ ‚v§žÉ$ϪÌ}J=ª’¼iùG¢óQEAÍýý½™²Èú,ÎÊDúGÀ‚¿LD%ô¹å‚:*°°Ò…µÞ}=;S(d…\;N£O2ÿâÍ“Š*°– 0âÖbÁV$% ø8¶ŸÌ©ªÔM‹1c•Lí£=¬·ÈýŠ¿˜àdž‡õþd±žyÀL&à9À×Vä#‘醶þhÖ;bÛ¡ŽÄ?¼g)Õ2Æ*´›5¢„èÅ{ýL(˜ØgëŸÞ™ÉBaØóÊ‘óÒ,¯(qlCXZXø§õ„ŒÍ’,8yGB¨vÄs$`Nj™ƒÈ8ß‘Œ ÂC˜àÅÒ~± gk»©P0E*ø #m­Í‘iÐÉ>Ÿ¶AÎVÛfWŸö5á‚ñu<™¢ó öÓL„Ê@ÈÜÎ-™ÊLá Y씤 Å5£5§k'‹ ;øX—^• óR¸ÊBÉ€QÄqú.¸òߺ@.½nۃߙ>"yÄŒäÍô¦F=Ô0¸þ.³FΑ´ ­ _ªºœAùÚNó»kM†Pu ×ç3­šJ ¯+¸¢ç2µ“-XZî+„}Û5óO¹ãŠ–Â2ÿ†ÎEp0{CVÕÚ⮾½3ª+¼~„JþUù]íf´@õ§÷ —LÁ†XlCEkÅXüôn™©SÄ{ĉ ÒI;Í%Ãqª‡ ½sæÅÇQSÍ¡Ýôû¾³Ý²”qêG,“ÂOAMíKÝc¨À>8‘™—ôܾâVòLO%6?×íynþ`gñˆ‰±ô={k¨n½™NÖ ñœ¶ªwý©ÛÎÛ’ßÔÌuür„B"¥T¿4&GU‚c²Íƒàm«¶MTD5Ž'… Ztj§b øÚ ì étêj”DŒH³Ã4•Ð4Û_©F}€«Çt’dî¹› ÿ£„ÚöU‘K¤„ä%ÙÙåÎý,d£úQÚw¦­nu¼Qû_f¥+žÊÄÈ©¥óÿyjZ®ÿ¼Pÿþe­Æuendstream endobj 291 0 obj 2937 endobj 294 0 obj <> stream xœµZßÛ¸~_ܱoI€5O)JjŸÒÍ" ܵY‡¶é×ÖÚjlÉ'ÉI·}‡âZ²³¹Ãa iþ˜ùæ›o†þõ:aü:1øµ¿úõê×k>޹«ýõ_–W?~äFX™”üzùxe¿À¯Ëä:‚•éõrõòv«CÕ½ZþçJ¦L&BÁ¤åúêeþ'3ÆKË"ű_Æ!Ø»(9µÝçþ WÕ¸€d*Osüäƒnô¦ÚWù(SL)^àGƒJ3Á2YâÊÌØs~ {&phsæ…L–çòz!KVŒûjXõ»~׎˦Œ§<Ã5Vv ]{‘ &ÌœEªXj׸¿[ÞÞ¿¿ÿó­ù†JYaö³‹ô°µëÄæ[äp3mÁ3¦ì~í~¯›5OR°2ów_Žë²Rz;U»]?Þ:aY©޾o7ã=Ò‚e\IgžqŒKVæ…ûþ±¯ðë*É?†­”…ìè¥<|»ZÕ?Tk3.$+2é,¶®»j5´ÝÓ辂%©÷Ñc;‚‚LÊËZSŽ+pV ¿øë7ã\fóA“ݘO¢H™- (?®›~¨´=h7õhlÇÃÀ|á×ÂÃÀ ‹$w]Wú¸&ËR¿B|UNá8:Ð\¾LÜÐ/jBÂ_L²×véŒÉ`ŹÃi3T2ž„5²ÒŒ‰ueý•3¡üNU³¶h1å§¶c(üÀKnæxX ¸=ZÏ•ôì­Ý…ƒ÷ýw«Nu³A[…·UÿnØ3ë¤îª(ìï« ×OþEPÀ výæß7xë2ÜúÔ0µ…’|.ÈfyK°BšBPé#†mµ; 1ä,É” Ç3ÄP°Ổ‰á¯wïÿöÛ‰!O§Ì\ËŸÁ €ã|†À1┓Á@öÂðeŸ—ÏhHâíºA”’pœ ¡oˆ` Ï¾Ò 0ÖãqgSY1¦¨P96 ¦zdYÐîg)r«.,¡ÎyÇâÐÀ6øùµBþN(‡¾s  ’@eÁx]¥{4ª‘-A3º5Ÿ4¯`WPj‘i%…4jƒÜ'(gÚŒÕM¢+©}+ ¢›¤<*µ+˜ËP«"C¤ˆKz T¯*ý°wÎÌÙý‘;í÷•†‚|^|fϨ¯€~lí %fê¤/H$ésØ9+gÙ¹Œ°ò쇇áŸ~…rV„ ¶­ÖGk5€ ò>ø«G®RÓ¦a—¡Þ;‚L@‘(Js1‹Xm©"êè¦ÀÕØ7ú)õSûvï„3х拈êz¥ÇÀVœV=ò¶Ça£ r¹ð^z÷8Ž-Kb‹Í{lõŒu“g¼5:¤±¯µ—½¤¹¡]nËÈ¥»ÍÛö€ÙBúÊx°¢ôöÉ®2+M,ÀJÒÁÛp2¤wÇêÓ«t¦4½r§Èœ¢¹s 3Òó­Bž*€nÝ“Že Sk̰†Ë˜…÷Ìjw\£ä‘†BæííòtÞkG$þ¹d7Ù%Tý·vßq•œÒi¤þîVm7áJ³Ï4ÃÖ¥(@ü%4ß¼¶ALáÐî{Û¸ªü¯Ûz…> ªx;e“ãl´º$lNJÃzÀ#«¶»jßâL"ÝæJ[ÇÓÃ]»GP²Ã®îPyÈY{ØÊ—¥äcÊ€m‡atüùKùRCR±ï%fˆŸTT¯clx ‡½Pe²¨ïN‡Z6ƒx\šQ·"¥Eýôt!Þk—½pIhk4yÐLºEXÄ©GwUób@ÅR…w– Œ³•?ØâþÏN£mµvCð é¹àжÂÏ3×Í"žKH¾PÇI–ðXÄ=ØMÕ ÐÔNÕ ã(J_±B!–>å8¼c”‹—’š(\JÓšÇfJß_ÚÆA,Ó•kÉ4ó’ÎÎ=À¡rOu2(“3µtPÁ2˜:TÆPBA1廊¹‰çÖO¾'¤¨^ßéað¿Ìtºi}Ô£§Š’¨Ñ£Þa•5Ý7í«ö5)zTX[Ûç¤D©šö¸Ù2×/9í?K[Ë‘^ ë«¡¯6Vež~JÏ&}ý¿Ê.tÚ„†üiæ‘v»¿[Þß½ýp÷ÓòþÝ?ïÆ£qÊy­Û&M¨#M-z®‰œÄê=vŽõ\]FZ¿£n ¼èïD2y²º ¯¨ 9W7w5ZMììK€‘1Át+x:O…Fr ‰¨ÐÒJä³Û}9­¨l»)Pré™Î6<¥i…F)mcwÑ*øiß?2äœWný“]äAB`®7½Åëa>çf›Ri¹€5•"\6Óƒn{Ö_œ‚ ï$Q†w¹©rªMÕМ–«¡ÍLA¬÷î•„>e8.!g݃ÿaE|6×/Xi¬ƒ… î}°/ˆæ‡.QߪÙ864Z »æ± Í ¶úàk’ ð«™fuý8U[—JÇrÚd‹Ü¬!÷=4pòtª”m¤ÌI«¡•”zµC´YØï5 ÿ’q^Ñböy+î@h¸P„TëŠÓñ A\2l‡'5°ïá8 F~‹PT„ç]2¿n PjÈ¥¢ŽÆŒÌƒÒjʇ¾ãBÜÂÕM’$jòk¡p?Þ ö­}•2`g¹ÌÒ¼¶ù\âÔcB;–s§Ýfá Z˜…cÝ  8òâA£æViø Á½²|Ó{ þÿ ?».¡„‚µHt–Ñá·uýh‰´ó@óï™X˜ÏܾL8`˜Yñ Ú·@Tn·B¦Å™)Õ‚*é 6X¹;šáð¥n’¦}ê&Š;–¿y:#{+¡2eZlQþ‹ô2{•ƒbJ_ÇíIÆÞ¹4f!FÎf}—ž£JfïºFÑË)rEþ©9úMDüœ#À[ñèÝòúïWæïÿBÿ6endstream endobj 295 0 obj 3057 endobj 298 0 obj <> stream xœ5‹± Ã0 Dw}…ÆtQ­ÉÑ0 Z:§t(xðÿ/S—Þ»«ˆ1´ôÞ T¨È'û×^pv¸nBŒÑßð;0ZÀ#Ùˆ^`P½ø"+M6Þ_0Ìy»ç%?›Q¡ÆÔͲÞÖs/d¢±S!i0;> å #—"²endstream endobj 299 0 obj 125 endobj 302 0 obj <> stream xœYKÛF¾ò#„\âV›ý`?œ““L°Œ8«Ñ¬vŒ†òp#‰²Hev.ûÛ·ú]”z<ÚÀÙUõUÕ÷Uõ|™U„Î*û/ü¿Ú^}¹ú2£îYüoµý¸¼zµ žS:[®¯ütfª™âœ6[n¯^ütßìÇöðýòßW‚Qq /-ï®^è×öå„ͳŸú{hH%ÇC¿±OYEj#ãÓ›ñp\ÇC;Øß8«‰¨iøM*ûìÕ‚‰U„ÑZXÿæNPFÎæÂí}Öxeê© \ªìÄ.‰¦B]8äŒ Â…dΜ „†ÌêÑDÊJM ÂCª¹>1xŠñ\P¢…¨gs±0÷î¯ýØ:,á§Ã‡0¯¾ã}ëjRK®ûͦ@(QG ºÝgçXM´J°ßµÃêÐíÇ®ß /íÏ’ 4;ï5ŸV†Àït»ÁGlºa,…© ¡4Ù\5±*¤H^ÿáŒ!MBÒÅ0 SÅ ÿH Cã‡Ñ&T†©“þª±BÁø5˜ˆ >ØGŠÔè¼þpGNœ%ã‹owáA u•!]÷‡mð%³”7x³=²ƒ§”ë¯y8îH(T– uyîçÑ—ìYy*Âe¢›Åí¯î4¨kP[\¿ùùÃûÅÏ¥b…öV6¸ÎLLü& €e”D…`í¼{{³|ÂãÉÎC·‰¬È3æ¥"ø3–'ã6I1¶¾ ¡ T®Â:ŽÒñØaÓ}v3JK¤1nÝ»H–ÎÝÚu{hþØ8›u=Q™¯”ê9îUnQËnŒÁ „d©KnRó=x‡¸hrx:|âêðèÐ*HP –%(‘©É}Ë@€Ìs+ìÚ”[û®Ímåéÿ$m¼/•¿É…ÿßRökKb £OßûDïUêÌûf ™F:ÙíV›ã—(eR¹àhÑ«~»m½þiÌCã¹µÌÔù¼kà¹Îºž0eglœ!sŸ}sðL…Ygΰ º"ž3g sèYhûã›b¿1Ðá˜Òq]¼©s=w»ýq Œ8h›õ#qH¤:]] FF›JžD }¬Ÿ§m¨«*[X.‚µJÞ^¿ X!~ÏFD¥¾F QËýâúsÒoÞÝx+ 0I.!ÉtZO ‰Ï>@t2}ývX\䯻ñ»!«r'‡3k„¢=3Æ]1¬‰»¬S ÉæQ3iƧ3«`º ³Ëqæ1#½õ®ÿÜMCüÜþÈp`ôq!ÔàlLÑ}·Š|Ê“ÿ÷>~ŽFÄý2?Û¿üy z³96cPM8KzPzfßÎTééÆÝqÕ†$:MÝ“¿|}ÑŒ9B$s0ˆÉPˆ(c¬”²â Šh÷S|v{˜»¶ƒ&RåTí,×ë½BB¯°\™YkQÛÓÂÔÕ 0F;w©Ý—b‚¯ Û ¼à0›8 =LsÍî.”«žklç+ÃÓYsˆ¤Ì2{4›‡sIlü‘ÒÇ!sB Ø9 üínèÆÎå_*Rå÷¼þj¡èÌö¦õÏ®9\)"·kNœñžÐM=›C‹1}>»e|vߘÃb'íVW$7&©a€ÓÎx¹3R= á¾ßNC› =Ö* Ú[×I{GŸw»õÕ¨î#úhÌ@D‚ö”;¨’¬LV³óÖ͇ë a“e•¬Åé‡<Ý%Ö?Žðº%`¹Í€të ùT•ín n²;pn²òàÕt(ؼ³#M|µÊ ™©Õáa÷ÞTìåÑ(„ã' j5ÚW€p¿ß´½þhGô0#×U|?ÄY§$ÀºðûË8M‹äû¾ùÜ¡âÙV¹„•ÄhÊï×Aý²×.]ã–<›ñÂÆ[\ßܾs‹K­€â“¾\Ò~`ÚØ/ø‡Ø!¶«B‡°ªÔྴ?ù¤г';éWõœâõU=7ø+TáÛv»•¦3Ë=zýÑHÑ5ŠÏ7’±w64 ß÷½_‡˜ÀÑýÎ×¢žuº¼ÉB”eׇŽ4D†……¡À_†ÀÁÉ3þC a˜ÔD)ÄɵÀC ”G䙪ã1øÆ3Ûvǃ¢À§Y§p}“î xö²xsâãt.\*%~}è P˜»p5$h2*“³K‹¢=i OA\:-ÆSêíЮþêÑNÙµ´Í¢+±ÒuM¹¸ÎÊïçdh¿‰C¼ì›ì]AçýaîåMÙ{SysÞ¨çÆ(SyñwHw¨¯K<3gva×/|›~Õl¯² é·™­æñ<ï7¶AqenLô‘°S_ aÂ~@hL&H?ý¶ï±ß½r]Ø«âÜ8A¾¹²Äð¸USÑ”É×T.§ÃØïƒ…ŠÙɇ“kvzܺ ôœ×˜ÊOˆŸVîÔÄûí>L¦šiŠ2+¥ât"׿]¿Yžûµ;ÆFþ?'3e0HC(€P–®ijޝ4ÐXUñSÑ8»#8™„.¹•F«\ÀÉNäyjí*å‰ ¶> stream xœ¥Y[oÛÊ~÷éÐcØ{¸÷%ú”SÈEРi¥@Ñô–éˆn!©“ýó½ŵ­ƒ"֫ݹ|óÍ7ËÐEeÿ…ÿ7û›ï7ßÔ­Åÿ6ûÅ/뛟W”à ©«š.ÖO7þtQW Í9©Ùb½¿y£ÌÛõ¿n8UÄÔþ¾~¼yóËrõ§å‡åßí_”$•f:üåÃÇ?~tû%©¥âaUi^iº œTp£½ðNP ×èŨ‰q;ûödw2JSuøùæx>¸UØ¥Òêèäî#¬æfqÇaþÌÕò/øøùÏk¿êó˜›Á;ÎÜæãy<ÇÁùP%¸Š×m[»H ‘J³°Ì¥/¶c7vGg1„²tDòƒ‘Š+ýЫbOîTp…:»_ˆtUw8´ýþ8¸3d‡Ð˜£Í¹ï[oDE*)äó×A€–ïÜNMd%ãN0 ™H!?ön 2(M4áÞ€hHj¼úãjù·åêÖÙ$H•c8ŒM?v‡¯ö/w¼„ ¾°)¨|¦žúãÞHÑCI¸•ÕéÖ÷>B•eŒÐárQåµW\“¾ úºoÎ5J¨Naí†pd•ÞlÆî×pØ·¶·a«æiëvƤý×{?+¦+ˆœkˆ¢7á©TÌI5¼wNAáÑ|ûø4_ëÃØŸ7É»ÎìàÌ´ò)óåò%œ£ùõçQ»£†BŠòöåm¹bç5DÃ- uµß7‡G(ɉ®•`’ ÉTÉâßõÞEðCÒ„¼îIqˆÔ&ºm|²k"ªTŠÅc]ö%8™`ÖìÎm¸¨®ÓEëU¤öyy62Ù­¯i&ÀÍôóSÕŸCØIó΢•C»9m3š1mÝwQå¶øÒú QJWP!(²¼¾>²àó<²*/^Ù{¿Ï([8~é݇O>´gt÷+¡Ù×Çc(`“i°e+LHãØÎEPÜ&¿ÄYeŸ¾z¶€Ði•’ã"»dWW¹=u½K!ð5¨¦ ÎÞY U“SxŸOMÜxò™Š'ìºoÁ[ŽŒò¹v¬2að÷÷Ë]ð¸Î½/$vÒ:ÛaÓw`@,qsû¬Cdúà¹X ¾ÕîŽ!èÌ?ˆç ji4…öýÐÉß@Ù‘¹jšmTImßûæîrDW.ƒµ-Y*gPå,Ý*µ}\ŠåS FŽ‚GUným—õ¡¿‹\´e*‰EŸãú OÉÅB£=¶Xˆ'#,¸±X ý‘¢þŽ˜úŸOÍØ=t»Î å®ýOpX°´ô| :@刵M¿ë‚Ë]¸€›\ãm?@ñýTa¤’Jn8~=Þ†Hjs‘`°Lç­ÒF-aë>¬ YêvÎ8iåô…RÐ3…ó·‚^Ž*³;¾ÔMôÑBý¢jÈöÔÍ硊`9´Ãm`xž#÷pŽ÷RVàÛºb”ÇoÄ ¯âò1F‰#Qê<ó0ñ¸×Ú`›Î¹y=˜…)æîWÚçÓ¶æÎ€6“+¯ý÷©o‡!šB@'8ùœAÀaZ^ãIKD@yÛ7»Hº™Ö¢Ž3Q‡ùò¦#-¹ N‰Üf‹G—Nðpð9"jø~,„Z1Yþ?ôÍ&B-çñ[¡‚ÆáËÛhUÅf¡vâ‡_–XÎQçû¶=¢¹^¶‡ ã§ú“¹Pº1÷ý°K ïê }ÄCe‘¹7)RU…*PYÏ5!ã0ŠŠJ,ß–8¡?„*°´”q¶45_!‚á1(Eqä3½Ÿ„XË\‰A9L& ¨Cߺ!09«ÍCA§ô}eŽD áEÅ2Ö’D@¿nN~Þ…±Í»Muhg1%ÃLÍÐ-§Þ÷pè"ùÄMûxNàU¹·! FR\ ÉO²"v“1rëiàæy¯F4WÀÒez§YôœH8pÂÕ:g+^KŠz·< ŒÝ¾kÖ"¾h>›f' ß'Ô¸¶³Wè¼Ço¹k&„D=§ñ<ðsë¹É)¾õ ©QJlÃ]NgÄ ž½Ëó2¯`Žªøt^nwCëw¿63[æp…\AÙå·”ëç\¦žs½—S®2–L±Ú c® y…É3=] lO¥ÚoÆ `$-/çä‰<ÎDÏŠ0¬KÓ0Õlš^­æsò䨦9N„¾rNÖ ßr½‹é„”Gf‹6æÍÊ5½,#?Ò‚|C>‘ª.MÌì—óoНÑWÆw:éü_ñ}qZ–øn`ާe`­K.ðÔÅ´ŸY}1ÈúAD@)‰ZòäV4 =û¨úž[®}OˆSŸš^äÛÂû™ª‰Ê±Þ$• ý'Õt!R¶Y%ïÓØž6gzUÈ”´qÛŒ!»2ÛŽâay¬šÆcúžã‘!¤L®¢R–¹RŸ“±Šô‰Z=¯—ŸÜ[¬‚ÑXñTäD›]»é™—?Ch‘Ví¾ÝØ % "kÅ!d?¬û0ÁEHy¡ÇŽéãǶÛÌÕ×6м ©}è yå<ÄÑ^åËKFzÔ¤œžô­ ú÷b++ £Oáç%}âhÆ.¬öJ,Z…˜6Éá]8Mm•ý¤Ž½O€™ ÂãEæSÇSá÷!eè%ú] ΗªP›ƒÃŽøãÂz %¿ý©Ý^,Ó§™™=‚PR!/¨~ÿ€å5UúJäGGªqpÇcpX–&j$`¯ÒÓIÂ4úÌæ¦![b9eiÃÊn˜¯b:­.ym“ž¿ÍlŽ=PÝ)êÔ\eDZ =ÄóïÛFدó“yý§æêyý>ÒµøÃR¡þ–ëÅ_oì¿ÿ¼> stream xœ­ZMsÛ8½{÷G¨ö²“* C?ö–õzjR5[Î:JÍ!™#Ó±v$Q!©dòï·ñÙ ’å©­œ‚I°Ñýúõ놿,2Æ™þç~®wW_®¾,¸Yó?Ö»Å?WW?Þs+¬Îj¾X=^Ùø¢Î¥¬Î«ÝÕ7OÍalûW«ÿ^ÉœÉLðÐêáê‡êz –×UîÖnº½Y¬Y&KáǾÛêÕÎmëÑË Q³Æñð €È/Í®u(<øãÐwæÑ‚î¹nøæÐ’‰28©ë1¥8X”¡éÃñàö$¨o{÷)Ȥ¼ȳŸ2YæEÍø„€þ]Ûº#çx’:$¿]›”‡ŒËCʚϭû„ÀL.*—‰€Ù¬+ùN“é@è¬ãÚ ™Z,!µÌAÆîÊtHž ‚pV®îÞ&Ó6¯Îä°R!‡o÷ƒK,BBÈ ß÷ûÍþ³ OÍÊ"¿{t`+xß¡d5Æ÷¹ »`f8€qV©à¾oO›µ±–3‰¹õdQ\°½I›¤Zx¹9æ&µM?0ç!<Î6¬V%’È0ÿT߃ï[C!R0‰œ9v6ÝáŠ$ÝÑåU¾¸vf(@šÑþ1zv'f$òñŒ» €ºk|jì–‚•-Ëðjká³£Op…BšÖésp1•˜ò66ùÅG$4ôÐÍiËtìö}7:K%2rw] „zmxËß%h‚Íœ[8qèöØž Érm“'üØsr÷~õö½©3ÌÃY¿êY¨ºub­eH$Z]ü sMÿ×Ïi>ÊŸ‘ŽL±˜Ó‘”):ÅŒŽr–Ïé¨bêr:’p¾)ÐʰëÙü¢4ÐQñ:"Ð]ùü,YV¾ †‚ýâoé”XÒpT—ýµJ8è°4(“@˵üÏ¡TR]…sZv'×"!*HðŸ#FR†Cà„¸Œ…<¸“L™ý`ºJÎ/þ«ÛÿÝé$²à1"×&¢.Q§Ð]Ç¡}0­‰Ô‚/Ø„°•VXTƒ‚–o·¾<’dfÈzͼ »<7ŠIåPZBž:zЬP`$Kà‹šÔ15EÀŸ E"²è1Å#Áâ…@ETª‡iŽŽ²ÚΖÿ\Û7º I³»¹ì¦Y»rz®×Np–E­(~§yû\rÊù7¯W7?;çI<6Ÿ½¬xYÓXÂÿµ¢œ¼A( TÊAÉ+‘ôGžðhí²ž7ãó¦SQ’ZÀ½1B¨½´«PÂÜ™ª98Ñ–Ë`µmSáȼ$%%™î‚æ¢Æ¾ÇVfËñ¦q¯(¿y¼vÇ ºÈjkUt#Ø;Óú4†Öú4Ò´k‘aæ3%˜Ž’×Iš°ßêç{DdÙ;›L¤üêl®°/žvÖЉÈ8MâpÿÑ®£ÓËÀéîo›ñÉ!”´•ç1záÔ" ýrl¶NÅhJ*¸;'ù¼ÖD›üµ|¤£ÙŸh‡aT>BníÎßî‡Í¸1UEQÜ!aHp…¶„FxáÚö»Í¾qaT%HÒÀ­›Ý®}ØÀï¶ßý/ývÌ3,êM‚5Ç'û] §£ mV%¨È©tɵ, çºyíS Ûqǃ:±äD©Î…ª˜Ò@Ôç6^`´Nk$°R%$ôëj’zìülq®†”“½+Œ4¢¤½”Q‡qi.3'JIvº&+¡ðHãòoZ ºöÂéUjeßD]$z¦¹4ëz+¦ÀzCÚ…¼I²zbðá©Å,ÎÚþçÞNÚä#c²Û{Nâsí0OÚÛÀ@](r?.!tö=¸;(Á¶ïm .!Â[Êgk ]F”R(tѸA³•G<ÖPÐe~FÕÖ &JU5!+€1@¬,(Œ“Ý@ºêJ¬ON¡›qÎ\n’ž°ýK»öƒjþ =e†¹ö’ê8Í(;dŠü·Tæ(·ò<<|¡G j_´vx-Êd[œÑñÇ&Œv ¢\Àd,[=š¢vu׃‰‚ƤF8Q;S˜i™¯Z%+Q¦»"-¢,ëÛö«‹Q…ú»Ý2/D°}Àäž+%ÖÙ‰O~ĉiRpòSa“â/= ¥àbêܺL:WUÓúµëæøùÉ›bdôµ•ÔÑ×Û¡»ž?Šy RIw˜ur6I2åùùK6WÑIM T‡š4ùZ¢¾ö›æÓÖ©,j•ÆE&ôÎQnV'*W†u>x¤ÚØîó²Þõ`Ž•9Ð_x1xL ´I¥ÃÁMÆÀH.ƒjüè땤ó"pPïÇt€'šë¤”DãEiÀhš¸‚óCß1õi®•wxìE>å4k+ÇÁ *R/ӂʃ¸Î\\©‚Ì&³§szŒ‰”»ÆæwtúLxÑËéY%|M†G)u q&³În¾Q%.èšÊФjoQf}ØåÑÝTÇLò û‹È¬T«€À‰¸ÄÑ¿mÞAäˆÐÍ­fZèûa³n¶6]t‹ÏâÕ%óGÝ`,-Mw?/®.*È¡–©ÌsLêñðè¤$“PâjÎãÝJz}Ezäy³Füá1´”fYIÓÿÃ[[gô庯§¯ñ[¾5{ÿîö7öñ•Ù%7}ä¤/B½)4D¼çîîíÝh|GŸ¾-3‡rr7jߨ/þbd&U*ÄÈ}IѾ4ý¥ª¾ìK—;ëÚ†ÈÃËybÂg§YtÄ7>¹kkXQß’ZØXÔ%ð4½ûý6™ð-ý*ÒÆG|%¾JÍ4ßBf> Ô~å§oŸa¯{þíÚ?-ä°·8ÕþŽžžg;Ÿ“¡ˆžYVÓÅ—Ïú({†µ=æ½øpßÊÉE„á ‘¡®ý¬Ècçte¥H+çÃb­ ½1~‚•×TaCX˜Û€LAÃíYEm bb3.DÂUr.áÔ¼¹z¨“óNñÒNøÎ*! UL«7~ Chõ…“JžÕaÇíê ZY ­¹º€ƒwZºñ âö~•SgA?`Ù#§óh 8åðu×÷íppx¦"úu×9ôï‰ÎC0»¨µ‰`Ž­M™lmÀdlm\NÐÌ=s )o!¬¢üS-6œYÈzU²‰jŽdC¢JsÆœN´É'xÁž––âáÚy†L4¢—ôŽ-º¥ “ñe®4ónZANf†9H˵Ÿîûèî` ªä’WoçRòvµøÏ•þ÷?÷VÂEendstream endobj 311 0 obj 2823 endobj 314 0 obj <> stream xœ½[msÛ6¾Ï¾þM?µ3C€Hö[’z®žKëÔQ/Óiú‘›=½E¤šúßßâu"d)wñMgâM‹}yöÙÅúã$ÏØ$×ÿ¹ŸóÕÅÇ‹fžùóÕäÅìâÙ-+àIVç5›Ì>\ØؤÎ'eQd5ŸÌVß”ù·³?. ¦²ª®à÷³ÅÅ7/®nÿyõêêWý%³¼ä¥ûÍ«›ܘ÷eVKU¸§2“úá³Û"Úp*rÛ”“©¨³Ê¼9ûáöæ­Y@d\IáøzvóúÕÕ¿®^Ùeb¹e™ó²Í›µ~‰óŒ©’»‡ï¤™Puî%mõ#XE©š¹Gû¾]˜oK8R~ؘ7á eåßÚݪ[7ƒYD²¬Æý›åÒ¼Báþ»ýzÝ­ïô/Ï`må~±ÝÙÕ•vÞ.ö»¶7oÃ1ñífmå+2Q•^¾Îœ·ÊJ¢¯™ÝŸF“*Ë ^ÑcO‡ óz2eE–[Ío8~i¾¨àáhS–Ir vØïÌÆà)e)d¬,ý •uou]g¹ ›í²5òñ*«dX µÚãY^W<œ°v{8ÏÆì(ÁD«íUÇäAê™~TfRë>lŠ<+òàZ(±@ÿÐíÊiOAº#ºÞí·ƒy¹¤Öš©2Áƒ÷ÍnjõÏX¦½[ëŸ[-Ïaç|5J÷î›õf·ŸzpÛV°‰**ãú࿵€ ³BÖµbvýêÕlò3Ä}! nM\Oü+™ÈT5Q ¾Ÿtxq}ñìúÇ (¸½xövÂ.žý ÿyñú%ü¸þ~ò·‹«k³TB Î& q™³C`#ðщ‚ج„Á‘¹5X¶"èn·YN_ž!¯Ô0óEäèåå¹q*%«ÌÂ^—BšRƒâ4Rö‡ÍÃ݇ä/ëî¯Ë¤ÁÀ÷$ÓhyÔ`€& Ààÿ? 6ʸ8Ï`?Ÿ!Ø8m¯ês}óæÒ«îÛ7Ç@f¬•8nAÅ#%³¡ðÔ„Âb ®V€ÞÓ­"H¹òHÔî:ÔurââŒc<µaE ’ÿ–õ8þc3÷­K2%ò‘ûÆ$Wö昑î]n„d\–Œ`s߬ZÍÀƒ<4·oç6óŒxŽýâ–Ê'6W··7·©ê\‚yÕ³šHâc¬¦>Tç> V#²š²p òì]»Þ`I ¸‹¬­³»âø6¤=«rà'ØXt:UÕH@M4ìï®?˜eX–ã2>ÿB8ç!"¬Ýõãï×›ÁåoßÏ›ýݽ3™Àï‡Ëñ÷ÝàQa©h°úvg³½f2X}ð"ÔHp«ôŠØaÕö}sg5Éàd¼Óžàó<:Ó]‚!]y›ò,Ȇ¥ðÚü:I†õ A ð.GÁm¼rnn]Lhž~ê†{÷Tò¬CÈß¾ß7KUE…ÖÃÏ›ÀÒ€šÈ`ùÍŸKŠ ¶O÷í®µÅ ÜRUI‡¡GÎF²ŠD²uå"S¼&F7}ë4"ëÑ)kè°Š·pY¢»±¬2á[€,ÿ­ ®Øóù~·kžªJ‚+DEqàR5ã¸ouh¹â XrÒíÞø0¯©jB¬UȬÀÓ7Ë%ÆñÁ!â—Ç‚ Íj¯84x?â—î¡Bgî›!e x¤P!zWe =€çŒ0#§@G ±@H´IÁŠÃ^ €XÏA… ? Úz¤'âЯÀŠÜW)Rgï`í¦óí–¸$Ožã\ wûTXÏÒ¢&ƒÃAQ7Õ4øÓ&àiÌ¿¶ù·ª²DŽeó×åõ‘¦ã50ˆf¹ôj+êðô“O„•ißaö«µ !\úÜžTQQt D’`Á‘äˆ7ûˆ8ê Õ„yöãå»6 ©ºbÄ“Æ>6sC@.ˆÇu«Î·Ë*ÝÏ í²>C0ñ¯ÿ´ÚïÌ»9e—¯—Å œŸ¦"%KP‰D¾êÐo]Î+П5×¶~~È È-È^>Ÿ½üÁ}~^õïaô^5±6ÐýS<¬«  ÅjŒ¬øB¯¦’.6c$m½åňì8lßìÈü¶‚×´Ówëy(ÜR?¢âˆ][aòEvU’56Öªº+šKŠŸŸ…&B '­n3Iûnžlä•àP¨\ÇÏ æÊ½G½Z⃈PÍrß©häžÚV´ÜŸ3YоùõÍìêÇ”Oë%…P·Zµ‹@¶6•&…>±´OwheDÌpÖÖƒ-ñ·W›;K[ ¨n("ø|EöÀ"ÈF©Pí›mÂIæ’™Æv$‚Ï­iõƺԴ¨aWÁOn œr •N}©ÚŒ°àm³ rBÑÆƒ8”ur`c‰¶¿@ $ÂéJ\fÑ.[¿°×‚¶Æ à ƒÍ `8ÂêA‰[‡ëR’Þ\³{p§¬‘V~µôà^¢F>íºah×NáJW•ß±~U’‹+]h祸úþzfcšë‹ &„$¡ð¦M”¿éo~÷ÀQ±[§î¸®RÌy¡À{Š%›hqµß›PÔ/i:*ŽRêaÐê‹xK鮣9Ä1°×Ú¨Èy, öcÑÔŒ7ï²ëç…Ä>‹¶Ÿïº÷Î!$î¢öBŠaûÇÞ®^XÖêHw'¸Š§ã”{ù4Åk¬­ÏKS™ÅlÚÕ •:J¢2*U.BºmB&ºmQ­rL.;)Ú¡“I2"í‹“Ú² ºðO÷}"yºò$"i'ŠýZ%j3²;„ýà^­Š„Κ¬ ÑJ´7C Ç(<Ö0ó¥uÿl ‰³û”2 Qi,iŽ:ÓÈÖÕJïVèA6û£ŽJߊ‚ÖÊ^NB>·yìt»þ;§r£íüKèŠïX­»Ç7›wm"(çg‰Ÿ/Z·$‰Œ3Xk\˹L|¤CÒ½l¥•ØÃÖ}JÔt}„::G80¼tO éMÞ´ó¨à—?¶&†£×!Q›D̵¿”¡GM(Ó(“v~‘-è¥|è÷°’to»9ƒ?Éý8@?§õr¼ozé± —‰Á„än ,»µUcÔì a*Ï:0 ­—Šú('ï5H5q¢]<¢R7ÌY(€™Ý8‡¼~þË›«s(€»:4JŒèšk þ£ÄØ] ½ƒÙ®ˆ3aXíú±nC,NáÔá´ËÁuXMˆ¦ÑUæÀ‡#ÑôàÎi&Ö]ùzG(Ô°ƒ(mÐÊàû‘J×Eì‘SÇJ!Ú8-´êzI5"dŠBØNyl‘ãÓ5—§+<$vüxÌôK͉El¶ä³¥=¸ÑgM[–¾…·7€,÷ ×èáÔTÉj†€Ñ9™ê{“Ï# ì‘‚\t€Ù翌ùט=‹|ny %–.59#ú|qÔJ<‘¥…ñc­Äˆ¼¼ÚŒ59·õ#Óebx1Ñ+ØuÍû¥³¤V?H²3`ÎŒ;)û$;½Ú§Ù%˜gcåÊ‘ $$í–ZRˆe°òˆ²ƒ.q|ÙŽ¸19¤®ŸgwIyn\k‘ËßäÔÞ8®øIN àϵ…{¯ŠPõÂ"TaÚVþÕ³JàDcéåÍO³ëŸ~1§R€Ièä2™Ôm©)Ó_³jåuáˆÏB×äÖ˜?fœ£îé’b~0YAjZ¨Sž;•p즿œ¥²¤¦èÓí_ÀñÝĤHiòDQ§(L#ˆjÇ0Bá’ ç!Ø0'§Ë¤¢ÒH òЧâ?4²ÑôªV2ЇšEw¨É”éŽÜú“±Ywr7Ü$ ž¥jríHŸ.ÆŒ•ð† UrrFtN†-#·Œ:–Ûä”ö PÖ;K^´f1Qµ$\ÆdšÜµ£š±×°Ü“9/Þo¯m Y1¯ªp@õ»óÊ£··¼yä¶T;ib|òæ°Ž”Ê䯖Hp|·slýÛ:#í§¯$|s„d·ÔÚOã磫„#dh,½ôìš×‰Òž¤á¡sT5Jy)9W†.2sM¦*L³—©Á ’zÈ4{ 5Kð•ûÎ.i!$ÇÖÃxºO§3m3?ž^I»š~5Œ{kýˆ)W\{3õГNÊÚ‚˜)¨X«³Îî\ñØE†?†y÷îôò/u ôÌl¡à_Ø‹‹ã³àSE]×~jÖ‡eH†}t|ÝŽ5hIÎ/0ºÊ4×zx2ƒ Ý;>ÏžoO ûÄÆRé«Î/`/ßd~tê̯^ÃÆ¹ÆknÅ,¨ÇÔª¥Ö÷ˆ )«'5aÍò…Ù…¯›Ÿ§å¥þ£¨§³ÓeV:Ñ?6—ÎXLQD¦sé$M#é|¦¥^ñ%ØÞ2Îv‰ÂÔ²¬‚œn¦ÝOÜfz¾knûÃ\‰»á¶!ñ–#}ÃYÕ®È8}éÿúPÏ»ö¦‹f}~†µ°ë×@$°ÂlŸì‚Nµ–Li‚PZ»Bš’xaý§çÎÆáôÿÔpPZendstream endobj 315 0 obj 3733 endobj 324 0 obj <> stream xœYÛn9}÷ìGyIØ=M²¯Ù‡A2k,dâ¬-c1ˆç¡Ý¢¬ÞHj¥/¾üýÉ"«$µ2AŒÐl’UuêÔ©ò÷Y‰YlþáÏzsöýìûLØ5ÿ£ÞÌ>ÌÏ~½ V¢2.Ål¾¸ƒO>Ï?~¾½¼{ëŸ?›r¿€¥×G^1pDfGÔífSm‘ùð⿘¥,JÀ%.½7KàÕ¢Œ=üno.m“¸ŒYÚ Ë“³žJ#UЙ­[Êru] 3HÔYTVÕ„A÷ôÎàý‡Ê~hŽic3X° yî£säA×cÓ¬"EÐjzÜÍòàâvçYð½\¥ò§Så×rºªÙîÆÁBDÅß™ŠîIÎÄ$“2ÊS²´'£üNßÂîL¢”vV=¾=>FX%Äí8ÀKm¨UiÍB½ìÚ ú›½‚ÎÉŠŸDUI¨²±’E”Šp`ˆUNNݶÎ}àuœìETÄÁ„Ÿ¾MIèÓ…KD¢à&ǘHYÉ_ƒ‰$Édç:kÏ…Œá6ë»@d—ϵÞÀWëõ B.#.?wY”2&Aë€È…Ì'A ¸Ïh‘)-v€Pe(5f‰ˆ3•NŽÌrö„€¦Ìà3ÁÕ§fXµ% øŠŠT38geQJ7-ô²×v·Ê!'Q-B H9‘©?m¸HLª•Šáß ŸáÞ]…ôïTIJÙ¥{_ð")BÖíºi”!ÿ±Y ­¥9# g„ eå°B*WPé%Ëv½n9½äÉû…å_3 Ì BAà÷˜À6 òfÛÛŠŽš¦QˆÙºÙêÈUô\ÌLÎÔÛŠžÀbð(ä[é힆¯P1±{Ú¡"0LaŽº/'vãßœcþf¡Ùh÷ýAm7ŠÆl;UÞÁÅi€ó¿ôºBØÆy8ûÅ“A˱YͤR|ý¬ëÑ»Jn,C…Z¶Ý¤‰¶²Ê¿1H£È²xXõèUà`¶0zǺ$W¬°öŠº³_™Zÿ~Ý·¼‚JCmÔ…‡tFꋎàÒì 3-dýø‹îÌß¡˜B˜^«­£L÷/^UFúè®Gfä…=, (Bèй  ÒÄfqÌ´K·i€ñŒ’Î@M¡@ÿgíºÆËb‘(ÝC…ÉÖð¦f³Ñ‹¦´cä4¤ßMÂØ. ¾aè‡êå?Œ§c¤DV†z>–ä f[¹o[ÊÐÂøXPÁt¾‚ô†waVµ;”™ð§®ýè‹å•&¬„¬œ¾€S1ŸE A4y×½gDàæŒjÂ>i³_®F_ ¡Œ$¤ªŸ\¹NÎHpø4«I€”ÊËji r§i Ò,åéspëÉ å©´,']Z|øór’Ï~Ø«˜âE½Ê3–Æ}Ž˜TŸÚ‡öŸX‰ò8lv Du”92´ɱÔßeínBÞtÕà+YÆ+YÿÒzsÂå928Á¹Üå˦B¶2t–/÷Xö4þB’˜G-§I vîûè÷~¸¼º¹µÉ–'¦]ó„îS%ܯwoú®Ç+©àÒ¸iãšÑãpæÊÖÌt²qr‰m÷­?Ö×ëæºV±æ“O7‘©ä}€¶â+˜RÇýáÆ‰—q™~ÞAwß{AðË“°cX«|Ry¤—RôÉœ" Rû¸$ô/‰á¿qÓ<¬4¬ûÌ ­’’W'Ö°nÉ^F%U¾%pË9Þ—eT’òÀËéÁÊJ²@M·`çž{ÉØ©ëŸVMÌ™,Zá®z=á€)Á§Ñõ€q) éØB:RîŸã>Áß̯¾ø)(‘+D¼¢Î}%Øï³'®žžžlQYu¦’ʲCN}úèâ?5fÍLO@]áô<ÄÀÏ™ÞÀl¹1½ 2ÿØ6F&ö稄W›ÝZ¿›..¦Õ²ô 6Vνf³}l¿i”+1‘Ļ帥~+çó»¯ï,öyø$áWÒzK@½„jÁ¼åòåž•Âý²VívNí—µÃ'°{ðî¶,54Ï©SoC_Øìoo_[‚(ÂwÜr8€:‘WFQÇyU¡÷$ɉW÷Ç}U»‚ ï7Øþ/TOTôŽ{\J)9l Î3ò^¿òÛñçá­‡Šà¤uOm·À$ÕŠ`7䇯e±y³í¾þ)ÕÈØ•—5Ï®,%+Ïvl¦[­¡‡ÚV86¦©ÃBqQïÛ*FÚ×Näd¬õ¸ý|}ysû åcŠy„OôýÇáu
ØeÕH}|‰@4c#’.Uÿâ«u~ÐÕoQèG뀅Œ*‘7ûF‘`aó½ºÅ7ISñFå{ÃÑ©v e2Ô&¨,DÉ"¨_ûyŸË^ç,´Ýˆ~çÆý?¸f­4ò"|ìFç@ä’f€Ý¸Ö}„’LÒ)wo®º4Ú]ƒ.øÏŸvîLåmfM±ùw]ÜÚ'JBGŸjÊ‹}È[Ôzt®ð˜ye^³ 3ë%QÊ$Í^Ź€œ4ãX#{ѧ1÷i?îv0 Éy> stream xœÕZKo#¹¾;ù‚/;ƒHÜæ£_¾ìÎ Î`°‹;Qm`ÚRËV¬‡Ýêóë·HÉj5ek’ÙCàƒ6›]¯¾zP£„ñQ¢ÿðÿl}òxò8âfÍý›­Gï§'?~âVX™”|4]œØø¨LF¹”¬£éúäM.ÞNÿ}"yÆŠ²€çÓùÉ›÷çŸ~9ÿõü_úI–²$9>ùõâÃ…ÙŸ²2Í$®¦,Õ‹•86MTÉ ód¶]¯«ÍœéÇ©dyNÚê5.Xš×¶÷;³XèS..¶YÌX¦üb¥—`[Q&.M´¬T¥;î^ÉY›J\ú€å‰ß…"ê ¶*¤;ðiÙÞéU¡@n¯k{W£ŒiæÅÙUk³*rÆÃÖåæ¡kͲ–4U~y¨y85+rùâ©ÍíÁ3¿uVÏ»¦×äLf^ Ôl¢¸dE"GøŸ8ßXARmm¯ž—Ž,vµõKÉò sÓm6ËÍ­±g"ñŸtº”, ^ìI-zR#ž’R¥ÎåÍvmϘÊ–ï»ÚZ$ä²àN€YÕ.­nsÅý±Û…y_2N _µèdˆùMXb¨Q’Nœ-ZO…µ¥572âÚº®´ñVõÎ<Ìæ5j­¡K¸?¢ÛÕèEpV™/ +ÄÅô½pòo»v·œ×ø€`MГÏÄR©C")^÷–QúÇO9i$ikµL8)áÉQ°¶ºµ;e„ ŠÑ+,§ïLH ÁŠüÇnÛÖsö´mæöŒ>‘MdfÃdñ"Ôhã©'š¿Fì‰xK¿¶Ù¶wàs‚RLIÂÔd$À Á­Mçƒ{p Èév-†¶ oßX€©¬LÜWjûfJÜ€ž",­–mÝT+ËÙ=¶²MÇÑzýxYlW6dt0«Ô…ÆF28F^ßçÄ3>º€.¥âN²uÕÜc÷À¤WobP/‘h:y:Õ†ôºzkžCª"nCuT’Ipâ «Þu+³Y&L”û´ðZLÂÀãFyƒ‘,gYæ 3dŒê6’ÌªÆ –Á ºçÈAeà ‘”"éÙ %Á$é@Ñ"hï9!£çÑį„ôV¿˜–·›­•ö` ÛÐûøáïŸÎ 2o×/Õª³¤˜È|„\†ošª1Ú¤œ¥ÜÐŽ%™«·Ñ¸ç°\Žû^ñbÜüPÜ“bçŸÎ/À­! =ÝÕLê2dåÊåÒ¤ô$_}Ìí0ZR 0wL Ê~ÿë` %U`êµbHfï½²H†­Ë‚Ó*¦þS=s¥ ¡¬„ÎçéÚ&M%-!ªYÛ! ˆùàz‹]N¢±$Z’ )b…n³\?`”æ¡jÚ6­µ± /q{  C…$}>&}ÆL- /øj¹s†‚ªê{€8I™”1¤k c pª7ŸM< :yxΊðëGôˆIb­uE6ÉsèNŒBE²¨)üû7#WR{“ºX‹Ìjp-ustØu7»vÙvš8w–9CYñqHCy„zg!ñ¬ë5‡ÀdQ'FÝ Æ2hŒÏY+¸U8Ï[rXª•ä0o÷‚’ª¯í²@(¡N%é`zÐÉ…üG©éssŒ_O”?ØIBW–)-&F¯^w•rïϨ¯W¤+|Íeyße`è@»»m·š#˜DÈ)‡ê¦>çy2&4¿ÜìÚ¦›i:WæPäDá }îä½";ZÏ»™M'}žÂog´É°ñ)¹4éS‰NkÞnÐX1L;YH;SרZhùÊÉ/°¢É¬©Vê¡ hBú þ/B¥b0„¹(OˆÎsô´(5XïôÂÄZ–ÀAºi ʇ¡@iâ3áGÅ2ïóDÙƒÃ7£ŽúÉU‚€›}¢(µn±â_º%‘¦CŽPeäT‚¨—JxbÃc8âçIXÜ1H ±ÉUp0ØžçN´“·K´<‹‘‡ˆµêdF±GÎhŽ<€sÙHÜý?0ˆ¤£!?K ó’Ü•nóûÉL‘Ðî.–dMp>¤ ¨^Bv½ª¤Yå5;–ÞŽ;,-²Pþù©I’¦&†+¡=¤!Lt V@¢qLU ¦E½æ{Bœ¢(EÇE-â’µ¯öÇ$ó$¶d³Ñ'ö:û~'¸ÝÔ“',• ²û ɽšÁÆÈØR7+$ËÖì–1.È5Å1><Ã0Ûw£*¨¾iÊõ5ιÇ:B¾³ãå£×{º6]á­×mCL>No‘b•lƦM_Û„úÖ¢I’ïŠc=h:! .âFÒãÆÿ…Œ{]Í1>ù¯>öÚtˆ(½5í ä‰7|Ff©ô¶1¡œQò¥3'#w¢çJh&}Sº?æìÏÅþÜ`tT!mÀ†ãPNZ?L6ºŸ›dòLmäí~W“FF½šäm 諪ОÛÚÛYO×þ©~r-KïŠ9D‰ w[Õ¢µ–H)½G«g•H˜y®ïEh%ü¾š¡T(Äî í†.žáàW³ñ7hÉ Hâµ½Jþc!‚N}z"õßò­£×oAsðŒp' ÃyRh“¸I %Ÿc––4¾NTì÷$´æõƒ8 E¼RáÐ:´?´úë=Òû1À}H )ïûßdOwKs|Twˆš¦ïjg1ØábLÐqc·™h¯ôLf4 ÿ4¬¥u\ ñÎgÛì÷[ü/âzXóã=›Þ.#Û管­#-ÆÂ¬Mœªz¨±¶ËÝU¤á§,±Vf<´ŠWªßÛÅvFÛ(5Ü8hSG´F 5%Ȝӫ—ŸÖÕ}ä¶ðt çC“ž~5åJ¿ õÒ)"rÊóÞ)"”ÎÆg^— nÎǧö‘>:Œœ‰ÐéK‰?%g_¯‡ Ç6ž>G6FÄùtôÛ‰þûQÐ!endstream endobj 329 0 obj 2594 endobj 332 0 obj <> stream xœíZMÛȽOò#tËõ²?ØMn‹ÍÆF 62#´D{H”LJžõæÏ§šýQE±%Ž‘ A€`]l‹lVW½z¯ªz¾,2Æ™ýÇÿwµ½úrõeÁ‡µðŸÕvñ§»«n¹„Vf%_Ü}ºr/ðE™-Œ”¬‹»íÕõ/ÕþPwÏîþ~¥S™ÔðÐÝúêºøÑ®qÉDY¿öË®K–)#ýâ¡ÛmìªÈX^ê°úöÐW‡cW÷ö7)r¦rî3Ò®ýpkøöÏÀ@kßRÁ¦Ô‹¥*Y1<øi×¹'åè$¢€ß—B3á{ñæv0@°¢ˆfÁ»«]ŒÓð›ýŽû­iûÁ¼f×nšþ`(9Ëy´þþzÓ|ìªî›ý)çL–ÂøŸöÝnU¯á`÷Ïœmc//…ucaK®™vö­vÛmÕ®Ù°™„3ÆÍîjo¹(Lðòï;g¬“švtË+‹\ùå­]*˜QeðîÑ½Í &²¸çÇÁ Lé2 ߮ݛ‚,Un©WÿÀv£»ò@ÈF„ªi›öóo ¡ˆP:nê?X(XžGÄß_‹ïÇXxúQˆìˆ"nâah3ôøá¡r $)QÍF§œF'»þê¢]‚‡Šp’ͱ:¸ -e©ÏŠ4YAC'ì;£äÌisß*n;4±èÝkïŽ÷:ìüþ`QX[×ÀðÛ¦NgLfh­ûe–Ú‰5Ç!û¸bE^\"”îÆ“œÀ’,ö‡ª;xªP2Â#¥Í1p¤œ@˜³Ò$2€|j›JlʈÍ,;ŦõQ~‘(ü×OÀ9ŠF§a†GÞàžÈ‹M@(èŸå‡ÁœA¨ìäésv;¼0ÆHõ¿;ì‰Þ -éâ¦Ù6.ƒD“ À‘ÖÏ'ÀÑEò;3À)™¡¤¦

>"£ù×ê½?‚Ä„é›ßjæµ-Ç¢âeÐ6ím¥qÔZ*8 ©ýôZé@ nz—–׆¤ð¶é{à»ãPfÈ9HZ„6â‰á}9:±?4Ñ/3Ïcªç.’‚,E9Uè¿pD#I÷žÄ¤Žv×í:€9Ôõѧ±Z”¸ÁãC gwÐ8a¡”GhÖó,c’b ‹iÏ-.2–Z1?wuå[i§¸Ì]ª¬´¢C™ªY7ußûð¡›@çCt Wœ•üœ‘ÿ/i ÏÚûä/°Š©¡ÅùêÑÌUôZ½ùæ“$×ш!—–¼·KE»ìQ !"BkhÖ>Ò ³»(Òt>q¿@ˆì¨pí¤1l2Š’ÂNIkêßÁIýW9i0h Ö —†h¤ï3ËQü‚ÁžË$Ó¸Ö[ÿ² 1šeN¸IÓ¹”‚ë™Â+@ç+·Á‰´ìꢭ{¦dÈ;•ü ¨æshÄTEäiµGÓ¥­½Ï]¬Â8)›$„ᆠt¿è{ó1fÏê®§êBÅ<½Ì>²j×9çzÔ ­ýáDJïðä·i¹—[EKŒä}¨£5L¶;¿FjÃú×ý¦Y9ØØn’ÇÀÿ gMÒyD’í»](I¿6ëÚ ä¤­¼Õ CC÷¬mFâ–]]Òñ`„#9Uµyœ2Båò 8¦!s¸“Š`ÜLºzàdPW}hÍèT´]ň$ü¹õ $MÚ÷ Mrê{A¡FŽ­ÂªJ Æ­ý´zM —|M‘“¤ÿ­îvËC× &(h¿3º¦$E„+g–buÖì3~œÜ€Ë±÷OÎÿß¿ôãØsp_ÔÉ"†0óKy—ø‡é›Œ1gÇÉŠ¡ußý3æý“#Ó¾±]ÎcÓ»ª=·MTì!“­N°%?,§c@Ý'™S‘iÂx‚;϶œ“OWT뵯¤ ‚çõ%%ÎdËCè´û‡á¸†2o¸(Š3Síô·gäž°ëåbT'•k‡àø2æ%E$EWŽ]Ûû<Ö“ñɈ`ΜɪÓ»£å° (³¡e©,ZJ`ìr¨>c·÷Ó4Eü-ÜIz5>IÈ1Äô]3]||ðü¦q¸ñ~ß5íÁ—†€ø±^r¨íl\;ˆà›ÅÝ««kPÅg¸º¶ÿòÀ¢fþÿÝ3?ÁÿL.ìì‡zàmÔ“HßûÛiÍòîõ‡_ú:ÝWŸk_CæÔÆ«¼Â@ú˜œÜ‚rk[ f/ËôðàzǺ¹»Ð?¿aûËËWÏpªÇéKOÊîŸ@Pºêi‡"h¼IØþ•+ÑBxfO^‰j(^Pºnë=º?2°ÿU6Áäü0²÷Xêt²4q¡°×Ùè÷ô@¥ £6_Ài Íε92H=‰,±afÄ:Ícè:DFŽ!–ËÌÓ3c¯N€¶UÓ—…ÝÝzªÌñáwÏY¨²1BÏ¿¢ô‰i ¤M…S6wí=íØ‡ÃL£õ/Õ¤˜>uÚøãOˆzQÒFŽzGr÷}¥£É@j˜äKÇQ¥£]LKG«©útd–€½ÁÞé4ù'xv|¬¿ôW¤!;?…6tb›¢1±2n»¾öEˆJ¶ª„aL*£ÐU.U6´3£ªsæÎ¬ ²»r NÏj¤ OÍÚ_¸ä¦áçWoŸŸÓ €E¡¨VÌ …ž‹"aÛ_tàe ˜•S‘ ò3+S«ÿ‹ÄB$<ÒçU¢„â<©œ&Á%•ô‚hN% ¶ä#ªÄh U˜ ¤P%4½CèÃ¥¤šüùÌD%JZô>!ìK©rKxôò¯òŸ#MÔ7;…CæÖÔ\"¦ÝržUéß‹ ˜Ð?³ bB¨› óOÀž Œ'ˆ†Éž$äo–¾S4H«\$E#/¢‘ºDT8I‹†"!þŸ– h/VìU^‰ÿM’F€˜J‰“žãÝë»—¯þ‹=Çó»Å_¯ì?ÿÔ×Fendstream endobj 333 0 obj 2749 endobj 336 0 obj <> stream xœíZ[oÛÈ~7öGûÒ°&œ‡“<í¶j¬‘´^oÂÎcѱ ITDÉNþ}ÏpngÈÑÅúP ÈC€93çò}ç|‡þ:)æŸûÿ~uñõâë„ökþ¿ûÕä×›‹7הà х¦“›‡ ûèb¢8'šMnV¯”x}óï NKRé ~¿™_¼úuvýÛìjö/óK)I¡˜r¿\}üÛÇþyI´,¹[•DšÅ©(l«&S¡IÕÿrß®VõzNú8)yØéºÙ˜Eª «”ߨ©wÍ|ùÝü ()*^úžÌš&šWÔß²^îáñ®¸ L„‡wY|sÍû#…PÌ=´Xw»íþ~·h×ËE·³/¤ÓŒ(Œ¬û“ÀO¥¬ü&ËvýŬ²»#÷¤»Sz‡ÃVÍsL¹. +À¿”ƒsì¾ͷͶ馒3B)¢x¸Æ¶YÕ`¹ó/ƒÏþj–$©JxÏ-ýrõû¬°.…[žõ—¦ŒH¶E¡à%Qå0´"² fÿ´µþgÐèµÅz³·Ë>Î<|Ù/KÂâr×öûrBUEÇÝÎÏ{¥ q_t6·„ˆÞ÷ÌýÜßAšœ±·~,˜ö·ún³A³a»ïcÅLÚÆWwÎ$œ`Mí|%‰Áúv}ߨФˆN¹9˜ø*zßgÌÁ„aD”áö+óHg‡•½½PÒÏ=ÀÍ‹…xÞ KõÚ9LD ãe|8J…)áù±íú­¸¹W0õÉú™Â½PZŒqÂcZ=?6kGNp?€Y à øqÈÃ"d²MðФwÅ͵³Aᙣ5”˜íÖEÎ÷ÏÜ›kE'ãæ7|j²¢‚äcÆë6 Þ—ZRoën±Ì€‘JT@@SÌÒÆnÞ_9l#T sC «ù t4%@Jþü»WËÅçm½í \R"i ûͶ½oæûms÷:—tp5 tdी!ÿ_;þ«µƒY:4[:(â¼Òù)Î.PªØ¨thRŠqé#Lº K‡ÆÇÅÒQbêp¥#!äC¥CÉ^ö)=»á½ªÝy4Öáï.x@ŽÒ-­mDi™$µgÄ&‡¹¶BK±Äˆj\bTÜ®^.‰{eìáRRU/)%ª8«””Õ–-É–ɲ¥DV™Rw¥D¨fi)ÿó•¤t=zÝåc ·Æ5ãÏ¿ü>sýY±÷ä}•V’ûe½ïÁJÜk×gת ë±5¬ý1@ÑÉ9Gµ¶jP³I ÑmmðL<­Å"sXW!9»æ¾µÇ³1*&8èƒ'Jz…ØX8R pŸÎ€jz„›v¿ƒzáå‡@´‹¦ˆå¹Çw¶¨“Yø´•<¦íz\‚¬Hê‰ÔÇ‘Xk9j‚ D™,¡(ÄâZgæ9wß;?¸AŒ€/å`ðç‹uÒ®š•/ˆq–’k"3yR§¢QŽL¬Î,T@ö¨8†“4O™ ÈýJ$C=›§—®Í‰:õp)b yP³ÀEª\ _—3å(7w WˆpbH)+E ê)"†ýÀTÈC…±1T(ª}G¡B½³ˆnÉ¢v³P±3BÇ×èkÔŒ( ô\>À“ÖÝfÊ›HÓq.LÉì\‘•*À6‡‘U¦’bNõ©ƒ&6ÈéeÌk[ïSGØ’:h¨½ÃÌëñ ¥s ®-¤üâºùæ'›Å0çˆË4ÅɱѺŸŸ$-*éhŒ«i‰BÔè~jæ½Ï„¹8ß̽w°ŒèÆ5hÝîë/ÄíK£Ð™AK³Y6oÍ/£A 5ͨùˆÅ_3ìS…ãñÔ>7ËÃE›õ·Ëf·³7•ð†djTxÆoy ˜j;´W*ân},bóv{[{‚Dã‹ñs ·$ã` ?µÿ4¶øgh›Oîî4ÒÑm³ì2 ôç‡Ö?/ß/M¹¾'½ìÚ ÎŠÙÉà0xõð¤\þøá/c—¦º¸uñ f§^j~XWb¬‹%‰.Ö4£‹“ÑX,ö\œ£q§ô¯àc†0…õ/ú’Ñ¿Læõ¯ßýÑóLº“õŽòa#ÂQ¥É[DYÿu´LäSè*(fßò—£®"(8z@þ±ÕvÕM`è7hSyðV“<7-Ãͨ uoÉÕŽL¹*ÜŽ´^ µS®Ë1ðñÛà dJJNGÙ3÷×IÅÔ¥¯’ñ‡/PiÐÌ2uhܾe¦J\–Y%>Лx\ᕸ™gc<ጎE8ŠBF„³øÁÏÓˆgª‰pE3"y,á´‹p!ó"\*q²©ÊÌžÎPâAü€§f€çÈ1oi£ñ¬ip4Ü:¥ÁÇ0HZ®ip†¿ß¤\б?`9žÍ' ŒfÚ¹Y%RgDEOˆ¦•‘ÍM_4[Ê‚³œ²@)*‹¢È( ´Çq ŽG¾^XòLa‘jð*ùñÑpùó‰A)0Ags U4ø9!T͉ìh$ÑIãi±­lU€/Œä;×g(}|ºD·_îöËiÚ¬-Lh.qì3+Îø ÅÑðèw¦Çã44 =ñÝåTn¹Øý©s·Fß ò÷¹ôåýH½¦™IB›xúþ+rA± ðéRd‡o,;M0æ°»*pGzóh(gáš&dËÂ<׸ûö˜xc˜OþÇb^÷Ü=h·Î¼2½|¨eïÆ‰Ùûþ†Ñ1êÅJ™É>*Pöù~ Y·‹Ÿ=µ†9r3êyÌÒñ»Ÿ™ùAöûI™™|4ž)6œ$Zû¿Ð*??(†óƒôýáè@ÅlÍ;æèèAöG¿q‚¹ÑAóÔØˆ ÜÙ¿]ïWŸ›­2%fß¹[#ÍÞAI¹Ï ÌÞ}T*\ÐΩض+÷8ɵ; ÂÇEVî–˜‚6c½HO÷ÍŽ-šÕf÷}ãŒFªÛ»£˜IŠÁ½ýdg´èe ìØd,]øÆ)+ÃSXNy7¾mÝuû•«~émgÿœ}øûx{—µ‰oæÍ´òV»0¸¤ÁHôæCü+Lä¹·ßçKPØ*ͱÄSV˜{%_¾ð˜eíyWw6ì$“ s£¡ÙÍäæßõcÙÖendstream endobj 337 0 obj 2771 endobj 340 0 obj <> stream xœ­[Kܸ¾Oò#¾Ø¦ñ¡×ìa` âxç66M·Æ­¬ºÕÖÃcç×§(É¢ÄîiÛ‹=ì‚£&‹õøê«*î§U±U¬þÁoöWŸ®>­Ø´fþµÙ¯þ~wõ×wLÀJTÄ[Ý=^é°U¯2!¢‚¯îöW¯ÞìÊãPu¯ïþ{%y$c‘ÂGwÛ«WùZc"âEÎqíM{˜‹(–™ÀÅ¡kµÊã()R³úÛЛaìª^ýMð$’ ÿe‰ZùÒ“‘)Wò­%ìéj-‹(×2D|Ú9Ò4Îð×wj©ˆŠ$eæ°jlÊ¡Z?”}µ$Œ“(όؿÀË¡ÖÂÏÕ²f¼ˆd^¬Öê}îÝ®šÎåêžf—c×N[§Kíâ¦ÚÚ;æ‘àV}µÖ„°êvušéð}µ1²‰´[”Ý$Ë¢ÜIQÓ»Håœåfû5#rföh›…&7±j‚›2‘æ[-²Œò„ˆ¬eÈ#IdØV%ê'öí#Þ8.rcéRk\xÏ£LÌž€Æ‹BÆI$|k/x‡ú[Kø$‡X+÷Ô"ék²Hdþá`Û´°¾ó±:€úšúV…)¨€g‹;äÌm£Õ’D‰Ûº>ô“ã& üÑh¼©ûU–8#·FS–ݸúrwê;J¸Xîœfvgt4ÅÎjO»z3ˆEàNƾ»1à?Y^˜ãû¦ú!’ÜzŠñL¸bºˆD¹Š‘î3øÊVÛ BR29Ù,ÖaöˆZI£Ô9—ó¸ ‡@ÿüÛ[ôE™_†©„µTŸÝw&âÊf„x›Y”³ŸÅg*¬´h{…¶¾í‹ˆsàh{/{vÕѤO—ƒ*%•†€pËt­}¿Î÷Ÿêa‡HÍ–dAÀ8Ͷ;Í)i¦Ôˆ œHs‘SÓ¾ÚÂ$Cˆldª:C×HF «à)*OMÇHå+æK€GºU FÉžÐù #J’Ë%íäðK‚€ýø5Œè‰’N„%a•c§3” DØÑN¼4tQЇ’S÷WHØGÈ¥aS¸Ë]„¼÷å¾Bn’)s+ÈA3V(3)sžt OÈwýâO&½ezÓѦ|Ía@Õ}EVŸÐ )ÖdÀÞ,YòD^Ìr©ÏðÇú³‰µÔ¡2L•³çadš ÐJþô[«u­ò¡KIƒ,UÆ’%£ì¥lS}‰™öZ9õ{J5ßíÛŽšå%£Ž¯*¤P2§ñ5Nq,$å–tæŽt†b[‡RN–æaÂÍ­ÅâK(]šªù Ý>u¥_ȸ9}…~ œ´(þzdlÀW¤û}Œ» Ûr€O”Ó£ÿ©û¶>lëI 2ƒ h¥{ÐÁDAä+Ú,Ý2DÔXqo‹—— îŒrê%“Ù¦ 2k‹ ·‘ž;dºü,(ÛÛÃVo Ú5NÊÃvL4i|Dºja‚ÅrÈžiF™ÁÅ ë½åXÞòýûWOm§ML9°%¹ °ª[öþõ‡À¾åòÓ‡¥¬Ã݈¦ï·ËŸVËŸ>~xÿzò ®xN̉_Ü—Ûr)ÒCõ°ä˜›G-Â:§š4ßLÍ–y(sR©R®0Á¸ãý;E‚¦&„ˆgP?Gܘø9“âRÌmHlØÙ<´G'I?ÈB® ÞÇDLmÝŸº–Ä{ôWƵQ˜¶£î­XÐèQ­$,ªO£ÎA@c2Òsh0 Ap¸Bs°ù7ægôyË®5¸€¿%¥k60 µ4ò'´Ü¾5ðP`_•cÓ4  )¡ÔL¹ûöi×jœÀ‘Ò?ÂzxÿBÌõìµÇÎezp\ÚìÂïH‡éÄ]þ¡­ÇDøSé Ihiœ£)½Þ‰²-§Ô ÜnkEgÊ©*J”öl‹ÀtTÏÚQºmÕ×êuÉ!i1g¹!qwÀqt6Ò6{: 8Êbn†É¯—D|ReâÏõv´b3aÅ7]}œÔ}žÄÊ‚Á>t%Nw“ÅUXHÚè@ȳe/˜’~¿ LزK³|™sI!yAëæœ~»>v­î̇À=‡CÌ»"´Ü¤]á(æFQí’z—tæìM™˜“pÚF$U…% ¶Q•£ð‚ºiW‚‚P–¹Äb˜-„š3M‰ˆ§6FU…x&OÜ}ë…%¡k/@ða(7 (Ú£ûKŠB)3‡”,ÌTWjáTSô°ÙmHe~fN£ë´Õ&Ô»]9 ‰€ &ŸßC@ºöðäÿ~ë¼Î¹À|?,x"–‚«›JhŽvµ¯m$´ö¥u )ÜÎO,üàw5Œ ɯ†»ðâ¬:hv²ƒ]Åë ˆñTñçR1Ö~–UÑaÓñØÔx15PtŒÒ Ri‚r]D/ÚP<¤ WjUÅN-nJÝ”‘]¤VÒÃJÍ NGe€ˆU!qJ ÒêÁˆNis©ÖùXñzR³>j˨i_ ‰FÀ:Iú)ªkÇSoŠªÂÝáVàǤ´);g[€Ÿyä_¦.SÄ&¡~o.BæéR*ªnþ"” ýRýí; 2gû×ä>$Z¯#¯—· „Ó\>WŠˆý‘öbféÍ÷îß¾Óâ(GrÁ}qe+>„t >rsá($ÆšçS3û{&!'êô¦JWíhõ¹2›Ì$6¡É™2›üÔ–Ù,Ë"¬Í@¤Ü"7 õCµÜvóˆãXW¡³›«¾îêî×ɪ/g¿Ý¶@ÜSæbé&põ›‡åÚOË;}®6ƒnçø=m;,/¤N7ꀩž(¹@{\ž¨õëÒï^ô:Ùaö¬½É±ª¾pqmïMZ&7ÔH<£Vª49?ÝÈð¹½ =çaWk¯ã9í¡,éx‡ˆ„Gx»^^’ø/fñ§¦¯‰ª‹ì·/5Yf¤‰M<¯³wÁ©M¹Ø–¡…¤C’“è)ŽycŸÅ+!öå°”T(7{†èG*”›=_.Þß zÙ/‡®<ôGLN@—¹‹ØÆ rI}(Ÿ@²¡ÆǯM†§ÖIBîÒÕÌ{"†øñªÈvŽã°¼jøIà}×>}¸øãMÛ>>]Rv¡ŠüÆìâkRé—,Ï,¤/*)s{¶“óÿÇ€LYÛ±ÓDCÊÃS–ÐÜä‚2ÇŽ$ ÐÕ—`Å|HšÍêŸkT*IøHép%ÌÑÌs°œ[ÚA6Å´n¼~M eêÂÎÃtjÐsþ&yçL¯M_Qœñ¼c6"/׊gÅóu—yÂC³n{úìM7”X›.­^,5ZÛ.'úÿ†gŒ×˜š3§,ÓUNh«Òš” ~Ïüï ~»Ýqx²£Rdožë“¬Jx ™ý†^ˆ{yú *’LžMbÿùnõï+õÏÿºf%endstream endobj 341 0 obj 3587 endobj 344 0 obj <> stream xœ½ZKsÛFÞ³6?‚µ—$µæóÀË—­8QUœÈk3Ùu9>À$,aC4ÊÒ¿ßž™žéÊòÁ.WYUp¦Ÿ_݃÷³DÈYbÿáßåæìýÙû™tkáÏr3{º8{üBjXeRÊÙâÝ™ÿœ•É,×Z”j¶Øœ}“gß.þw¦e&в€ç‹ÕÙ7OÏ_ürþìü•}’¥"ÉUŽOž]þtéÞOE™fWS‘ÚŹ‘9l›Ï榅{òÖ®§"7¥ÄwïìJ)dR&.õ×µ]”…H³\áâç?^üvn× ü>7)®WÛ•]T ½¼8ÿï‰eDNbíºfÓôÍ{Rp5êý#wb*²"n2¹ówÏŸ?s«…(òÌળŒ”"SQ¯j¹¬wýÞVÈtЮéÝˉÈÒ"ìºoÝš2/d´BåÞTZhÒaÒ6}}ë_UB—ñÕö{S %ãA•]ѳ2 ²¯ê¯¶µÓt®Ë\høý$I ´™-’Î[Ö«CW£5ùbYmÑbI’1œË3aàÈhn/….È燽—AÇH…jv1G*ø€)¢þ›Ýºêká´u¹– E.Œ{þ[Û×Oœ¸J¤E4_x[‚ yý]{èúkÔMê¨Û»¶Û¸·3‘Ëck‘jrJãb5çÅ0kö葤Œo7[oŒ6 }º]W÷Þ"¦*‹VÍßë®ÞbÎ%E «~í2Éê®H™® BÛæ(† )IïV;Ÿ¯IBñºEóqlB†K¡Té"FyDh¯Z¥EL³]Õ;”ÉdÑý5,ûxÍEjÒàèÞoš°M)E´…ÅKÍ _N enLgE³;t;Lç’¥ó¾vÖSR¤éqJQš\þ¾xþ»Ã¿TŠ$=†Jpš¶AÂÓüåâò9Â,$¼ÉS–§?ú%ž}¨× IëÛ ’ ~„x阤qA¿k×ëc2'W|h¶Wè7ÅÂ×ÙV„µ¼ËRª*í$ší¾ï˾Pt¶)-E¸î&Ñ`€€T;¿YVk'_èAE«ÔFÐó/t; ÊжàIhTív>…aYQ”¾~}û=ÃdxrûOýfâåô‡@¡cKË}dýýÌŠõõgêu{èw‡>iªyN\÷µAƈŒò–Ány‹}\0ãVëþº=\]㺼?ʾêö¡L2¡Y\¸°HEÄ=:/áX‚ÈTÐÚ¶ÚÔ«ù~Ýö¸@Gy\6RËb]Cj!m´± $ß×+„{%Mö‰²ÝQó@æ:‡ªQ*Vná™ ÍÈã’©xé8Ò’uBÿŒ³" ÙCˆBÁ–[[F|0À¸ˆÄµ‘[pci‘,Ñ¥(JV±×k„À삊j,fÀ‹¨˜õíx‹úÆ#NÉÊxµ> €]• ª¿ªˆÚ×·Pò÷{ŒÂ²èBY&Á2ÄæÔT’€¬ EZ¬ÞŠdv²¬1{YªG¾X2.ÃEà¾E³é‰ÁÛx—¦åÑéCrsãÝdÉ_yÚsË*$¤¶…%ÚnJȈQ*åú<òUA³ð¡ñÔξXŽ8u) E#Š) +Mõv]# „n·èz&¾å€Hgy±î`„ÓTw¸òM‰­ËE„7sÊù;Š %hDÉsBÞõ!$+£© €ˆíRÌjCpôäHƒ¾ æò©4ÿô~à“Ó¼l9Õ9<4ÿ ´£ät‘à™õˆa€ã4†Úùáj˜*8šäÐlÔ„´³ÁpOn½ëÁšjP+YÕT×€ó°L?©}M9]`Q¸˜0PŸyÉÄó@XqH¹è[ÿ¢ePÄzí®m”XQTËþP­}†€×Y‡ZŠ2aiéôP¯ ;l‰y<Ù‚&{$ÊÅ;½c€tçOA3‹‹¬IÈÅš?bêðÐçKðcV[#IÍyÙ<Ñ@.ñÍœêÖuµ½Â6v 8™â  —WÊIN&øî maÄ]l|{i,TFQ'´üz5ÖòªîѤ «™]×vûTzÀB©ÏOÅï˾û(:ô2Í8çúárõíkÛàPŒ0x•Œ$,Â×{%¬¦ ÒRžÌe–ZW³˜üL6|Í„Aã­e+Ãõª=Œµj·_÷ãC÷ÕÝøÝa¾6d Wk¿>ѵ®À°P¤‚›ªS4:Šó‘6‚ê«"ð;]_SÆ„â¼- ÉÏø[ Ã@ÙÁ ËXà`òÀ%ZŽ"úp†½÷`wNe4œŠTœA2°†’$ii7 ßɶ°Þ.×í«‹±ãŽN÷ãgYæM2v- yƆŠ÷Ï7íEèÙ/¤›þõˆ­–ü´ë=†'›b†qFÉÒfg^~ªhŒÕu‚û “’á<0Ž<ÃÇmBÎ ÞVŽlwL—ƉßívÇlv ¢6Žñè„á§X« fŽ—eÇ“sà˜È JÙþe×γŸ½ŸAà[í“Ù<›IèØíVZA÷^öÂåéÅÙã‹_g}w¨Ïÿg&Ïÿlÿ{úü{øsñÃìogçnŸé[°ìÄ­ŒÊeqPÃ1™»™ù¾Ý¼×Ý)ÁrmºŸ_°<·­ì岪OÈ¥¤þ"SŽìh&WèÞ§„‚–ÒrÜÏ.”ñÐÏŒÕS ‡´¾ÃIé” ¹EÌ/ hî’œ ú‡'f¼}nׇÍ)7ki©üçÔvPÐ_0Aõ“S"Ù¡IöD‚V¥¤êw«ÄC¨ï4ô[zìµ(‹/"j©r’¨ ‡)o€wÍrBPLãK Œ±·[†Ç#»:%ânT žvM§F*Ÿ«î«2»«ï|€ºcÍhÂë_/HîÛznçsžƒ(;­U\–EþfŠøÙáuÇ“0ÉŠÌäÜÅUéX{S{TôÌä-…½ÖŽs%ðŽQG|áèþ4P‘Œ—åHìÙ 6]X±ãþ±˜½?Da;®ªGbmg–NÝë1î'óF(ôÏZ³ËS¨ˆ{áŸCm‚*o·ñÓÒÅÜŽq†-Éq³hý ïeaêa/ù_Û~± ü6%þääX7þzaÄÿK€Kvˆ$.ÛÍï`#ÃÈ•7yʇžÍÇ*ÈRVCƒ’8 u¡Gœ#ÅNÿ1%ýÐÁ¦v36ÞcìMî6l¿¢±û`¨ÓôÒ²¹¡mŒ¼f ãÐØ²d|ðŒúzýÂâ¦Þ`ºefjy~®KŽoFcc{¸Á1Ä”2à¸ÔÖ°ñ:å|XÚÄ6¯Ã 1ôÿD>ÐùT‡¨Çv€Ò|˜–§Ò:ù’¨ÏÆ£"Wv&=ìnìtSËñ´ s–=þ;œ€P)¸‰àôÓÊ›´¾ÏÔ1hç&±œ„ב%s²ƒ/[F–´Ó™hÉ‹žDŠŽ·„9õèÍz]_Uk¬cjÔK~¥HSœd0Œý›_Üóy•§¼|"¸¸ I†3{ÀÜôøkŸB¿ö ÃDM˜ƒÓæa#‰Q!ùøæ®¿Èc8òÔk¬I;ïÖ3B®k°}ʓݷ‰Ã«°ÊGUB•ÔWf0 a ²„éuÿ§eEFV7çóŸÒ$¼5#­ÌçB2ldeì8¤¬9é{%<ÈÚÞ"QÁ £ð„¹ê¤ý¬D©mdS|YOÜ.¾^\¾y„L&1ävÕUMÓ„ ‹)1d ÝfMÓ™h{ £Í6š6 n¹ñM!ß¡‡Á{&¾5}·“ eܸ‰ˆÄÅo\þrEs¯0‰1õøó›u󶫺»ñ/âÈöÏo™m®~Ùó'—c0^=’ƒ}@áäcÉݺÂu6cBøóÇÓÏRZ?ò[%N(²ÇôǹóÁôÇ~1å>¿­–}¼@Ò*n½nþÂ}4»b£Ë}Y¨íWañšâÖ¤½Z³)œ+¾d$B’ð«›ÇÚð šÞMÜǦü¦é¦Áyà3ë5ªX)¹d¡°¯wU¾Md4}àûËúñüàÚ> stream xœí[Ko9¾{çG˜‹°8ÍW³¹— ñx±sØ™ÝÄÀâ9t¤Ž¥…^‘Z üï—"Yì¦dX¬CJ]]¬×÷U•üeR:©ì?ø¶¾úrõeBÝYøo¶ž¼»¿úù=åæ„èJÓÉýç+ÿèj¢8'šMî×W×·‹v×wûŸîÿ}%¯Í—îçW×Í_íå„é†ÁÙívã5©„âpØï·+{Ê*"uN?ôûã¬?ýŒ3I„¤ð™Röìç÷ŠNŒüÊ(hõ› #Aéz2š4·û®9Š4š*°ðÏóì~S£•¦µšLYM˜ð·ßßß½½ý»»$ªŽ·›·}ë”nˆ¤µWéÖ»UÛwöIÍ',¼ñázµü´o÷Oãvûí¬›››>üd?œR¥¯ädjm#=ò‡­Ô]PVKŽÙø˜â”f¤i’ýAiÿú¡×§TÖDqjÔ©AÙv½n7s'JrR«¨ÍÝWç^F¤Š>oWG#Ü{±ÆÒ/œhCX5RÆY\nºZz÷}Ea²ïvîPiô€ÃΘ¯œ©M V‚7ö¨&\è*m73÷2&ObMà8±51Á£XJT:)ìBIg"×ݬ\§(ÿä_-j­ oÖªtB{ûÙQ¢U<Ë Å†èôÈHÎ/Sa¢Ç¨‰¢è× Zñ蜵Icãçè„EëòÔäO§ÛMiÚˆ±&;ÒW£¯LJñxÚúwùì—_¡N(déÍ Ü¸©^`~®ÊdwnBWx ×pO¤¦;2'">{ŒzÓNÈuÁÅ÷:cºj^ÒÖëáÑC».ØwÕmû…ó“¨1%®ï½¦ˆH† F6N­HUSçÔÊW¨åfwìêL ÏÌÀ…檄ÙMÂ]-¾Ù#Ed2Ëv??Ü@D¨*–“å¸N–þ¶X:71jo °›´y6½eÖ:H­QèucÏgEA®cQXÀÿMÒ ûê_¦yCƒs|š;3YÑÑâ(ý•.¤?Êà,þX~±†E[¹/ "Òɢݷ3ƒ‘>1¹hlDõô×MÈT5 VpŽ0BjF‡±×TN±÷´›²}¼ðì›÷wîÁZŒE‡›jk¹súr“#2:‡ ÂSq)jµ+(°ï—žp«D aHd‡&ãZˆd¢"„ÊË wlí(ƒÔ~ Öô¼¦ûåãNQ.ö>M"Ø(LÕ”„ò¡²&EÅ>‡11÷ §ÛÏŽû=Xß䵌–ê=ØåPZ’¹Ü=´;5š«q6ÀÙö؇i@>XhÇŽ(vùc:pÆdíxç’µFCG˜Å)ÃGÒ,n3‡<3 ƒ›;2v¬[€T¸<…ÇöÓ‚5¬]dH ßBû،ڇ¥Qâ!+î–Üvµã®ô”Ø Î~n¶üìljµ6bÛЖP‡)ºúwg¨œ£ìw:ކAUJÜ ÆáŸÂe ÿ$žlÃðÏܰiJ˜2T0…Vž‰T8;ý34Ÿ%DS}¼“îñ 5ÑoÅ ESgv OV_†qGìXZcser›[¶ÓõFMÊäðpÒ¬_1i̲A]´G!3Þš¹¡g\`¸«iW€‰Â|ip~¡ˆäæK¦…2_!„ºÅSdJT…³“ªá('S+%ðh¡LŠ‘;Û’zبÑ@ÕK©¢2/wõÃõÁÇ”íŒê!ÿvñ?ž¦Õ/Êj'š€auòÐÃõÛÕ ÔCìIªs™ÂÄ5¹© íSÍ(Ì;‹ íê2çi—ò•=˜É{Ë jÉH0iœÏI>vjq¤]2|ëÖÏMÝ¡æŠjPòn f ®­¨‘O½„YæÞ/†A6¡yÂéTõØnRqžïõ®¹JÆq}ñ¢"õèMæºOb¼¤Ê`j¶ÝÌŒ 6¡ ¨%ã”Óþ'&ÛLýþþ¿ q†'nü²ðŽûŸÞ@@^–—%Àe pYøPº,.K€Ëಸ,æ—%À$ÿï—S^7~èŸú ][–€èã`¨92½ÔŸ7€|uêNvícà-ÝJ{(ªæå5¥n(0XCßÖ¿`A>Üïô¯‚Ë¿"~Õo…©%ñ8%°Ùo–ÿ ¥áG§Ñ¡¯YIÄŸfÝÖçí~ y§°YO&DÌòóD%GóÄ|‘טš’œéûìO’ÑÉ)©â¡o§y¨Yë¸û‚¿ïãÄ#åã!Tº ?Üýv÷ÛíK“Ž4™ 5i(8e·K ú±éË{Ü g"Q¨KD¡)®²èH?6F\%ÓóõTãuzz÷4±’Ü;¨ÑŠc=Çe787t;xa…D¥Ãï‰9¾1²Y'°(ž=Xà ÄÈ`h»y€®2Ò³ïìß\Š,UTä4°àF°Ä T|¾üKè´³ùXâ¼H¼ÉnMºìçývíÝTi8­¡ŸýQ@T®H³dq5¤Äh‚n’M  zÜÐéñÒ+“ŽÖ)G|I½6lYQõxvnk)ïG ý\ˆÌõ.ì)›&O™&r˜¶0ÌX dzxQTÅ-±1Jú{¡å§#üEÉ”kacåØfÛ/ÂÅVŠaè‡þ ©¸@úaÓ®ÆÌÈ'MXØ¢B’1<¨?³F)-?Z w4™à §Ì÷ü€œƒþx&îöQGm½ã ÉÝýä_WößuÆÜendstream endobj 349 0 obj 2773 endobj 352 0 obj <> stream xœíZKÛ6¾/ò#ŒöÐX3âC”t òpŠ ‹ݸ‡"›ƒbkcZÛ‘äý÷’Ç,ÚÞE ´ ŒPÒpžß73ëO“„ÐI¢þáÿ‹»‹OŸ&TŸÙÿw“çó‹'הà )’‚Næ·æ:)’IÆ9)Ød~wñ8ËžÿuÁ©$y‘ÃóùòâñóÙõ¯³«ÙŸê‰LI’± Ÿ\ýöËoúý”©äxš’TNEÂ@l6™Š‚äúÉëµz@9ɲœáÛ¥:*cEb/ì«»mSöÕ¥z$r"uV•‘+ÉVD÷÷æIfµø Õ%B‰UwÓè×yöۧ׳·smC:¤ÛjÛV]¥õå¡©³¹ïPçNHT«mD¶¯7F¦RB¤öüe¦YNÉ\–½öƒ0pçðz½ÝõúXù1µRû z[Ðãš¶õÇž /µ7AdÒä$y¨­ ”ïkË"r'÷®ÒqaŒHq,.U‹¹7±k[tB’Ô¹ªoþFUÙÑXWõú£¾\ԧ殫–úT’´p§¥ )ø´8nÐS|ªÂÜk6ýôQÓT-QSAr›CóUi¢y™ù`u:­¡Â¨tÔÆ¥”H×€ï'X›|•å.‰ëCå-rB¦¼{†ÏS—ÏQ& O-r «ÿ>K&ÊŒ=–ÌB´, M†—‹, Íî¸M‚4ã6I"¬ MB¢”á1‚äÖŽ0dîh R×}Ë$%ÂÇMŠ–J—Ê÷X’c–Ì=^gÉ 9Í’ycÉÌ·N§Y²(N3 >w,ɳKwÿˆxyï ¹Gð)õŸæFˆn"Z’,qߦØ#¦“}Ê%ÌW¿­lÖ2OEïÞÎÞÌgo^ÌÞkdºÈ-×}¬,¡y+ s% ЛÚÉèDa„ )gS®€F¿ø¨é ¨Œ¢>™BÉŒª¯^_Íg×cŠëoì”X®\ýÕúš¾yÜÔÚ²ÕžJi˜ÆÛv~ÞµUœ7Ásd\„.Üìz(磾‹ ”‘´h—c4Þ´c€kꮿ´µêçÃe¥Y¸—û†¦Z/±Î€dÂñÎLÎQà4=¼j°\l1ɃO1Se`à¿1@j+‡séÂi"L•õÚš™EV@·ûÐUÆ*åÕ½Wó 7!Ò­"=Úýçȃ’$îã›Ç·&®jñ&—Ɖa®Bmòn úF—AO¶Ðy6.+hG=ª €Ì|ßt¢‰Š:ñpduãcà;Z‚`…‹À§K"ÐÃxæ}L©ÔD=X¬Ç‚. ½cŠÉ‘S¹@"¾ [¡R:=pÉ0ˆâÆ.¨/øÃ‘Õ8ÉüØçú¼hC²×=Ú)#è|”hÝc !}ÉGÆ¢®W7À(v}Ô£Òrç|^Ãä+B¨™_c­#Ê3´ÂÎöŒ±¯ ªÁÒÚöìêíÌy ÷ú"ÿlÞ¦ÞH›ŠøÖÌÊx};vEÔ¿q‰ã²q½^ 0n÷%~œ$a¶“pTŸÅÚòNc÷phÝxŠa9$€»¾îwæbµ ¥Žd{—Ivļz½hvKlbTäkúðìczÐ$Ô®&\r¸gðÜüÕZåm[¯{ë­·µíC†ÝÅŸ7_ªf‹@”yþP5ÕvUY 4ßi˜[UU¢UJ—+¥ËO‘~‚>/¦Ï‹éóbú¼˜>/¦ÿÓÅ4”úÊ5ÂÃÓÓ\›©ftp 9á¼/ý.ö¥ì^à}^—~ÛëRlÎûÒox_:Ú^òœ›ý)Wƒ¤~ó‘IˆÓ»Ë7/±Ñ ö÷Ü\lÚ\{rs™Cþ¥òðæ2ó|…¼G­™ôr˜·áƒáñEEíãe¼Ïý,rãZAµqoÇ5~t&¦þxáWµ€úr}› âžDa4ƒ?³i/Y éx),šJDD+=·êô\~;,¾¬ê……Dÿª]B½¥ÒþÑuIðK®ƒû$ƒw,L€•¢Ïñ<Ƀ&¦ûÛ¡Ò}cü<ÈÝ ¢JÕ|vPD¾†D¸²íMtŠ ÑÃÖò×ǵîí„ }нµItõ”œZ=Ìa:ú©Ä€¶À;æ Lé¹7[ _]o¬–þîng÷«¹îWMkAé(Ò\ŽmŠn¡!frŸ®H"تÆÏ~ŽÙ¬£¦ ÆË"Ò½Ÿ7:ßæF‡…Êž:VÎ óB'J³ÿÑBÛ£ÿ÷Fçü ¸å÷¸Ñ9ÿnß­ßåJçü ¸=ôþö6:³ùä÷ õïñ?R€endstream endobj 353 0 obj 2192 endobj 356 0 obj <> stream xœµZmoܸîg÷Ðß°¸/½^E”¨º@ƒœ/‡HziìC{°ýA–å¬z»ÒF«Ï_úÛ;$‡œáJ~IE€àJäpæ™gÞôyGbëø·Þ}>ú¼fÍý©7‹ïÏ^~)¬D*Vbq~{d_ /Š4T²8ß}wºª¶c3¼8ÿ÷‘L"§92ÊÌ¢¬ðÊ<Ç}ÒGÔ#ÈèæúºÊ ²ßäÉôfîM³™ŠÀ»tzµKeBKÖÜzÉí§WŠ(£ûånÝÛÁÅ·û®Û¾3·”ú(á¶=Ÿlr¿mëj½¾wX¤+¶ö>‚# ÝáZ.rÖ÷³H1¤ìv=j£È¼ï×m5¶_Œš3 äx4 Àñg•2ÎøÏpsùâ/®&Ä’*Æ=†²‘79›÷A§«jœšJ[…Œ¢/èÝÒRx…Ÿ@Œá®Ý5FÂL1qå¬Î¸& «,ʉËçdüf°ö&fªÃGÛܘk–<0ݵã 7¦+½–e}s™2›|³^Û]’"l¶KB  ÛÈØ{m×ü6.Ç~¹®¬œYi“ë²E]‚»Å!Às𪳲 peæ•ò”|Ì\°©Pô¼h½ êtÇ6šöµu´’¥œVGy=ZÙEˆty”ƒtŒ#7=¾PpÎyTĶ⸚»þØ”š‚M†Y Á*/ç`•ªXÙÜÃmñ4¢ØÈQS?ƒ+5”|ÞØ“dL+ÉÜ`Ýܺ¤€;™‡c?Ž,u— GdyîíÐ;jO³Ç=n;4_Ú~¿CzŠ)ul¾X:vònV­÷%’”d¬,¬Ø´}Ø9Eªf·Cb7¬{ŸR°\Œx>ñ2ï)sì¾C2UŽíõ+ ÷ á”%÷ǽI‰NWÕ”bÖ—%  Q<÷˜K›ŽàëoµknŒ²Ñypy«®Ñþ·lcS¡f˜è÷”‘9¡º~œbæ¡ü¶Œ¾´Ù²x(ù S¹ß2)ËH i &•ÇÂüô÷~lN0KéúoSìò`tŒyt£ß”±-u*þÉš'¾ã—ñièû> ¥ ï_ÿË¥šœ \†uÉ„ŽØÞ¶OE2ÝžF² ‘±>fBñ Q¹Ìï0•’QÀ£óÄçi~ƒ7`‰ãœFgº žË%½ú`,CM¥åø‡!‘À°ÅŠ‚Ç×L æŸºSbÒôu.qbE5¸ÖN.}.oª’¥*¬±˜ö°D 6×yÞývÆëíö˜z¹WÄÌîefÃÑÊÅ%X~èï¦o|Û ƒ Eᘞ†ÎÚtýþÓj†žHžp*0¯±«Ë–dÓáôð>Ä*Œƒ›aÑû5bRã+ᨑUQ¯’«+LSò]fŒe’êzˆ))sÊmiTrb;kfz€á+wÆTÛêSƒtÃjôD¡³åäÇÖÙ8W]¸4 ȦÌ}Ûã{èA{ÎTäÄKî ÈÞò`ДÄuáæz~$¬ÕC¿ÛmªíœËΚN?þtvöþõäj6":˜6¥Ô-ÑmQ× ß9œ8±—&N 7FävJøôã³/aR/'S$A$|h䥄®Q9ñ‘8å?Õ4µa½âTðN çÔ«¶ÃŠÒ*¶íl×vIvx–„ÍÑ÷AÅÈÔôX?d¡Zcj¼©j+›ê­p–å±²] 6ÔðÚ;3ÚÚëýhsçeª¤Ï>ÄÇâ°UΓ}7VJ×?ö_‚¨5ÛHrŠû‹Ñœî"ôüóYå÷â`zàg„1½ªïã:Ry’Ä‚3Póy_Ù©µ–›F3Š›o[í]ÔsîÂJQ‘ ¹Æ0¢(X¦ xŒ}½CLbÁŒL½ø»-®±»o=Õg]á°’Ö¢ñÍlVˆúaV×á0+‰5©Oœ"ãE¦¿00G6íp¥úSC3|²9¹íúø6mƇ¤ÁrÐìIØI¾q_ýŠPü$ô^È!' tZÌYäу=T|Â)x0ÞŦ¦Ú†”žPo:¡4´AþÒ”éo@üåýq6 Æni¦7|îWäà¤$Í“Ìñ…}È€½A Tm qê«y9!Gœ4™D¨¸˜ÀúqjP Àú˪jnÚ?âÍÒ„W;¾Y¯?Üð¦Å-L‡'Wåtò™†Ó繊‰÷ ‚žŠÇ°.¤JÞÀùZ«•¼2eƒ6%-gfå(mÕI«b¹üT Ûj¨Öëfm.A]4jõ_5(²Ó¼‡:oäühaíº% ø¦în×b[Ìc/Æ™­¶š°,ãõØv60"|:ìÝ*¥qØïò ¹ ø–}v·jk$ IõrBSþÞ5¾×Àròß1L Ä®¤Ww®·^ðŒeÝtŸÆæú‡-²8Ò Yó ‘–üV¶ «ÊË *së‹»~¸A²Ty®¸ƒò MÈKñ™ÙõT°úÊ%”Ä´3g$ÓWS\b5¥¼r…\Fò0qaËPÆj¦­Ò™59s1üzf¿ë™ý®gö«g.]'Ó3ê™ýj‰­CH”³ÀC_YÈÑÜ) ñ°çòæ|ñý]²”ö“ä%ÔE‹Réø¿P ‚,õ§Ëß¿=zùöýböÍÑË.ÄÑË¿éÿ¾ÿp Þþ°øÃÑ›·vŸÙï›@ç?pÎô)%›4Ÿ8 Ñt¡8ÏÓR? Ùž^™:è‚ïÝ·Ð:Sgzªh»|z®˜+§àw½µéøœûúþ ?(É„ðãÞ¦ F/úß¡¦Îendstream endobj 357 0 obj 3300 endobj 366 0 obj <> stream xœÍZÍoܺ¿ù#Œæð’Ö«'R¤>ÒC÷šAM|)â”]9V¡]mV»vÓCÿöÉ!g¸”×~M >¸äp>~ó›}=Ï3qž›?ü¿\Ÿ}=ûz.ì3ÿo¹>ÿåòìç÷¢€'Y“7âüòúÌý@œ7ùyUY#Ï/×gÏêüùå?Î QfuSÃûËÕÙ³_^¿ÿëë·¯ÿnÞ”:Ë+Yá›·ïþòή×Y£ËŸêL›‡?¿¯Ä¹(²N4.”¨à˜ê|¡š¬¶+—í´lW[]DâÉÖ,d™I·ô×W~}õ§×f©ÒYU%žÖmVûnÚ§/öÝz;´{»»Yѱ§}»Ûß¶ÃÁ¾+%ÜDtﮞ ýç]»û†?Ó"ül»—Ýê°ë®ž›— ©«¬ê|—”øc&füãXÌR‘˜ë­0Oá »ò"Þº‡ []´TÎ-•¸´*ÃÒ,˼”yžåµ“2¯ÿÿÄLÝoÚÁ[ÏÝâØy²(³ ükžÚ8å‡ýö°Ÿ¬è`nI¢ßX;KÐCÙuÓaØ;gϪBi|>^›g «RןµÛíð­ß|A­Ô­]œg…‘+u;B’n¯ž;»¾6aà7Ÿº[ûPeŠTÐíÚ*,޶ž.¬áTVTÁoÛ w©Š w÷OXÞoº••¥É%|L¶žŸ©²É½ºa´[€-HMwèEÊÝ”Ì×wÝÖ.‡h/Ãe:n5ØØLÉUáï~áÎ^„»~cïXpð°­3 ‚ùß~éoÑ&ÌsºVÕ^õv™Î„ Æð1ztÆ“a@kÊ&+Èöè(¦èJÓ0Z7MVѳKŸì\äH)¶´_wöú²ÊD­½ºÛÍ ½² hÛZ…‡äª ®®Ž]Udª *èÚ%úA™‡ ¬š›HùÆ¥ûe»ïG«ÇEQÕÆŽ%HKEžÉ&ÑDwh ®£›põktø$¹cÍýìzÐý@ÍJëà#h'È%Lx  t™åBq4x³Agn(èdI'O=•‡<€JÐp€„2Žc§9.àÌ Æ ½¹ë:´~‘‡MúÁ*+}/(k]"X ¾ÉÔ-Gç.À™Âî‚P«ÙæÂ’$ÇÀ¸ÒÌÆM·ðv+èæàt çMN'XäOè4TM“€S†I%—l.oÚ=ª J¢*Ê N±íP²1æ ûBt¼Aùe”8ë.=pãà¡"x8¬1Xj{†ŒA;Äšœ–aðYÿ Б>ù8¥H¿z¶E{°œÒínÚí„ä)'“þ«ÛWÏc˜Í•¿Ó»:2*:4 3@«Œ£×cQ„|÷jLz†exE£Ô\¨´sð9†Ç€ Î:¾€²^øU“sgíoúß¡Qqôü“wÃq“Ús:|žº¯—/TÍýÒ^£Ê”¤˜8¥ —v!*Ò.I­Ó”1§¡…‚|WˆÅWS3£&ðÂ>`Ùu&CÆÉŽ3„œñ™x÷Û~<8òT„œPˆõRð X¨û|Ëÿ{‰H݉ )űՈ1òðEê°ÅªÛw»µ'K!×ÌHŸ“;|sgj(ÊSºe‘Èè°uá ‰RMñy㤫³¸]¶t(AÌqNaåKîÑàFN+‚ÈNëÄ—léfÜlº/ µ[Äðšw®ÙaýÆ=«˜kì»/Ýî"õÄ~&ßÝôKÌuŠƒd¥QM.Ãí§™¢,fƒ±é£¤RGIÅ…_•C¥CX1¹¬È„²¬ƒ}¤ Ìâ[ª2›!.Ð¥ @qô6µ%„éÊŸP\äA`—²}jŽmç•r‘B`°KNÑtÒ.à/âØ,*H‚¹=&EW É={@ëÀ;€Ó•:ª®$šACbLÛ[¤%'¤ódÞð3RÎ÷m}àÖUX|×CºÅ}±Xe%{t˜èáœ*aÉ:rä¹Kcä¯Zõ$ôcôuuŠ^º¸ˆ¢hŽj¿À-NÖ~xÆñxTÕsåAAÚàœ»2{—Õx6aÀ ‚Õ4Õg›èá¡ó\žåuä÷F¬P"<˜[9{±ãˆ®)4OV³¬+‚K´þÙýÖ@Wo?¼ÎÐÆ¬Âºò•Reú!Éúœ±Pyi¢–…áókMr»•5i )‰Ë¨Ð‹/l*b–;"ìf »~ã~3ùWõ Ee‡wîƒ @@ëgKÒi?n·Pj†ž™ Óq=yZ®S*u*ñ[xÚ!ŠÇ¢`a®œÝÔ©¯±œ"纑f\“Ì.÷ t½×H;ÖÅaǺá*¹˜ñï¨üõÞðlæu¶»@Ë!ÝKŽ ó¾ï¬·Q"źïŒßõXÁkƒk3¤u0"Í” §S†gœŒWV(oMÉFв:,Ñâ‚§¶{Yg×9iè¡f2GÎ)«Çó| Ä¦áXó ˆýc¦÷î6ê<®]ÏTñ(ÀKAY”SîY7(`뤛sìéÛ:UÁLN„ú‚꡺¤îˆÏ¤B΂åÊÈ¢rT·wD Oª=噇6-VßÛ~åÇ<¦\¡þÐÊQh§#mªÈ¤¡€‚ZguOv¾Žˆ¬©…øPÔÇÙ¶àôöqÔþ %kš»© ÊªÕÉ×ÈM,ÌPT”¯ß°Ñ!ã©eæã/lX»Å€ŽZÕG”‡UrWÈfPÏGºä|†¦›a o!@3g²¶ïG³6Pïk~Ac ÓuÀ*>&;FRü5ÖÎGy¯vØ÷vNä9 Ïr,KÝt¥ºþaMàÈ”^QkÈèyDC·ì¾0ÌMˆxxQ%LÃ!õ»YÛ½‚STc@%T›F3uXŸGA†DTQöãǼÀäa§$A¬†ßlÉLP ?wþÃ3ƒdä$/eª®lzšáµÁ0êž/8r‘=Ødî~‘ñ«ÉÇŸÑqi“ "²ÉÊ*bdG…C›Þ£¨fîÃ"ïhS³ÄclãgÅì¦o|°l½÷%¯ þ7ÑšB2ÂëŠæt) ÖéH-º¢°R:É(vxû²ˆ†3óå1 ó•cØÂŒ–9+ß ÈˆtxÉÌ: Àà«´×Rò6N\K×uÚkyÈÊO0WKe¼3äww±¹¶DTÅpû¥€8o Àü€§Ñø?ç-7ç¦vòñEÍÜô”œÕ˜ã‡9kTó‡ËÊ{œ5O¼%šl#ÌMPXtÅ^ÜH îòð¬›ul™âÁ´1'Œ¢yS KfiŽ57Å/÷¡E©‰ü›e‡ýþ¼4i˜Åc{½Ç1KdØÙfZF¼"îÂ÷U¢I[¬9²OO:ÀJAa@ cÏe–‡áoê¼wQY¯uQYË3Ѥà6‘–MÔjF £2èºÿ T|¹ì5Ô^¸/¸*e>•eÁEBªœg+^ºÅ_¾Ø¤'|9ó‰ç<$±âM~J× \ÇÊjØïú³>òðµ*0IÍ¿©õžà¾~kÕóÓ‘ŒÛþËÐâçèFw£ë?/Jð/óï.þ Å…;kˆóÂ54æ*Ú[qD%Là öÑËïáêüx™Äo—À|rZðO:_Ì `—¿¾<ÿÛ™ùû¹GKendstream endobj 367 0 obj 3141 endobj 370 0 obj <> stream xœµXKÛ6¾»ýF/M€˜ßT{¶Û-K‚nœSÓƒbÓµYv$9éþûÉIÛÚݤA±‡F|Ìãû¾úã¼ t^¸?ü¿ÚÍ>Î>Ω·ÿV»ù/ËÙó[ÊÁBÊ¢¤óåf6ÐyYÌ5ç¤dóånöäz[Û=]þ=Œˆ‚+X´\Ïž˜ŸœrÂJÃÐv½o½±$…ÐC·oœ•D–j´¾ºãj8v¶wß8“DH:Míù-?ñoÁµ î_ˆ’¿ðÏûní÷ ¸ÿ…w‚‚©ü¡ºûóÝSg_(FJ.ä|¾áۮÚήô72-˜ö‹VU¿ªÖ–°)çp¥",œx}õæúê×›°XjB5è \6Ø~ð•D«˜ÑÁî£a*FÓU7|ªŠG1r;Øý;ü'nw¼{ÒÔﻪ»ó‡Q")D>ºýÊ®¡"!OçðXp©H ¶UcÞöÇáp| Ž¥P¶Ö×ÀŒôˆ¨õ±ñqs€‚+A°ï7~-#ª4c½j$C47Ñ÷OÞgWU(nýP·yp•D&`ö1aJD¿>×ÃÖ/—,ò¶¯vÞÊ4‘2¶n]ÀÄaKtX†3#2±oŸh&H¡ãuëú;ÛÙvå7¸4…Xû\.þ‰ÒC”¡‹•Ï|ÈH”7EäÛÚnª1Ï ¼‰.¶!ZDVw~;ÐJF¿÷ !B•ňŒ@(Ô±@±h"m Éñ;YˆQ–L*ð÷Ÿ¤"ɇ 5—À¿˜¶l8•LùŽ÷s϶µdšÉ@5 9ŠƒºTµý&Äö—·W¯Þüvs{ÉšS6gPsÜlªÁ^n©Û÷UÿÁø…—ñË7°èO@ =;Ù9¸ g â3ENJ˜<''' `4®=x£$2`!Ö5RѰHEëë\‚ä&”WͱêÐ+'\Æ(§nKî*o³ë«-™éô‘‰ÁËõþJ•_‰à¤¤Là¾×éá‚—Šx%ŒdtÂ2Rq³ÌѤHü´Õ Y§’q‹ ¡©eíìE¥fú;Á[vÎŽŒ±)EÊKSìž$EðLõbÉô$/u·œ)Êõë˜è]DÝ&Ó^°ú Ù@1FsÕNz%s¹€'"=ìU&Ÿ& ë>µ­Ûz¨«&ˆ7‡±ì¤ ÉpeÇ1Üåµré&XÕl`¹ÚàˆÅœú%îÜ‹”Ò9œðÇX.2ÓÊ9ÕÈ™gا²Ó'× Á†,D>v`ë¦ÐzXrpì˜eêh¾ÇoWû]˜wš¸µñ&=iíg<š}ì‹ÆD=D\ûÁÐÑ%IèËåH눺I§J‹‹T¬ïïv—^Op;LÎP+F£/^¾òÁQHA–û¤ßzyIhÒ·ÐNõ¤O«c×á)RBW.XêÊß"M›n¿C¥,/'™“—ÃÔ8–§i»~öÛA–SGÂ3™¹ÉøýÕéWiHyñúíGœ’ª¯È¿¡ù™ˆ´ØdJÖPw$Ñé²G*•ÏOþ¯Á1_2ˆK=¼oöæœ'/KbœÑ›kcûíþØ„±N¸c-Þä^zb$¢€Ê­ÜC"׃co×!2™yƒ¹U—$0ùó}ú¡“C}7ŽyaøΗ4³»©ÅÛ¤GXzujÁ¡«žç³ÆC½ƒéÆÔ¸Þñld¾úòËEѸºtOH¾@4ÇÓd<Í=-ï±Åa){0 uƒ*™ÍgÐ<ÇPÕâsš_Æ#At¡ê…ûIÕ'µ§ÇÙ‹§òn+ôŸ&ŽM<+ñ!R‚I]b0Þ`Ç_;²9:â¨)…€@ TyÀú3ÄšÑJH'a™‰fBž›2â];ÌröÎ »¡–ÊL±JŸÆ­³Ù¢ è’Y*@éÖõj¦áU–¸`ÿq2Ø#ô¤þ˜Ôó™={«ðû (5w:—)õÿîìÉÿÅè¶uJÇï$ÀiÌYE1ð{LJ¦cÙ`t9iy6ªž>¡—·lF’·7#x²§z‡ÐËÇÀ "çgŒŸôünAtÚ}> stream xœ5‹= Ã0 Dwý é¢ZþÐ0 Z:§t(xðÿ_§.7¼w×Уë½WhÐOö¯½âlpÝXBê”ÑÞð;0ªÃ$BêÑ*LÙ_쑲æÃÛ ¦¹l÷²”g71K> ³¬·õÜÒeÐ@¡Ãbø€ž/"ó"°endstream endobj 375 0 obj 125 endobj 378 0 obj <> stream xœ½YÛnÜ8}7ö#zò’ Ð͈¤¨KƒA&ëìˆ×Y§ØA2J·ìÖF-utÇ@0ß¾E±H–Z²Û³ ü`€R“źœsªôe0¾ôþßìϾœ}YðaÍþÛì?­Ïž_q +, R¾X_Ÿ™ðE,b)Y*ëýÙ³W»ìÐåÍ÷ëÿœ…‚…Œà¥õöìYúB¯qÉDš\»È6MÝêu)&¸ÂõDêµçW"\ðX¯‡úÀU(àt-Vaʳé°gÊdªÉžÏ¯b¾€°xø½}q%C™ Ø^¿nÞ–£ë‰ÎX‰ˆ |óâå««Ëá^ xhÏ;4õ¦Êö¹~¢8S\ÄøäEQúŽ?Q, +ÌâÈ=`ŒéE8: cë¤ÏÚC¾)²O©;áºnö¿×ë`¨`i.VÚÃf³¿¿v6«˜ñ''mîò¯ñÆ8Ø+. š |Ç G^ÎçLD)ÇŸ;oJÁ„€°™åbˆl&Økez .*ÒÀšÕðµ8NìŽîæ"dëòÁ`™0á‹"3ˆám\{[ß ëÔ“‘saÕvM¿éŠº~£ûtH‚‚ÄE’ Û ×*J|Fmêáuˆ$¤’<мà,N§ Sg ß3nÏ!òOM-§àjwÅMV–yÃ0)Rá“ýbH ¨éØ[ñê -S±óèå4Ïœãåÿ5ÛtåA¦üAeñw‘;h¸BÌ¢( lî¯/MF›nòC‡‰Âcùn—o W•Ï€·íb•ߢ_C¿x"+WaÅ–éH¦Ü>é ‰Åù¦Þ爟4±¶Ò$ "Ÿ¿b '>… J P$!Èat2‚ÉpˆÄç D `ñˆ@ŒqLzóÏóÁ¦ˆBímÑí HŠZ§Ã‰se‹è&b&¹+"M(¡!WR¤LßNcZtLH±ö†shc›úpõm~ÝØ$ê}@eŒ-DÐZi*4a1…)“‰&(´°š"JWT7˜kÜcM+Á‚S•ÝÔ%VZ»ß8|3p°H9+ ­Y“}*säŽÄ?ëjYöØ«ówç/Ñk*PÖëåðjÈ„/¨7¯—èÉ0qfÌW!d;€Íú¶FÙ@8ã§ïã#þ¾ß ×#_f; :vgÁ½.‚´½‹² m>#²r_·Ýq^yüdØcüvUw8±_üÒ]¾D "¹?Wý˜Q¡_Úö‡²ØX®Q’õ“É6xÛÃî UÁ­\íÕͶ¨²fx†PS%·@PÌ.û&ô—ºŸ¢çMÞM»]“çSÛn´i@Èž…JˆÂ³+ð±=r¦À»»ÃÌ O¾ýøã”c¾áï(íïGª÷TH~Žkš<ÛjŸ #ÓŠ¦;?!^ÍV“¦žzrUÜìºï¦o4†Ž°&|Dìß×Ms·œn†À1>ÚÞhì«[38²ÒÜéÉwÆ ®@‡Œ¼v’Ç¢1)zä)Ñ£µÓcˆ,dÜS6BÇۦ躼ZbaâàX“‰‚ƒ`¢ü/~aN7)PØÖVaMzS®{.Ò³m½ |sÖvdŸÒP¸éÖÿ¤p[¢Òä WvJ¦å§Ï 7Z¶,özà!¶"$4;ÈúÖ•¨"ƒ Kb$Ú– ¤¤úæ¶(mßHflº20Þ¤U:®‡|ÆÝº£>v7$?wîÖç°¦‰|qþï—ïÞs•BEMÕ e¡Û±P¶y[4¹AW®F¥a á5V[—}‡znœ°.µÈ Ñq=ø}f£EÊÙžFët^+ï¾ ë"8š»šÈ?¦zC<Òi¼KìÐ{:ƒ^7+ÍàfL¼ZŒÜÙHj^=רbŽA;˜’ =Yè»L{u¨—(¢rif&|ÏDyoÞŒ}aôF§’€š}SáÏSy< SD¤”…߀»¼žŸdE…ÞOÉè–ˆz*‡EàvŸ#6õ¸>bvãüŠÓ¡^±³©H´¯›Ú&ŠLm3D#Xç£6È]=e—´yâÔt;¥¼çH@ú*)¬i§å;eå]Ÿ2sËÁ*s’Îÿ¡Ât&rýPf›6ñ¯Îe¾E2‰Ñƒk º¹*Ÿý¹/ɱšúGÞä8'×ì8NÉ™ª61ƒ¦œó”VÒŸ:~L¦Œ0ý‡³c¡ûÿO âTž’…÷Ž üך#ˆ‚n:á ¿mÕæÔÜfþÛÞØê$ =ÞïN¨É„~ŽùèjMœp¹-ôQ}Ô€¿ÒPñÿAžÿæ©×[c»–ÔwÆäŸ…+ÒªñpÔª7™¥Y©¿·ºˆ}ÃßÂk‡nzÎ#É +o§Xž™2"'ܵ œÕô ‘Ãm½Ï¡+­n†BW@f±#”YZ\AìT8úoÂBø”µV¤$^»n`u‰ @7þi]AØ×\Ò6¯’à¸å"E¾ËîÍg1cŒÍ('@àî©ÏÒÁ ¥Çžr™ÝħÒÚ¨Ù”ˆÞ©bjw5E¾ªÝNµæÎކh#2}íQŽšˆrgn‚–Èüö&eÞ=mé&1 t( CZ\3Ã|*$>Èlb:ÞÔBŒ7þÜé”GÎÈL‡´÷O‡N7‘/eÒÁï£bŽÒIk4ú8M_A²W/¯ÿ:ÓÿHÂqiendstream endobj 379 0 obj 2609 endobj 382 0 obj <> stream xœ­ZMoÜȽ ù‚.^ž^vó[‹lDÈqVŽ2‹`!ïšáh¸æ#~XÖ%¿=ÕÝÕ]Å!e9Hàƒ²»ºêÕ«WE=œBžúþ¿9œ=œ=œK³æþÛÎß­Ï~¼‘!¬ˆ<Èåùzwf_çypž†¡ÈÕùúpöC½^ÿqÊDdy¿¯·g?¼»ºùÛÕ‡«ßô/I,‚T¥øË‡ë¿^›çc‘ÇIˆ«±ˆõâ7áäÀU˜åB»«(™yòöØUÍ ŽÈ(Æ.öe]·óõÓèÊcY˜WâTÈH:#ÝRŠXŸ|Çî¿ÿnœze¥%¢<:_ÉX¤ÊÞ²½7¶(X¡[û²1«¡ÈÂ$ÂÕòk¹‡²7§*æÞWð|_šÀ·*v/TM?tãf¨ÚƼg"Žüª¯•†™Âµc]l6jwøh˜f’Î4‹©È¢Ô½ßvÕ}Õµ \&BéM´§eú0ï×/Æ(± r·]J£;÷$§·ÎáB‰?Û¥˜$Ó›¶Yy[ãH¨d)¥3 Rš*Jžúl›jA©NÁ‰:ÒA69‚@¹2+±¹9é4º*÷Ñ]ÊN{ËÝr9ኡ´õA•ùM=nKÄ`”y ^ÿºþøëÚ˜%`D<™åLýçúúã墴R@“‘R†ôý ¨¼¯¿[C]6ãMOHÒ\žúo%µÊCîx›=r—¢k_Ø£„ùy(î zSþÄ¿íŽÀ9a*YÒÞ¶G,8,Áp·mÛO&`§Û§›®ìÇzáZ·ö5‰NŽ©ø° ÇrùÂV&®TŽ3f µh‹qå­}Ø-2ÿ”( ªÂ»W'o33á4(zÉ—.„ÉŒ¬vs#õnæÀ¸ö]û¸ —ObhïQ4¹Íî!˜‡ln¥û¬¨>Ý•í8G¾Tcˆ×µçݲ’sƒ ¢ ˆRv$Æãù0,‚ì#¤­²Xk9Éý°äôòpžŽ ¶ÎvÔ,¦Ám?´G¦„Ž ¸î`ºÒ;Eй|êÙ‡±E›Z»«:»Ï4ËÜbÌ’ÙÜ㳆 ȸX}ïZ†Œª-Õð‚ÒèQøE„š­¥õ„ 7P sÍÙY—ZïͶxטJ òrÄ‚åp£>c}ÕA›à ±¾ûJ±sîZbÜrÚù±ªk,ÃLwNfº8{±‹j&§¸z¯J³€§Ü]ѻֆuT· ÍÈRÃdÿ—†Ç¾™¨eAÏǤ‹¬7‘N²IiÖÔC/â—œj_Mo0üuÁ½k ¹¬‡êKè¶hZÆZ¹oˆyãê7„¾ã –òŸõª\÷Fd.‘GÆ],•â·®ƒÍèrº™¨š{Ûg@Á½mïF×G¬õß¡+“æZú ;:Ù*uŠpƶœ2™Lt!ëÄ÷ÐÍ`â„•²é]×#xú‰8jŸ£ñ—ë_®ðÎQ>÷[ž ä0 ©Y-|6yåìy4äó;Ëî|’:«0:“r*ü}·ÃrnšBßê½­ÙŠ-uå ‡y[””‰y´=Ég£¶Iç±)êºì,Gè MN7­ï‰ð†òë`‡8TP×ónˆ£x 49°Ú–j°(XaÚ´‡°·íz"®|÷VY&è»´8VŒª›â`'VzhK E7 ‘N1Ôc5ìI²¢bwŽEo}yÈ…,X~ÆÊ%!Q qFÈf.:š°y¾L'G±ý‚%¡¡VÑl, ôtˆ„Ï*ÀØ9íÀ¦+Hb†3]0ôù'Üƃ kˆ6„—ÅZ°ÍÆ_¬þÝ—n¨’&'ÕyªR†®ïjk¬n̽±w6î§À(ÒS„±Hq­X8öKržl>ˆõ¸ö„€Üó½ß¼+!hñ$ÑËîP5Ðd[¹¥sÄÆBÏüÌår ×ű¨j¼œf©ˆÜÂp`:KA'øªöÒøa^ø{7ã™Ìµ½ègÃÖǤúÓLê)g¾¹™¶rºøPõG'©H½BÞtV±¤¼föûv¬·2–9P Tâ2×ú¯$ —“œdÕ˜r’iÊ_® ùC“ÂÆFöVAz€l*ûýBO‡Y:¶Ý¡x E³”µ38åÕ±²%S÷Ùl8<ኪZç8Õ%‹ŽU¤Lß½<‡ Õ”¬‘ØWçŠÉGšg5ÒÞØ£´{C¥yBîeèìDÜ`Ý- ŸÀ\7lg%zaVˆ(™JÉçêiª[u7çMtp‰WçeèÉÖb.Þýt Á”)ƒ\óô¡ƒ|Ò–[ j¾c]Þ{G¿ï°ÚÆzê4TQ<ùµã9”Bv]{X ñ¥-8:Ò`š( ‘qØlkìÑ%/=£s)«c?:|Àî 5?HÖ’wá?—]ùÊA>ˆY›ácênÜïT~-Ǻ\Oƹ°üžñdÝ‚h:ŸK]“ñ$Hy]¹ü‰QZÙ’?Ž&C)6☜óÉ“ïÉÄÒ`§’úx™s¥þØvn¸Ëç(˜À“)«'+ÙɸSêâÉÆ ëm€à·„ÌôÏ›5v¯‹ 礗^Póûrï1§ò‘Žqê§×Ÿ^›ý2Ý MGí/Îs0ÐïIß°¯>Pˆ¶È8ìûÂòwÞ9¶¨3yò´ ¼DÿaCª8²±¤O‚5t6ÛùàV½Ç‹û¢Ã˜M§gô× Wëóœéÿó¼$áendstream endobj 383 0 obj 2640 endobj 386 0 obj <> stream xœíXMoÛF½ëW¾Äì w—»Üõ%p· jÇ®£ da$Úb#“2IE ßÙï¥È¤FÑcáƒÕ~̼yóf†Óái¢þìÿÅÃäqò8ÅzÍý[E„³Ôž?¹Ï›Íú«úáØýr O'æTQ-Íý}‡Ôû8"zÛùå«Óó‹ÓßÎÔæŒ¡,ÅÂ>Po»Í¶Ó–§ J‚—ݪÐn $’ŒÚÅuÙj#1IPƨ~ÃÚ2_×úFÉ.‹|=Îà)ëÁ˜ÊJ™dvK€ÄhêðÍ7vyÿ"‘L=ŒOxá!ÿ¬Í‡€o™†@ –ÈÄ6Lሧ°U±^×··A³ð˜Ì œ½<:M‘·u5ôê®Ö´S‡ƒ-! 4ܰmÝbšúÅúÎBfÛµÓ««smÄ3ã—v#S˜¥Rs`bÔ³»3‘%H†µ\-1”ò‹Y¡v–”šŸnÌ[åöUnûRV÷Ú<ÀArºÿ®À~ç²X”Kí4UöxÌv«2éŠ"‹eÏøªîl°“`×(Àm±¨M’AÒJà<Ñùg‚ZV;Ú”¥Ä³Íš"ÌvÙG’Ì;ØÛ²)Z+2ðlËյßÇmÝå]iÃĹÏ⇼ÑìÖ§™¿ý“Zâ(ååPË1C,äGÙ¡!7‡o*»Ú£¡a†cO¤EnˆHRD±7 ì,ô$±Ó£êíZ#LâÔ_ùMŸeHˆ#zš!Ò—Æ'¤ü/§×&)h†¤`½¤(F‚{Cžpù¯gçç—–$p㛥F”qŸ ‡ˆ’ß2FòÛc”B† ~°ñ>Ö:Pé˜b¤DK»¦6Y ™—%YÀ`W‘õ¶°l’rÄì`Ž¡-( xè$‘Gò¬*ºynV ‹TøM÷¬uD§þ¹ú®+ªaR, Î@AlÚ÷!¹¢*íñT©€¤Îé³Â@Qò!(¸D@œÇH(Ô|!ÙV ÏÙåõÅ›51àpÛ5Û…¶<…œH<½FéXÚíN’ê…ád}Ü|þcXœóË÷³cœ4IS§/Wïgæ=hæ± •Ã÷Ò ¿ÈdM†§*¯UQœé?þ +—ËâÎ+æ`–‹ˆjØöèBBݘ//NmFˆÐn½º¶ÅŽeÞ K’üCT}ª?dO’4öH{³“5®èÖ¡‹ÓW×—WC©uåàØ-‡°è#/¿d ™ $÷Ú†hH¦j>ô\š€öþÌA0-’T#Íqk“¸¤Ú‰ZR+–ìÿq‹åœRJÚ;;‚XR/3#½“ÃxÐTmõ½b/f.˜»¶øk“»R´Wù•Ö«ûá<ûãêôíkkàK.rõ'š3n ³øÔä. *<öb¼iêE±Ü6…éþ†•UBb5íìÌ„äaæo-XÑЙ·¡[ƒø%ÿïÄol%ó®.áž×EÛºŽJEÌ÷™Ý*wÅ1š‘M J·¼BMâŸm¹ÍSG=ý-lÛÏ‚O7Á  e1W,Xч”ºrB$DÔåŽ9Í"¾Ã¾‡VÓ¾”„ŽiWv+“ôjøÀ"Jz—0±ó±äˆfp›½Øºé; #ŸFÁP ÆEp×wy¶âHð ¦÷YMòÁg5Hšá—‡žµž 0ò„™~ j”ð0QÁ‹ á[ÐnU.l“’†°²>s.Çl¥6PØb¡–̤00£¦ç8O“Wí:ï Ûx³±Iƒ¥U¯Ã ` QÅáªY%ÿÖø¯g +ãç“×ϟ©âzã(Ö®ê•Á蓎Æ>TˆXîç½€TGÚu°)m†EŠB•ÑLÚï­"¦Q"¬û˜ŽÝƒ¡ƒa:ÿ‘9Úž³Ùô÷‰úû¨Æ”endstream endobj 387 0 obj 1912 endobj 390 0 obj <> stream xœ5‹= Ã0 Dwý é¢J1þÐ0 Z2§t(xðÿ_'.7¼wW‘I[zï*T”“ýk/8ÜWq!e´\AeŒÎ‘Žh†nö'’¦ÃÛ†)¯Ï<ç­™à‰ã»™—Çrî=©®SO¾Álø‚–$?"´endstream endobj 391 0 obj 125 endobj 394 0 obj <> stream xœµ[KsÛF¾+ùª\âT‰€¼6'G«­¤*{¦|°\µ IØ€‘óï·g¦gº‡Ò”³)ì‚Áyôãë¯øý2Ž’ËXýÁ¿WÛ‹ß/~¿Lô3û×j{ùýòâÛÛDÀ“¨Š«ärùpa~\Vñe!DT¥—ËíÅ«ë§z75Ã7Ëÿ^È4’±Èá¥åúâUÿC=LÊ(/ o†¡×ï¦U$d&ññÛ¡×wWÍ8¶Ý£ú‘¤QYÚ·ËB=ûö6•—ð‹4eàx ™ÆQ— YE%·Š“êðYe")ýˆ$J«,ŸàP‹ªˆJ™ËË…H£Xê×|Ðw€CTe‚KÔ~–E1=kœ ò¨ˆ ô²¨Ü°Úã,Nd†Ïê{\ ¹]`ªӛɨÊ›Q?K£J”©}ñ©!ÍØ‡ýfc”PÁ2»Õ3 ¶Ji«qjvc„+„;Ø¿Úaœ®PèYáž·Z4•:D"èƒ>GZ€XZs`u_wàk#®8­ì“?Ì“„ °n7õýFï"d”“qÒ»‰Ûdhí» QÍùå"Qªÿ·«·ÍÚX‚ˆ¹%X…Ns{ûÚRáÄu½ Ùܧ¤;j©åQVVq>Ws‘œ©f¶b;(¶4v/²‹Û{oöF ðã"·ïÕæ·"’§ÕÐvã4ìWSÛw›vœô%ª(g uZl)(”ŒmØwzýTF"ÉEÈ.Å|cq¹Ërû/Íoî.ÊLk,6ÞßïÐ’ÊÌ]¡jµ’V8Oé §$¢$u{¿1Ï+…Ûp[£ôr¨?uËœ,ïÞ¨“?Ò-ᔤáýhŒ äP‘žÛé©5g&΋‚~Ëå£u Ž;åÞ½ê»Us÷ .–KNý\ÁÍÇzÛv by.t‚;s+S‡«¾[· £”8Ò´bn¤Ž©µ˜– e¬M#t&‘$˲{Â}ÒÐm­¹q$ªœÌÅH¹•¾Í+ÁÛ0Ðÿ†X]t{kò9ÙË[R£ý©öï"*Øj¿þrcA/™›3ù b]ê°…PS?ZÉg©“¼ƒÃœÔ´Ì-aå$#\0¦äoÇÌо×<ôˆ»yT‘ ‚§ÝÕ`¡¨J «xþ‡Æ“¿7è¦'Eæž^7ÃT£M—@Üý´<ôE ‚wæY›3Úú˜ ‚'kø*«~šU¦[†,ÑÿpO0UA~sÆžßÍ¡üÁ(=(JÐÖw ï­+Ts…Þ¨Ž’ÊŒì®Ð·™»Úp«prRžr'@ï¤r‚ê÷º2œ¨ˆ¹+ïö&¾d2fP÷ãA8rŒÃ@lÊ™ ÖšN.ò³"VLïO1c†¯‚%ôÅ\ȧ6õ*àN¢˜“b€†wƒ¢‹&¶d Éœi…ﵪíé„ &3”÷,]«:š»ÉBç!+Qñ‰~ýVšÇÈRîéT=þy6¨¢‰0@"6œæ$Ÿá6¢{˜Ü!fÿÏ áÝïúÍÏËþõÙJÞÍ"û|û0¯ÿ2® VÎ9Ú° ~xÛF b£÷sAn͙䖑"‹ÎN%‰ ª›ÓI†~‹ bVý7èvpK*œu ªýŒÓ²°„K̼ÇÀK¼ÇpÅ#ð)c 6©_ò4¡IâÁÐ?§•= ŽÍqÕ‡1RdÂ)ck³ {©È /ÌÕ'é™c#é16&¹;çzpœEUÀSxšÓz Eõ¤’—ŠFÚÿe…6~žW¡´$O<»ƒ_¥À˜CâɨÄ.ül³\ó,—BʨüˆøÂ(y×4ëf­‘_Æ H§Ý×6¹ËŒ0øò ‚Ò~〄/ò–—åbd’áDŸ¡‹&ú6›’E”x®úýf„²2é³Ú[ò+b—1(÷þÃR‰”Ñô‰”ÄD4FRAȘ¦<~ƒJ‹ßFÐ4 )jÛ¬P‚À§ºkÇ­‘>ä‘ä[KsŽŠÔßö‘ÄU\ru„J^Pi׸/ËÒÊK¢Öëº{l†+$Ñy9ã{å•9::ýüê\¿YyT¿é÷X­ ×.hÅ:<·èÙ’Ÿ90¤ƒðvnÎ(fÁ"õ³Ñ½2žRpu˜¯­ÙÇæQœ}&Ÿ¨‡²©(@o"˜”$‡f„¥ÊNR“ r½ƒ6… BNÁ¸¦–‚À”e—‡É d›``ö '’'šAmŽ´µ¢¼Èýƒš Ì,‡óÒüà–ðOAE ã®ZÃe%y r2öÍ’‹XU˜S²pÑŠ|~ú ¾ÊˆãÐLûÁTXüÂF4m¸Ž´ô» "0 bëÍ& $ã¯3Ìw̆ ΆÒOÕDœ 1Š„xVð@¾[n›e“ò’6K|Xi± f,Ƨ?‡sý= È•Œô¥¬¶œ^eù,c©8åaÀ@ß²£Låí.'n×[Æ*=Ê8%[õÞiN O%æ^$`3#hâo k®+ÙÙèó”Åäa úŒ5&Ð}{ñ"³}ÕDfC§+ˆfEÉpaÝ#sæ•_›¨±Óõª¥!áúº¹jžRto¾@¡ú¥Ì`½;˜X…3ÔÇË*i7§ e]wöëõcÝš ë"Q=ª¬äiÆ?÷ƒí¨å°T ²ÌD<ì»ßêù —¨ŽeRâóê*‚M,®B{©"•ŸÕ‰ñ÷b4< غ#¹õfó':<«bí»¹ñʰý¾[Û¢1ƒÌц“J4M"Jsœ¹I:‚#SbÖô (ˆÕ_˜ùÅIHA¶ Áx/l¾›ÍÈzòÂUDBnùÜnlN‰8‘³Æt`ÇýU % sä13ŒV.ɪ²?vsüßÕÃÔ®ö›Ú°ï  ªÊSà…×gBÅ@N<$ç9Éšœ@•¼Ñìâ¼¢}ñz –G9yxŒRR H¨…}öZ˜ÞÓ¢^¸­“XF™tAªÛ™Ô úí¤ïtçu†¦ÇöÑØ‰TfVÒ©¢œ®êÕb®mÊÒ~Ûïý[“"H¶n8X°†SàìÌILJ:INNÂ4ïqç Ð ˆÐLJjþ¿·œŠùÁ¸_Y#$–ð„JNÊʇŸ!ð–3fdLyä…Lφ£Q#ë¨çÆßáÑXÀh'£e• áD0N14[ÛdòÂÛ‹ªýÐ>¶]­—ÀJ+‡U;æK,Òœ@½©²ƒ½)o¾F!¼þŽ+²’bgÙ ƒöS£Nñ4 1›`PFÃá/±nÖ9M'Ù´›k`™.0ºõÆ„Q…›ÏÕACÄ."ýŠ·N–V`sžwã›N_4ÏD|€æž€$P¶3&šÜh<³4Ï3³å·oÞ!0hÿ äoÆ… ï¥ä.ÑüVwæ’œ»#™ÌQ ©xjMŸ¥ä5㕹¾‚-V˜ßVâSRbƒ‹ÄÓóÐÐSÁ}ǯ1©b¡ðºÙ´÷xtÁ›ž°§á]àä¬S~Lõ€:Ì2Z´VêNšÃclTĬȌÿ–ûU2ÃØ…uÿœ»k)ÌÆ¹ž;•ÓÓgËìäAyÄog`m@àO¨I“9:Ïm˜,¹(bIÈÈ+Uêsë\¿^^ÿ€FÎ(ò #/y¨k-“É!õ›æÌÊKqhå¢,Õ¼"Á4gêN˜,·1áJ]žU BéëÞfBQowÓrçu”¦U¡á—ÇãúÉž‡æãá ) &Yz?Õ9ãnZÂ5QX\8~xVã«çöÅÉ/3~×£Ü]áÕY"ÿüÔ®ÀH2Š'‡ 1V‹OÖ­9“¼Šý‘ V^MAµ²H¾6»ê'ãL—œ@©úNcmª_âÔÜÛZÛa¶ ô’;éy‘¨à1.Ù<Î,Õ šƒVšÌ’` R£w"”®ÑÄ%Ü ¨î¶[!²ùX¦zïþòÐ&oúð~^þaܖטy‡š€¬Ä*E¾}Ûß?!Zy“F®•ÆHMñïó‹(X›ÍRÅ|ªååá”è{HT[nc‘àHùʼnÍ+4«E‡#ά î†fÕ¬›ne¼~Qjâ•ÏS€˜ó´@¯ënèG*5tT'4ÐÚ*›_5í§(çïì8Ý“l†;Ã=LÆç Ÿ/=¿èå¾ >\õ„™]=@Ü6“±ïLMEøŸê½BI±ŒG‚‡î€¨]J#ºŒ]¬_¸1¡zKNÛzz¢Wead5‘Â5Œ©A`Ùäþs¡øsF‡¾{µiC Q,j,ã @úö}®÷îæç}s5\}€+þ„ø_è’¬­ó¢¸é&oz ¶Ž%¼àeÍ#¦ØºmëòÓ±5¹žb…tÜI lWzÐx¼ ª&]òÉŠçÊI˜’þ„*m!Vë¾»¯mË­ ´TÕ„  â\Es”_AÇ 'øÈ/0\:çÐ<48ë}õկΈwòk~c£Ò*4VŽ9â:X‡VÃC´Ù=V™^Ÿì\‡Èyñ/4•¡Uj@ÂùO@»9‰Äo4$P »¶Íˆ…¨’Ã~_°ÁrÒ˜ 8«)eEÔYä—&0ýÞEB©ìů—ìkF¿Cµš§v‰²Â[å3þP0þðÞ¦—žÒKÜY÷™ÄÉó3w¶ß@äŠe¸o?¸kØF¬$PÄG7bÐúþú5ª…ˆÀ7ÉLTÀ¿ô.¤?ø‚8Íí t­óëÁöS+Æ‚?qQ6hÚÚN‚š• 0¶ôÅÄ‘H»%‘yªilª^‚@£ìQ¿¦r'ô̼’ÖçÜçn1ä%ÖnmtOdi_ÅŽò¬»^ª‰IU|U“ÇúÍlµÒûj'öÁ‘ļÑíõ(;G¬Iì·Í`‚½_ÇÙ}/ËÆsÂ’ß'4i€(ø¯6uh,ÒFG9ÃVÿ×_£Æœ·¨·¸{.Cß^¸n×0GàžU„NŽ˜Ûy"Å#ik6ð*Ã%·ûŸDTVÆæ,ôÁŸ=i \Ä^ÕÝNO{=“OõXéÌUWXyàXuä _e.æF¦Ò‘ùw6¬{¢‡Æå›ÄUÁѵÀc’†cóñJ–ð9‰_zœš«¸àí´w)°v¬äÄ'bƒøà©Æû±—ˆ{%Næw<Ã<¬"Bf*Šp„\·_€ûvñ‹ÅrTÊÌõ”ûy“«ëÆ:óý†$ñrX°°,[ùRÃGL]–À³Ü’zP¬K´‚O™!£Ÿñ¡P]kIåwB ý• l*c÷÷ãÔNû ?A-AÅÜùNL{ƒTÂg°uìsDÿ£Å£³F†óy]/UžFÇõ5vlÐÀ+K¾pÀ2%h<1§kÒˆtlVÅ•ó9°ëÙ% V˜$Ç9ߪýr…e}¹ðØ`óq²è°.ªÅ]w*ó„»â‚¤”רXê•ÉË)OVœØ¤ %oã µ«#§ü+°ÐnN§Ìwdß!V2áÁ"càípó58LuÞg°ÇB@„A™ €ßÐ÷‚ªmçnÏq2ø=‰Hç Ë“¶Ëu,‚ªÄ›G÷uð3•Ðg9ḛøe¶gÖíÝn›uëš[™â'œÞ,/ÿ}¡þüwÑ~ƒendstream endobj 395 0 obj 4285 endobj 398 0 obj <> stream xœåYMoÛF½ ùB/q€Šá~»{t91êD®L·àh‰ŽØH”CQq] ÿ½ÃÝÙ†´'A¢ðÁÀj5;;óæ½™ÕÇq‘qÜþáÿÅfôqôqLôšý·ØŒ_d£çsÂ`%R±"ãìzd¾@Æ* Æ"EÇÙft å³ì÷#i$•„ϳåèàÅtþÓôtú®ý$M¢XPŸœÎ^Íôþ$RIÊp5‰’vqÂ$‰d,Æ“”FRêâö)©âwk³‰UlÌ›|Ý®R)âÌ–•ù²»vgSÔ•ÙËHÄOp½¨ëm­M¤‘ˆŽË—‹¼zÚô÷_'xªb{·ÂœFƒ¥E¾¿ÒVEÄib¿Ü\>Ó÷%BD)!ã aÕŸþug{}<¥‡@ââöº]#°–H»¶)6ÛúNæ,’ çaÚ7|Þä m°@R{ãí’Š’`ã¶]‚4REpå“Ya°I¹^Ö[4G™3w«ýIUĸÒîÄ&¯¬ïOfBª¸;f_7ë“B|R¶&"DET>‘$m÷Õr§}’àg"Ãàó¾Ogsm.¯œÕÙ^3&ÒzºÔW'_z±CäP»tޯ˸—¥‚u±“Ré—í’h«Ï-š%„=»x£P‘ä.¹¾!Ü‹çMYÝ dèÍåAµ5Ë,J”+ºX˜ɶ øCiϯÖâ™2pN¥až“oˆi¹´¥Ga¯+=H?^X$õëÍoM½ÝûÏšPaþÓ¾¯o18$J‚dU[,k¸oÀ :Ä:ô¬u⫃d NÇÄÿ˜ƒ€L(þäK1HD$d‡kä—p ’œàW* …fƒŠp”æPÉ„¹+­Ìe´²Ú•KLƒR:l\\>{jIÅ­ø…yWHi"vǽëGz»G(PÔåÖ¦XB¨\Pw¹ñŒŠxg–B’¼]å ªñœ0c„WçìÛ²1šÇ#á¿ý(ÔLÀQÊ:LBt+@8(¦;ê)’Òa­«×-óq€(èHÕ%}Ó¿ôr8G«B¸òZ!¢U(Ε ÔægŠI¼¹|½/ŒuÚwå¢*þ¸Á„¦.™Å¢)–˜ã`ÙÆd"x{\'„¬oüÄ$!Ü'ƒçÞ+ c}‹”‘xˆ®,å_v[ê{ˆÇ±b—Õ¾–ˆh©, ãÍû!9r-tFþþO ~¨îQíýy³@¡°Û­H* “&ûR½kÓsBHSO’Ùë9Þ úf»sfˆ'ÀϯÚ b…%‚û¿Âz’Ðñ’þÍï? \z4—;Ìgì¿›¯ë"_j6apg–k—Å“Êu¢ @ AüÓ¾çÍöæ¦l´ÁÛÙà3j}#‡Þ~JïN]^]­ËJ§c’åÃ%Bdߨq‰}(Ý-»»]ShE`ПŠþ,1Ôõ½h\ xºÛí7èÐ$nZºëÃyˆì7E^Yõ„{r<==Ÿþ¨­&@O.ž¹ÇñɱwÌW™-[á+9¯+ô•qH¿ïʪõkAa’N†èyÃîV¹Únu•~ëh‹tàÑ=âʉ: Cª§Gwë-Š:ˆ¢ÑÂ̈ÐKÄ>Ffž=N}%ÜÔ–Iê*xQ,÷u1b`um‹I¸D}u˜S 'ŠбlU[¢„œtƲçsÖðI 5{³Ì–î@·Aš: C‚šjS> dßÄ/ýnì¦.7eS~BÎ ÞŒ²’XD’tÆà¼‡î÷» VziÏf}1º¯µtøA´€Ÿ†ÐÝuú öw3‰‚\3ÖÛ€˜gs$ŽÄKóÅôùɱ&;Þ V¶â,õ*m_C\´ —ÅçSO¢Ùô<3Î$Ä͘´I{d ÷Û}PºGÚª|ª‡#ì¿þ¹ò²•âÎÄBÄóh»_ÛI”ˆú*-+¨Þ|]þ©ÑÏá¶Â9ñ¾ÎoVåb‡… $˜vÒ7ùÂÔŒß w7®‹f_cÒž¡Üù tz1EÒ¥"xH¡Ï—î{‰¡G§²_—»‘ âÑE.PƇ†¼`¦Ë>‰ÿ…!/8;ò‚ʽ? Ðz™ˆ4H!P«#ìdX^ó;‚GãA~>Ïfgˆh@íVì²õ¥¬c³‹ììB—00”‡ÄùnlNE’vŸ=Dñðìì³]1Ðö\uÓð=Ÿr^¾Ì^Ÿ¼Õ3BÊ#îKóÁ—À1ƒ…• ëôíK÷ÓÍ}ñxYY7åõÙ7ñpn ²Þ/šr[0ö-ÏFz@:ç4`wˆ çþA9èˆ]m·uä:mûÄSHœ¯8þ™€¯QÿL0ÍÆ?Ú¿¿Õ¹â'endstream endobj 399 0 obj 1792 endobj 402 0 obj <> stream xœ•Y]sÛ¶}÷ÍÐÛMg"” ~Ü7'Q;žqãÔ–o§“ô–h‹·©TÜÌôÇß±À.%ØN'™A»{öìÙÕ—Y$ä,2ÿðÿÕîìËÙ—™×Ü«ÝìíòìÇk™ÀŠ(¢BΖ÷gö9+¢Y–$¢ˆgËÝÙëw›r?TÝËÿ©X¨(IaÓr}öZÊÿ˜E™‹4Ï\¼Ùk±ÐY.q­ZÕåÖ,ÇJ¤©V¸ü_³” ™Ãý¸Tvuy·­zó—Djûsó¬ýx«™ÌD,áxñ\őȊt6W…ÈñUãM…ˆd1yS‹(=}“C3ñ7ÉDDY"o:öؼH„Lt1›Ã…©÷_¶íx_*ò$uÆåŸãÑJ©7Ê ×IrVof…˜åÞåj¨ÛfôU,r©4®×÷x;¶÷I ÏÍc\ûf– ¡!.¦íýiø†M…q.âÌ}{ßn·£™²™ÒîêǺy@ã:;¿š%-¤*Žœ:¾]‹œ@Õ”; "´ò¦VÕýЋñJä*q[nªÑŒ8°ø Ÿzú O‹©ms%S!#=››Ø[ 5m·³^O2¡ ïÝ~ÕîÑʤàùÐ%o},}‹‘¤w}i]ŸEÜf—öÝI½›WÕúÐUhv‘ù3W6ž€þ4òp²&ç"Kr™úÛí7ŒH{öÕ0^–ñïÛ¦:=nÑþõàµ:=)¼Ó‡wæ…ß¹­wõ€×kB®ƒ”ñŸ·Õ8ï/;•µ©8éäIõÐc Á«`½ dløWµ,rRøÂ»ð¢©‡ÚyþNs¡xcï¼Fg »óIXOQX$Î8€-Ä ×«j?`Ä„™û¶³|“D†žÄëüòò ásGþæø#÷Ïúy±¼Y,C¦àV‚ö›ÐpeJ~xw~³¸øùÃÕõâýÇÐya²Kòížâ›uè\"2·Ûoo¯1Ë$Aç÷«‹÷Act,’Ô§ãx·q6¥Øã¦^“B5o(SGGy1¹{9¾ªp£ƒÀíq<¡Ú5^¸ï]]­…}v&g½Æ)Æô8JDZ(("P›=ù ŠVLÅõñ¡0sÁÛ!½$€mnÒ<÷èø"v´³ïóë¯ÕÏ?ëZœHð%D#…â΋ E öˆ¥ÀD(zxݬëU9`b¤àkŸkæ\i#.Ár• Å8sªM(Úïà6¥Í‡Þq™¤¢Ubj$‘GèK¬«Mdôé[ éߺn]YÑT±ûæßvk·ùD,!6Þ´‡íÚCb; aÅÒËÕH§Ë–°¾hp-§˜•Ns¤l­Á8&$êÝ~[¯,y«Hĉ§2!êAI–ø×ZÊ‚“5ÒÓÞÖýÞ—‹]JnøÌ«¿‹|HéPm‰”?úU‡~EFµeØtU……,"RÞŽ·9’’ØxN×¹ƒŠ±Š´0²„éŠ ·@’ÚL.—’é˜Ý”QTËÓŠø–·b}ªðrzR6T%%¦³Ì¾Sù=րآÅd²G ]BLæº<¢ìôÁd%¶ÜRö`ËLõ{cùÙ:+zúª~W­÷!²„pçœ*‹Z¬¹F|™,SmJ\€-'*þy¶d4uÌ–‰ ±%dÁ±ðVõMÏ£-½š Q¹üdo2žÂ0Íå*XÌSè°ßS “ã3O³3söF–TJÄ”ÃòSúEò+@Ç‘ÂmÓ×ë "=¦€‚þ†¶9Xi˜šô#º¼³ “‘wÍÐâ×ÛóË “y”ÅÛÅOXóYž>"õ1¹_L\þ²øåíâzÜ«á/ñ±†á{«a%œ2 †‡5,Ž5—¸@â H;¬ ×òÓ~t¢õëž4S £ó©úã<‡{ RVž-쬄­Œ4GùdÁ ¤Š\[e?q3®²¼©1ÇD<ŸlLÿo×FXzìË [Í›©±„*jj0*¼yûä0ªÅ`¯2ͽú…«˜ŒÁ«8*?!ZìÁ4k” Oœ’ îa.… ©cÎ¥Uו« ä° †kœeÏU€IjêšS9r*eÚn݇ä|ù!!T‘ªöª¥«@rY’q}rèÝL3ãÓë»r…F4¥þ³ß–ýCË:”ñ±AÆÑô(aÀ¨ºÁ$)–9M³Œ»²Cí¥(E?»$™ØQ7«ía]!Ì5i‰ñ¹£ØûaSBJÌQ ™~?ãéëÔš™°“Òg>.Šç"„š"ɾn!ÀÝcmõ¡¬Ñ i4‘)¨§XÚæ“ïÿ'¡cƒìuÍpÜ»}_vZ7Ýà²åÍêA‰Ø¸%¼!rMÞd^ç2ÑŒ‹h^‡/Ÿöƒ¦ÂRÆš/ê¥ØÖ ã ­bš'…a .C­ú xL8–=Í~ã%/QÔ ?6oN«KßžÞï‘5"æÔdfÝKŽd[»ª?lí€u2€Xy€fð¯^4=LíwÕ ç'™_¬OÛ ÞÅ„µúÀ\òìpj}X¹2¡y^>ùC†oäÁ V`d¥\ w±iÈ…Ä”DÓšÏdÞ¼º?ÝÿôèpÁ ›çÿ”'SP‹¸Qà‚ßP]±áw0g±ÅŒM=z"töqHÕµÖŠÿºfGgS?ŽCŽR£X™Ö"K,¾±i Xú>çøˆd~هʼ•UnÏ߇ ;pá±â0|MIðùõgs­y#‚ÆGü· úêé+¡>l°«hBòCP) ×l‹ T”p•´mËuÓÖ}mÕñK}ÎåÕùûW7—¿Û<„ªANùžYQP0™™¢~6_œ`Ê_,)½ÓÄÉq‡2•ôk+TCúµÕÏYLž™ØÚ@¾®«W¯È’h÷Ñ%x Ü¿×Àý¤ ¥Ž¹ïÚÝ©$ÆÂœ±,zµuõVò”¶bÖ’‡&„™äSå³ÛcñÕDÐmWvî§æŒ|E7+jvå:0%}²:$ŠZæÇ-uÎe4"ý;¦ð"®]Ã-E*‘rŽ|±œýzfþýIù Ìendstream endobj 403 0 obj 2598 endobj 406 0 obj <> stream xœÍXMsÛ6½kò#ttf,„ø"‰£R1­§ŽíJt;™¸Z¢v$Ê!©$þ÷]|CeÉ::hÀÛ÷Þ.øu!<ŒäÏüÏ׃¯ƒ¯C¬Æìß|=|ŸÞM1…$"‡ùÃ@¿€‡"&”"A†ùzp&¢·ù?Šc”Šžç‹ÁÙûlú{v™}’ObŽ¢„$æÉåõ¯×j>G‚ÇÔŒrÄåà»i‚‡˜¢V” ŽN`™d8b¥jæcSÕr*‰Q„SbÞïåc÷eU­«NÇ¡;'(Iq"†#x‹è87Ó‹«|’Ýä¿]^|¼ÈUHŽQJcòîì[ÑTÅýª¼{«c8ŠaúNNÔ+Õƒœs0,gÂrH BDdÁ©7u].‹®ú&ŸÉE9W?+åPŠÒXD1}Þ%4Å6DW.Ëæ\á!NwsÕ¼èÊV>b°?â_ù¢bãTjq[?ªµN)gfx«Æ°@w+„ÍTÌÜÔ>3AÜŸ¹ÝÞ¯ªVe‚2”2‡iÛ5Ûy·mÔN&Ü^¡^ TæÀòâ{µZ©Ñ(½W´B,»¸ä— )íòƒyÌ~ Fœ:0TXŽ&ìAžtò(‘EXñF!ÏÀã/»9R{H"¦-feiv@übŸU ¿u¤öæòX,KMGD…;3*CL¸” ^Í`B¥L‘=}Q4ú¼ȆÞ‹d4"(Ž8È๎þº˜ü™¤i! ÄxŠy(¤T^#$ÌN¼ƒÝö‰ž*$˜JìõÍÌ,Š—[Àq»ÿ²1R‹„“š‘_]—*Ð fIf|žæ·ž¥äu,%ìXƒÖ¶ÕÒ¦’çíiÝœ›¥ˆù~D—Yk\ÐÕ¶4Ý ñ󜷄îYäͪ´Žé ÌjS, !™ÔéÜçcav/¯M®„âxrnvHc·JÐ…n}òùÚý:ÑlkãæÄ£¢5Ráôy‘á²Tb˜î«Mm‘QÈ*Ä{¼â¡Óµ‘H \ñõ…:ð}‰cU/µæ æ3™ïcš3øÁ]$vgO´V$S©ó¬~­Äôd?—½BÊC­l-0‚;g½ß6O¦iIhP7y9“vèêöêýíôÓõU61]O0q²¸ "éúÄ\^®A›0/¶­vpJà ÍÁÖc—à­Ø“y^.ÌU${÷–L“ñ-´Ëýù!h킜:»g¾ÞôëÌðŸzÏqu)x7¨K–Lå~Ë»µx„­"ì»\œ›E‘¿nÙe™ív^éÎ]I“2˜ø­íK^ÙŽµÆÜhÐp/‘µÖµê ƒZü cw±b¿]Þ ¨ïÃgcƒDÀÍ?3dx1Ç™ÕJÓÞOãÀJœ/(|—CP*_ì¡k§g‰ ‹.ÿAR¬´4ó;/j…Á¤$Èø“õ;ÿeGNXJ­é—xìȱÖàI„mØ­+nÄ_ÏiçˆB„ê¯3®yw.ö=P€å³(ãÂ@Dj ºÉ­Ñt>²œ¸£0ÝžÅt>I ¿T`GÇãS?àtOÛÕ¿¸ak,‰I[Íâ\^mèþâÿ‡rC©t’ëøp±Õ ¤ºXkêlÒ˜¶ôY6¾Ì³éÕ8ϮƳ™öèÅ…oœ€XÃûîòÓ’órE ”¼SQ‚»Ûåf¹1Y ¤ìIJ¬áЕûa½©GY½„žD}ãP…mF÷=˜Þî{ÇÝÙC³YÛõ4-ÌŸåcÙ¶iý1è‹ÝNÞXhgNƒoãË™žIœþ(ÙÕÄ}¢ô[³wç,þ1¿ó¼@"endstream endobj 407 0 obj 1705 endobj 410 0 obj <> stream xœµ[[sÛ6~÷æGx;“i;k±xožÒÄz¦[gw;ñ -ÑkŠTH*nº~ˆœRÕnwò B‚À¹|ç;}8qª?ø÷rsöáìù˜ÖÌ_ËÍù7·g_݈V‚",ÄùíÙ~AœáyEA!Ïo7g_¼Y—۱꿼ýå,–AF)cvÙáÑrR×\e‹› ’Ýt$0i±ÑÅØ¡îCÚlìËvhÊq’KœàÖæñßñN h1÷NP*y'9QDŠg@i%ä²Ïõ¸žÞ‡ëÌØ&)NG ƒ”¹)ÛÇ]ùXM+/±§&çɃ$LŒy•zL© ¯Žë¾ª´…YÆ“ÿhýlJm@®©ŒkðïÉ," *±Ž|Ls!)x]ÎõôqþjuPupº‚¼£ûZmämñ(‘édmäª}÷]¯P²þ8},ÿŠ­Ûr£o‘ÅÊ“I*Ò³Ñeßk5G1ÜÂzÊ… Ѓ°&1)ôîKTiH"„O Qý] &1dzÈóé·Ýr·©ÚñHЫç™ç}«T†NÒE3‘Y]mQ>E2W=Jc)—ØdŒ`_a/—E«KRkuU9ÔÕ0¢ÈâÜZõd](2™îã>„8:µçÄš\[oûXkć`*9–¾BÁ®0Œe?î¦8© gOõ¢©Pò1Eºq]ޏmD(°ª^´ZƒçRƒrÀÿˆ‚ŒöF€€ø•ƒ^¹ÿ‘ärÂTŒ½¨’BÚ}~WY Óö!eíZñ¿¹~÷óÛËoý¾&Àˆ#°9f_øüdá ¿ìg¯ÿýú‡Û¹åöíõÍO¯oÞz ¸˜T*&g¾]kƒÃ)¢ën׬ŒM1 ,Ÿôñe‰¹Çˆr3«5-M1æ³kð_ư8Œ=⿤jýóiDÂ¥í J_¨v4[RFºÖÄžçÆ‘–ƒÏÙ4Õsת¦Ñ "óÕ¦~BˆöÄ ü¬-“^g1‰Û¸"4Qº/†Bñ±x_C mòî"Ö7XÕƒ°Ø¢k† s´{öˆ3ó(„X­1tÈt–å` ˆaƱÐÔÿ±Ð™±ëX¨dÄrÜõ-úPLÜöæüöRŠTÄ©µªùy0¸r)@ãê^Ç—8¥#x"ưóù›=kL mÙmçôô“V1ÿYSÊ©i»~{××ËÑ-S¦”†¬JP”öÝN?™ò¤¤Ó:¥%£>­ôÏ}m¾$3wèÚüÔ{'N‰'ëh«¿{±8Šã IœXÿ™SÇ<Þqk/M·7|Ÿ)&Bgžñ~þ“<¬38xmø¨ƒ‚årÜ•M3)7—ö,5ó2±'ºBéÓlÁˆxAúlêû¾ì§}#•±Z÷¿Ð–2ª‰ˆ2Ù ° ÙõƒfÛ@òؾ¿Ô©е‚ÎðËN³°í”¼‹Ù”ã­ÚŠÍIûjÛ”K ­ O>†*@ê™`ª«•\î7m (ëÆ€K!l¢ùª_|Äå0µICµ0qi¡üdÚ.G!r`Å*¤3«†‰¥*!µF]­ÀçDÕ”tàM©uM‘ï¬5¹êtóÝÍ•®mí+S*t³‚ô x¾á­‚üž xí¯4*'Ä<¯ëÆ”Ø^z½G#¡ùøûï®ò^eÊÕ\¥1š3(ûæTÒ¹±-0XªuÌÀˆRÖ¡ð) Ž=nŒ´|‚ ¼ÇµœÀ¾Û1ÖnCÔº2í–ETãÅ*KƒXÅËý!Ó\bøcuª'éÓž£»Cö°¶OÇÜî‘r²Ê¶a _‡³]»ÂÂA ¼Ú‚’Ö/Š5õ0†v’ójPrMbS› cfÉ_“N¶ð'-we«Úù¥ÞàS,)†QYª†÷îaìMË:äÉs_Sˆ‘b ÌøÞ†GÃ;V,3æåÊŒ<Ð-!UÛ¤o]™LŒ1ïÃùH¬²Í?Ñ#u38¬ÀIÞpÌ9æ5‚íöãæ`Œ7’óôOM.Èý!8ÏÔ=¡ gDîá°9—2’mÙ%×¸Ø X`ÉFÖw4J¨ÐÂ<ɘÙ.1Ÿ8»p(C÷íu6ÿ‰¨RẨõ}ÊÁˆáîË‹)1b‡<ÖB7è¹ð5ÀU¿–›­–E ¬„È©›ä¼±ÇB?OI¼4)Šzb§§¤#°Ûü\uÕ€I·Ûgjê'øRò¼—Ã|‹Ò³V·˜´ÏZQ"šªâ¬eršY8Ý9Çÿ‡¶8É[Fµï@èIHt»Û Ÿòð¦¨9¦»+çPmpYÙf+ùiÝ«švÌSJv/6Ÿdû'!q:/MC¯¼@XåUñu½Dca#Nk4‹0µˆµ©×(oÆ|°Ñ*™±}fÆr¸}ÈÙ•¦B•ùßÇ·Ýcݶ¦§ˆ+µXŒÛx „ήTNK‚œêìd~é¼lá  aÖ亻óñh|qËSéP8µäÂKä9ÄîGêCå3d™‹}–Íwn«g%ƒW(È6 J¸3¼yX­¼ÎûÐéO)vl‰¢4pÜW‹AwXŽÎ÷­ëö‰”ÍŠ]¬/‰ýÜeÑÙÆÚª­o·°îÝ¥€¾-êšœ‡Q{›9LÍv-!¿Ùs ´ªä4éºF÷¨”óR=› 'iñMœÚr „©£cIÄ{2…|ŠoãVåcrºrkÈ]ÁgÄL—‰ÝC‹kíWRùÑìæÍb5WG¾h´kÆZ¥N…±ë„Ç«ñ/ þ 8u"ÊìN¤³¨Ð™Rh?= r;íöÄêhsæâë<›>Ò¼H*Ú,¹±œ`îÚõæ³j*ç謀;ÃQ{ÝÆE£NseÅeÇ«4èžZÓ©fÌü.e ¯‡˜ÇYÿÄ0„§¯s"s9hl–†ÞÖª¤aÆðYJLa‹’¤çθ¸5Ù²6!5R Ý>mˆÒ¬z*x£âú‹°nZëÝBe¢š”󮳫‡fµûN3(¨£è¡æJWs!å_ÔÍxìpËÅb#—·ßÝ (d4ñt­Êêg?HFöx‚\/oÌÇûØ© æTp$¬^3™‘‡ršb%Ÿ,Ô«gîî^ÓÂe{`#g ÿäˆ 6\"óaF7À°Xyb5 ¥ž-q«9ÜšXwåp,eœ&ã\iU/ËÑš_F¿qx6mùÒ…YÂî^æÀi°»Êmj¹Üõ=Î0… jSôc¥el8%QO¼ÃZóúp¼[i-~¢ŽÔÏFœ!ú#ƒI¯ÐÇY·ÿXÆÏÆMæ;¼×ô‡~¸â4©LRÌpe‹|V|qšc^JwÀAXrvžøCø Sƒ…"<6^Û+39ÚïÏçÃÔï$ªêEc)§Û¥!f= ú{åÅ|´ý2ý™§ —"þ“•g Ó €Û»Fo*èR¯ßš„Àùˆ¯gâ'óE*KþƒÀ¥ñZ‘µf1üôGüé,* _Q Z7ã[Ê5ç?@‰OoEEDvürúáúêýÕ÷Ó.Rs£§ŸQ,‹ifÀÕÍnoD̦?^z­U ^ó;l­&Gìb(~95ÁSÔIöZùÇÜêÜ_dùÿOÒ?|H÷ÅÇï;—o¯n‘ù± »Ý¦ÊXÌên’Wˆ½]²±Úl1r3^Ü™©e™óߖш›@ð™ÿ±n!k—Þˆý¼Ú"0+V+­Áº¢Ù¯©¸žäÐÔ*MV¨A‡©›´-†›²î¦¯ÊÕ' ÙÌ_56L®ty{þ¯3õç¿Ô¶²endstream endobj 411 0 obj 4200 endobj 414 0 obj <> stream xœ­Z]oÛÊ}7ò# ¿$7°x¹ü¦oÛ i”¨›ä:JÀ7@‰¶ØR¤BRNÒþùÎîÎîÌŠ”ì~ –ÔîÌì™3g†þzê{âÔ—ÿðÿåæäëÉ×S¡ÖÌËÍé«ÅÉÏ×"„/÷sqº¸=Ñ?§¹š†¡—§‹Íɳ<øiñ÷“P$^–gð|±:yöj~ýçùÕü“|’ÄžŸ)>¹z÷§wêýØËã$ÄÕØ‹åâ,òØ6=E¹—©'/뾕x?·ïW\‘ÄY€kúT/ú^¥fñ/eßwe/ŸD™—„Ö'µz]äžO¯YLh±®½AxaG¸¼lµ±´Ø6US5wÊÃÌ|Ð6õô#$?ÚFÛ,¼ˆÎû&—R/Žra^ëVèZžØ×Êb‰AH|{þú´)Çó¤ëµò{hoÕÏCy•‚~Þ—x; ¼œÎà__O¥#/q~€çEÙÃNý|: ƒX¾ýÙ™~ÅÅaì¥Qº]9µ\"D:züFº’“ÚÚ;ô½4ßRä‰p¥ ÷Rß‚dÒí~ ^F1ëÊe{×Tÿ,U âÈËS?Çg_Ô’´ßl¬à%„'"óÎU{§s(l$lîDte»¾ìÔ›÷³j¶»A*„õ02Xî1*ˆÔ“€”€öüÈ»²)»b@7 ”™Èp×!cnh+„—6´Æ ðn2e…:%ñ¢„.»Öæ4Ãÿý¢ðs?³÷5Wù½Ølëò\±Jê‰Ü² bß½Ç# p⽸ÆäS{ÔǹɥÜ&tÑh:dÓc/M„^^}P¿®éþ1B³H2¶²ËÛÛLj‹·Â$zFÄòªE¶ˆh­­ËB,H!ÍìeÝkë… ¨w–UYÂD¦25Æ¥Ë7”€ûAñ%öÅ9Ä@ßS$½M޽m°“rF-L2ˆfÕ4–| ÒlèBÆâis3ñ‚Ð;A§ín€4Tfa^pþ½íÚ ²ILÖf¼¬l»jS Õ=Ö&V“Km^ÀÒcÛ•«j ªscàäØšÞïLáÉ"*äåÚ~-u#[Z0…d©.³ì‡2È)RG; ˆc¶Î¤„»º,W; ÈPÖcªUù¤{l›s¼’ÉÖ’”üÞãlADæYî'·.I–:Ú9£Cø@óþ·ui3Ÿ°È€Ñʸ7=”î¥Fvâ{Y@Ü@!ЧB>"抉LKYib°úa`L÷{«éÈ1²Šyª½g*ËÍn ‘ùëË…‡61¼|z¹’\ÄÌ öPŠWX’ÔÆkYl«¡¨Õ¶ Kdu9 e×ãy~d`™ôqôêB’îb[tÅ]Wl׈§,±WŠá€¨³JS}¥åÈ"p0¶wZ¬@ûj¶^[‚ù²0v)]Þd*Q~S¥6µ2äÒî©ôòBÛfDâN Dì~àp~¿nwõ …O4‰«=î Y"ÙÈ3¯[ýž/2‘|µº¢3”2uYô¥‚ÓLİ,Ø€€DƒêàÓQ?4Ò¥Eü;¼EV¨»r[Ë«A@¥‘+Ù€äÖ·jXc MÛÌæÍ]]õêaEò¸ê97’-³;3™ VÐyuu—I¤ç–°Ÿ+7AæÉy´ØiD¨;ñ©ò3 ÆBGç žúM±)MŠEöNÇ2þŽ4©5ämLŠ˜¾Í:uœ¦Tên¿ÃêÔ‘`Ž:Ê#°W·X]†‹ÓDr¸€nÌ8\Æù6Ærq¢K‹ƒG´{ÂÞßÑv/<¶‘+O  G ¨£ÉaÑ}WT“³…Ç7þŠ=9Rpø«Aþgf°*šMä œjÅ®YAEq ¤ã¶£NÑ)öÕË~õb¸˜ò¬_EäPÓäU¦:Î׺ŸZepóþúòíBÁ ),ÞÏ>Í?|V9™C9‘½6ËÉÉýÿzýòò¿Øt-Â?ÂŒûcähÌ;»‰¶¦«Š/º¦„2¢6O>öåK“òo Ÿ@ÒÃ9¤ìàùÆL›€í—¸‚øw˜ÓåŸAÔb‘‘Ay$ö4êí9"ƒ Z¹ýLU?¬Á@YÍÝ ¨:>奨ô<…ü_Ê;!iÅDÆh ‡(®’c »1w„Ò¶&¨@#&WvÍR*ã~,N»rØu14µ rÀFk:ÜéY¥MÖH¦ãÍmš)¢Û2¾¦²E2»òöÞ¬Ùö>¤‰Ú{V.X{o‘í½‡„’Ð\‘çLL#Õat;Óc¢âÀñXYcü˜Îª¼-võ`„"ëD7eaƧn¿>¬‹aÌŠxyj”!ά ‡J5™ŽÌbB/%?µÆ¹ëݤäͳ푴nËa‹ Œ‘L@YÈw>i;ĸì:ýȦº[£qñþ0.¯ßÐ[PL*yhÇ‚r]`n2⼋€ ¿0¨3™ó ¢)„Œpë&&@*8˜ 0…Øo(1ÑC¢÷Ù,ýp"¹äá~"<ÀÎ0c¹{Îç˜ IB²w]ÕF g$ý\† ˆ:ô$ûÑáL¿cà–ý¢;¯wåb ‡Pß=)¶P@‰$cjpzñe½@O6Ü,áÝUR+ó#åÅæ0DÔé×eeEá)L™“4‡jBý¶¨ûÒt9‘<1*“8UÓбŽáe?‚Ä%5tAb xY§oúpýb†ÁшÕÛl9t÷Çwï?½ž¿QÂvñæªÅŒ`”] î,„ cµî ``7º¨„_’Aj .”savÛ•Írí}iíx8‹yÀ.ä'!¿º Ä®ÅÙ°üº+êíXÒÙ\xfºX(nôlS0¥[=“š^KO‘‚öLøïÿaBêøõÃAÅün JeÁåb¿:x:sû,±o¯WO<š§ CYzYÛ­nIf"’•D°X˜Ñ§.®Ôí?݋ͦøGé!œ! ÁÓÔ˜p¡_û~QR!€4añ4Ì Xe€ç"ãù*£j&b|ðœ¿ÝÜܨO^½ 4 ÛÜó}Ôg}²§ÊÝväàÍ¡?@ír„´äv«?»u~ó Ûæ½Æå È>›(}ßàzE€vÐCw©+|!oБî¼Á³ò®¨_ ¹‚æg*;^`lšQúê¥O¸I/¡Ì†m7öÙžç†-ÿ:R'¥„¾à¹,Ó ÙÞÏxÿœ=þd35Ð ?˜Bé@â Ï™œöøîG#C>ÿ㙽8“Æ6û­vèMöÙN­†º…!%sLŸ²1åùqÍ.æ»$ûðÆ:±I¶µºGŸ'íÌcEoNwäïý‰ªÏ˜lnFúg· ü)…e¦Àlöbç1!iÕÊxé*ki ó§l*4i£+ÙÕ¨—.¿ã0z«¥˜ÜñÇï¦RÂýv<¹Kì|¹ûÃûüö“Öx‚ýÌ´¸2''ýÀ†Š”STÞfa± œêg?y°‰1¶o ÐØ *Û—f ͆ևÇÐòOOìkRµAbŠc¢?†kÝ D¬‘6ý1û«†½†”Ùm{0GÚç ìýæ çˆ^öçc}©õyÂçß“=Î,„–ÔhâÀe¸€´ý‘®8çïaߣîe¾8ýõDþû7*±‘±endstream endobj 415 0 obj 2932 endobj 418 0 obj <> stream xœ•XM“Ô6½oåGLr Tí*’lËvr"°$T‘Ú ªöblïŒÃØžµg ä×§%µÔ=x¡8,%Ëíþxýúõ<¬¤P+iÿáߺ¿x¸xX)wþÔýê×õÅO¯T'¢”¥Z­ï/ü jUÊUž$¢Ô«uñèé¶ÚÚéñú¯‹T‹T&.­›‹GJÿlU!L‘'xøb°g¥0e¡J<ƒ·‡êÐCµëþqÿ±w’´¥IñN™Ø³«Tf"Ï’Õ<,܃×cßÚGºðép}¼wŸV"…ï„ÏlÝE•‹\ç?Ú£\di®S3;ƒ¾d‚ßÝ€ó¤ÐÑ`çoJ‘Ð͹­c™HtÌÇûT¤Ñ§?Úy®6­³¡”ÎñÉw;݈ŒB¨¦`C“¡ê½jb²E^’<úðrÜŒ.ŒLyÌà~êúîÐ}p6 ·ytÂÛESq÷èæÍúÊ•() Q˜ru¥!}n߬/ekõz}s‹•+©Ð—¾ ©.áeôÛÍúƧ,ÇXÖöȈ’J÷Ä¿›€Øðî%&LSÒ_<¿D`f&&ìÅóë—¯¯/1ç:eÃok<Ý<ÁÊC^B@O_9³™Èò˜˜›»Ç"`„^_º>ú¶€ò|˜ªaÞU‡}JRUlæ€z–WtŸiÈ`™fxþÉ‹RÅï}?)è#™¸bi÷ ·ç…Èɵã|Àt¥„¯£ÿ>¼.éðéÍíÛg×ÏÝ×ÀA¿òIDFÝÓ´s=u‰ÈM¼Ü6îrÊ[­­¦]×N>6#Lш©EI·«¦éB¦Ý>ŒKGjwÍ".D¼­†M7lÜ9´+a!´ëIÔÔj`6Ͳ3Žá³…ï”bÌ4Kþ[`Åì  Ò*zÆÂ6'a»ù™+ÃÅÎÐú‚áR‘ |åÀ0ÓŠ§#^lÄGq™“™/•ïOZûʇ­íŒpŠ£ æh*£­€f–kw³œÑ@¿‹¨·ú4Z@E ³xlK¡|q"éÈ{ÏW0J¬/†ìá€Í I™ÇHиšhb×½"×ÄHkšÑL]í»ƒGþ)ÅíZÛ»s’ɇê?ÖVŽEòÛz|0Íôi¿m‡9ÀS¤„ƒ$_BÚì@m=Œfçn3Ì˯yÜÂ*T±d±„ô(“áÝtÍÒ–æ"¡ÅÕ $õºë ¼»ÇëÒjͱNÔ§HÜî§q3U=Н”bï«÷¨ž Z[…¨qIç}…*qÈ'ϰÊpm‚ÜužSOñÜø>›uM÷]÷ËÔŽ¡ý9éTW¨r;E‰Â=” võ¾ýˆ‘±½ ª…\î{'«Ç¬ZKõÆÕ¦*>Ÿ¿~® !ùþ™÷Èã9‘_[w¸”K+Ë~3rmBºîîQ+6âhÒ›/o~S½fõÄ_,Î^½0RdÄe#Äf(‰ƒ?v‡í’V›nÓf³†<ë†zwlÚ·¯+ d”¹qk0-/î=˜¬:7_gÇ[Êæ&Sm!D,ð S/‡´|âˆËøO‡qéḛÃO ¿5“z~xJY·þ…ë0›xŸ&Cb¤­j4m¨’Ûå(ç„oø„u×}èšc3x.#sЍepñ ©¤[L×Gjû²®/N¹‹W)°´§³*^Ž¥ùjo*v™!×ÐÈíÀ”øÔî'Ø¡*£ƒëï©r û³$è¬a»Ú3 !Á×·$93,˜†RY÷q·8$¢â·?Ë,ÿÉOWC`Ýœ–^+›Qˆ2Ù~ ô# ƒ‡c;G~†GÙî«éýÇÈÄp_ãn•ŸY™Êùýúå-ʆœzì{œÖiÉËnD˜ð¾ôÎy^_†(Ïí²àÉÇ\JrË–#,ù±qu‹ uZ¾ÏEVÀlFúe„D˜ò%ô+p·ë>Á-Hh:ÊjsÞJ퀿¢:ºN>G#[n©z¼\¯W^Øÿ…bÊendstream endobj 419 0 obj 1936 endobj 422 0 obj <> stream xœ5‹± Ã0 Dw}…ÆtQ¥¸¶£5`:$´tNéPðàÿ_§.7¼wWIkZï ”‹ýkÏ8Ü7q'!e´ü‚Ê#íÑ2tú¸Ùœt8½½¡Ó6¥9½ª ž8ö±™yy.×Þ“úàõä+L†+Ô#í"³endstream endobj 423 0 obj 125 endobj 426 0 obj <> stream xœí]Ýoã6úGø­Ù+Ì¿I`»‡ö®8(¸^£dÝ:vÖö^»÷×eY6)VŠ›ØC‰Ø‡de‡VæÇùäðã(#t”ÿv?§W¯>ŽèöYõcú8úþæêíÏ”»'Äf–Žnî¯J:²ÙHsN,Ý<^]ÿøÏ¿ÿðŸ77¿^ FIƤrswumeñìíÏLŒ¨&ŒJQL1®…%f;pOïØ©„ ÅŠ±\î~ùéêú/o¾vŸrÅG†X¥¸Ù®F7þð±à™ÿ±"Ò »[ Ù®n¨ qjèI£Jˆb‰ðå ðeHæÍÄl9HpîctL­&Jëј™-ZÝÐoª‘ª×Lláú WM©è^K"LûJÂ#¼jb=² ¯¡JÝÁ•ûpƒ³´ë‚«$FSNѽ•$·‰%! ^µm@ ‚¯!ŠE$Â?es§Œ²ª¦ù7wE/(^¯{î%0’ ÃÌñâ*lÛNœU:Œû:,ðˆ hÝüZÇÖÃjù©¡ªŽKb„Ä ¯L­9Ó;8ö™ñ„[xÂ-ƒJX¸×sg¸åwpY8bVï×࢔¿Ä±Q–ƒ¯—t”²}£ÞÉ2øu²lŒÀ¡•KÿQºU·øÍ¾(ï²ÜÚR˜‹$áVª*`•ß/W9¼'oKÓaF<˜ˆFB±r„3îù ^™ÒX0UÜ¢’rIDÉñ òªDk¯bàk…Š!Ìœ¤K0 qÜ„ñJlÜ–fG¼ô’w•×îœXåܯa¸µ'õ«$zgº¡XDÌr7PŽ =-öêyê-¨ÿº}€ÑF]˜õêZG‹ˆÈ5Kçj¹rÕ#ë Jùv¶iê1À aV SŒ“NºÇs»\~m%÷.«é¤Ùf±l¨†‘DP5Àý?ai8[bzpT 8ËŒ›Œ(F/‘|¢ Œ7ÀÇWµÔ‚v5>”l J4aI:KM´'CÑÈìÅ ã–ÆArliA'tq~AC©S@õ>ã“긌À> gï8jJ’­AÍ%´Ô[æXÔ{°G$ç}$DhÅí%̈K(oŒ+סMøi5Ë£w™êÐÕ9.™MÑëspD º¡„[ê¦Ò3Ã|J”Àõwœg {•VJ˜è©Mö|L(¿;9ÖpaÄ‘:õuzÖ×î“TÅÍÀDæ‘ù˜Ð5H4´ƒv΋Éjx"(D1"ª h8~9 ýK:êºe $jˆ<àf2o è½Ö± 1B„ò3P3 Îðü7ªæ§|^Ls&‚ºßëg“S¸» ÷̦o)= \°®úÓæ«UCk2ç‚0UÎPh¦^ {Ï8¶íñŽ€€ÏðâŠø¡*¬ ˆ(£qòNÛÙ>™cÛ¹P/É!k~ùf>ijai ×줞H½Ô IÄÎ0§2Ïœ ÎÍÔ²›Ír£Äcë_’ïÐB…õý²qB¢»Ó±o›d<”ˆš2q(iÈr²=eÐHhÂD²ÌN„´Ç˜hÈr¢Œ©-°w¹d`õ”#€ L 'BO¼œÐR©*…ð¹|¤4—[8TÛŽ–ˆ ˜ðòJ¥ÿ†Ö˹ûÛÊûÉ5-Q ²–£1/‡ý œêz:YO'wù›¯ÁȱÌê·Ð"â è°ÁÉbDÐ1óŒ8ã¯îÿ„Áfœ!”×cÇýþ¢Où·Þql9èeüìIàÇ8Àµ$SÖ\Z"™e±q< Iá¹íWÌë:’ƳÅ:_¬g›Ù‹a²@aµ†¿‡íþƒ@ûº$ÇC¨ìŽÉ2F85;(Ÿ=,–«¦êvÉÝï4î«V1Z·8Å…àú›®ñËÿx¸énÊ6øÊ·V>€B\TâÊú}ÁhÄ3"„$¼áÃMû­[yHÒÁ}[qg¯Ø*vûawN¡’H£R´è<‹@(cåØ`]í«Lû;LçùdB‰q”•ç–)‚ý¢„IA áØ7Æï³ê‡gmà–8ܬÖÓUžÃèNézƒ”^hã•òwþìƒß 5oQW «MþGÃiM2Éõ)ƒY’_1û‘·Ò3Ž-§Ç™wóWxêu:_6¤XVXFíÎ:b‘ÅJ˜yˆuPâÏĸ§Mô”šÎ‹G> ¯¡©›¥—lŸ9á}þí8nœœ-áÍü4]˜ëX‚);*tûó"•W”„q£-ql4ð¼›]µïâ„öÝò±ø(ÌÎÜÎ %'šÝáº"‚"¿¨8"À  ’¬ [”üp3ú×UñïÿI(8endstream endobj 427 0 obj 2847 endobj 439 0 obj <> stream xœí]Ýsã¶ï³’?BouŒ#¾§Î\â&7½Nš«g:}TlÚV+K¶>’Ü%€Œ"Y “™øFâ RûÃ.»‹×að°¨þÛü½{¼^‡¸þ¬ùs÷<|;x÷ Só Ò…ÆÃÛ‡Á€‡ºJJ‘&ÃÛçÁ•ßÜþo@±@J+óýíýàêýͧÜ|¼ùoõà¨Dn¾ùøã÷?Ö×s¤¹ ›O9âÕ‡ï>Qó‘BZª*‰× K#G¯™Fª¾ônöü\Në[¤UÁ6·X.Öw`´°ï`þi†¯7¡ê†UX¹Q¬°Ž~”<é öÔ_"©w°š"פ ˆ21¼6Ää¢þâÛÙóËjYΫïon‡?:…TÍÖkfþ©¹˜¨¡¬þk8ÿþÃà݇—óU9x÷Ÿ!¼û¡úßû}kþ|ønø—Á͇úNþ‰¡5ÐffÀÔ<–™,„¤õàÌôðï»q9½+ÃcŒ ñcæuglg³ðÀ””H½ÅÀ46¿(q^Ú²–Bã­Š|ž”Þ3„9I„?‰O!a]ƒwÄ£Ü&ÞÝlzïýMH¨â÷3ð²€{y,˜}sÉj&a-‘™ìj&‰Æ««]:lf@^4^áríça‚¸ñáb~^aŒΔÈSHŠÀ=â$­k¸EÑ6AâŒ×bCŠ¢Yy­îFJršÂKÊÀ §jÄO“…e^°Ë’—}–|¾/ü”ШX€{ü 6˜@K0ßÁ8Þ³%'ìÛ K„Qÿm(ïó|üøT}lÖ4LkÒ˜/s8¢š3•Â[Jb)#Ñ6{ѯ][â_`f©ö $ëE& <žâÖ5Ô²@R¸ÜZMk¤,,dj8æà;ËÌÍÀ#=&J[×`iñ;á´ùl±x½x™C*ŒƒwÈ“ysIA &ÐÀB*ÜÄ´¤Þ1@Ç’œ4³ˆ¡œäß2žmn|Ùñ5wM´˜,&³‘3”$p;ÂÌùÞp’yMØc`RÖÍ…½5£'Ì¿péj‚@¼ ï?©ÑgàiMA´š/fs/ãGD‹¸µÉÊžÉ#D®/ÂbˆY•@JêüêµÙÃk¢³õ÷nU–¡!ÚÇÁÕ}ùõ´ü毚1¤™`‡<3€÷—Yœ€ž€¶s´í%’Ú®isÿ7¯¢ œµDÛ·…óül€Ó£¬køþ ‰‹[¬Ä©b\Jp›™;Q ¸Ë›’ØA‚ûr2~/˹?^Í0bº½Íé‰%ó¢z1ÀXÞYM:¡†»ŽÑëª $'SŠŒÜV&æ…:F ‘Šîî%Þ/‡Ù9Fã¯ÊyS8¹oª¢l’u&M@±ð­µ_¿ ß6~Ð ­S¿ˆ±n<žåxâ%@EÎrŠ~Âç„çªHb—¤;šg—ÃÐä×§q ¼êÉa¤G‡“ÐûÍ@@ZûÖÞ’»ƒa“BÊ–·4ÿüs€D##‰&úRz1ˆ”‘eaë‹|[}Uði·Õwã½ÛUyïÛÞÃØ,çÛi\0_PDÿNØ%/Χ¼MükR "4‹/ëT& ìB%ûæ‚xüÀ •Æ”KaîP”™’ЋÌÀ<ײÈÒÖ&–fVäú:´ÄRHªÜC4Ä ’zl°–XŽ ®;7^†ÒR¤8»óv @ƒ¸H`$?Ò±/®y™ú]·ªOôAmý²òdàù'5Iv"˜ð…ÇjŠ¡5Ò…8a ¿@öxR&9±:Û¹c.“^éÚH)ø¹_QBDÏ€žtj{{¶MRî2éeâ7J„"ªÄÛz|—1ˆ òF†|9Þ²@Ù—ËÀÔ|¹ç—z³¨ÞeÝÚ›ÏþͪIºèPÚœÐO°û¤A¹Öù6|G·#t€$þzML!š€{z¸@ƒÈÀ Iˆ]¬c“D9–dV#`Ô²ÙõÛ‘*Q¯ÃQ]0_Pê@ƒ¸H`¤´ÝÔiZ[£Ví8O bx|#b’t¹—ÅË8Ð0Hd`¿¦£H³û¦;]£Ë×Õhâw݈B'ìÄ 2ðø¶ÄÞ¼qKìöÏ6K\ËŸš»?÷b=ÆÚ¨)‹lN_„rª¢Ã±½¨t·j0ßÜAd `¬›M%Ù¢Ò"PæS É:äó…d 0 ˆAd•Zýmm*Q×4T ÍQŠ)âÛ¥0ßÉÅA 0R¥M|½ 7¤œºŽu‘ð4“‚ÄIéf×Õ‘ýÓ[ºMýtããÞƒ^èï›çÓ‰Hæ·›–¶–JáÊ:¬; '"Ï<“œøÍ$æ®”B•u[÷$óŠ20亭{r¹­{æÁb»QÅ“xú ÌÀÓQI:0‡J­àE¸þ.{|˜.ðDŸoy|óQ(!57ÊÊ@˜ƒx³€ž²Mkæ¡þr†[cpO bxläf{ËúH^b<<ŠÙP i²cR`]Ä—"=z é6A‰.u»Wû*Ͻ:¢O#;¸Êª’n<á·@Q7~›:hÚ¡Ã ÑØI£<Šq4f‰Áýƒ›lZ¬/òч״@„ÕWþÝ{7*Ì÷Wþ³Z ÄˆÊ ¹ASÕe¨öë`‰þ"Ú-ŒË‚²šµ—Vâ6UZÀzŒš]‚Dÿ™}[³Û}¯; ±µ]ûzRZm™3)aªgâ~eüan.Rb %dÓÑÑéìà´„4L öHÙoJ F“ökV‡Iˆƒ%úëÚIãœ9LR.“9H Êze’Òf¯°ÄH‘íŸ|¹¥Û2P$ïMK¬Ÿ £ÒÛÏê•ä~¡a³ššÞû-—@¼m¸ì]fHÊ b—ÍKHâñ8Û$Þ§Vc¥æ‹à¡²BÜì¤OÅHe‰r¹Q@l¹€n׊\ÁÌtÛaÀ„;S)K< •\;åPÉ >²1FZÑœø6 ì¹vöN¢¿¦ªqê¤uÓ& w³à2l+GwÕ·Õyer»óûäå @óöáLÝÔ,-õÏa÷ ‘i‰$íÜAÖ2Så/Õ—X#Á·S@ F„òö¢à uæÄUbàçÆ6›8´Eœg/GÌJ ÓÃrýÀ¨'D re‰‡2‰Ú¾›hùn¿ÖH""¶Û£y „ΫüÜÖS䦗 æbÚUb¤}¹ëj”ܶ7/«@ÜÛ8eZ索ϭ,½ó¶Þ:Xçæì­KxIAŒqcuþ˜·1`lꃯ®ý&’+b^ 1vΓ}øó†^3p5™¼ÌÇÓê¢ÍŠ67^’i1âçÃm“Ò¸7xl’j›—`÷‘ëb&FµÞ’`q7/Ë©Wå©BTÒ¬ò½TÀ”U¾[<Ú©C²,Á6Á2Ëò7ÿb‡Tà.`½Í>Óåzi~ã°ëlŒ×aOz•]@ŒX÷JùÞ{·«Ç»@õ¹Ô¬Û£ƒPáD€ÙTõA¢ÿ`¦ÆÍöy‚N®Üc9]|öo+Eåa„;‹~fç-Kü2#ì‚=Oúèf'ç±\KˆÒìh=$kö1ç÷™’“—±c™j*­CÒ®u™Ì~ùË_+*Ñö†gÄ€;S ´DTŠ„’¹@pªXgË™—6õÁ³íóýJ13j–ø§½9k}#ÃÎÜË|æß{ñvc¬žPY™°…è¿D:[C¾ŸÍÖØŸy92‹ 3-JÍe*þd}4 3Õ²Ä?bp"=ò©í”a)Ê×Õhâgç¨hïm¾½sö,¸8ÿ„ÄÈ2ÜÖ\ÎBšë÷†ŒærÌZ{§;!˜ìº+aGušÈêúµ–2Tµ… €©äݘJAHŒä—¬IØHgu?wºžßðÞíê©ݧ¾ÝtJ–gßÛK˜óTÎ!ÑcM¤íÂÛé‰Ú¶&OeÀÿÉmmOì×$Þ3rEvÉÛ1ÉMyß—ËÕ|9ñ]À0bb³³ ¢O“¶ÄHå"+ö,G£ï³çÀ!)Áã–Š.‚Bœí’xR&yhCì“§ìsE¢Ä§õ 5æÛ­6NØ®¥ÎÑóäí‰q‡¯•4n%klv›õ•‡€¿¬…Iy#wöÿê3Q[úÍ@\k‘· Ï´%þÛæÆü¤už}Ë)\”¯^Ž`a\Âö‘!ii,T`vÓ’3\u»‚›ÛáOƒê¿ß3³Tendstream endobj 440 0 obj 3545 endobj 443 0 obj <> stream xœí]K“Û¸¾Ï¯Ðm탱x8mU*{He³I¶æ°WÎ m+ÖH²ël~}@r(0àÐMƒBù`›ÂG@TìFw£ûë #2ÃõŸ§¿ïo¾Þ|‘æZ÷×ýãì/·7?þF˜¹‚4Ödvûñ¦™Æ³‚1¤éìöñæÝß~ýëÏ¿¿¿ýÏ §a*ÌÛ‡›wº¨¯ýø“l¦–’©úºQ¸Fª9ßUíXΰ=–hTè§Û¡fÄ™"ʽĈ"£F¥ ±ˆ ùÒÞÐåÖ:Ä­«ÞJˆ†ø82p*@‹ðpKˆãZn´œQr©ÖxüÅ{³w‹òΨ7B/p§¸ª…—5©5åÑo•Ð`dà…€Úz‡“£v+í¶(·».STˆ1 ð<2Ø"RzÈe!6¹HK.¦uK¯ª¬?¬ý.„Ó'Àóå§ŽsÒ¾/ňJV< Ûßß-VŸV^vš!§¸§çl çée °EÄå[¢Â‚ñF¼)¦ˆaÚˆ· OÂý1¨;.âÒy•O;“Ž¼× ·"˜²ts ³j» xð4Ò˜‘èZz¸Hd¡=f˜,éÌ%FŸ3öÛêë¾\øÅ bRöö:—×W8 àùîåÑغ“-ò’¹¦Ù“ÀûÕFà×lÌúRþå¯ñ$;/ûæ’_Öͦš)ï«Nb¤’=Æ1—XÏ\š/«÷«e=‚a¤Ù!_`7o.šÁ˜áƒ£ªÜÍÛÁ§ä“¨`’¦ð¼®b/hˆFz§ÕŽå348ÒÇ·ÍPŸˆEdà4€Cv…exé#Ýwì.C· ›Ša:J®A<¢ œðÍí.…„5†Ëîê›]Û] ±L#ÁÅ(ÿnB¿TB@‹˜>0=q¸ÄúVànUn6MøIÄ9éâ‘z)&ŒuÈDÜ%–̳ËÒ=  ':¯mà#qL³¥_—`3­ à¾' ˆEd ¶)cŸYh;×K;l[•!ÛáQy”É<4 @‹ÈÀ ‘˜å¿“,hº"-Wóí|á7Ô¸@Œ²xŠ?€gÅ{²ÀÈ._é£xKÚ×ëù½ßG]§õŠœtŸi¾W"!G^X¤P.)êOêÑœwÒ_úxŠ Â{qœaÉZ ý( `‘ÔaÇó¥kPyÉõX~©¯S…°8T樼”“îÒò9“ÉA,b”ýåç·Ù {ûôO­Ëì4W…!It"Ž1‹ÈÀ䀑} ³¼É}íÓêsÈ'®ëÔ0_Ìg’WþÚŠ€”ü„Ži%‘bœwÙßÚKLèCù´js_ný¦åHóQ'O<7¸@‹˜ÐÃeÁHø(ãzHÉÔˆ(™®+Ä"2p @]¦¬Ãvþ¥ëNÞ~žNáSŒt¡rä1Á-âÒzʶæ˜m͹Ž2?êj/ËDŸFf†¼õvÊ=ºÓÖ¼RôöÞ»³¹j«Þ>–÷›ÕOïðè>$Y#æO–Э¦¬ThÉm­Ö¤þrT`Üù·«ÿ®Ë¥?cá: !ÚÌoƒ×FêéÙ¢,œb•(<ÐQ‘ð)‹È@0o÷^:™ýv×.%¾Ô›HãCåÈ@ß( -á}÷L¤ ¼‘„¿Ï\3éìG/“yh˜_Oˆd½,¬\N7Úcˆ„BÁN0í{Ò†} ˜)u ˆE¤ Œd<;,qâ6ÝádªÒ‡@ÿÌKC2ÁÓxH ‘€‡}‚Ò>¯ìD_‚½Íæ¾à8Û`n#aWq%væ>w•ĶÚYÁ)R„L*. bxnywCÄ:úëæ?¶’^§…+õÝÕ—bZÈc>¥—æŸZ¼õ—±ˆ | 06'ö^Âð ¦M RC,aë Ä"2Gì.®zœj ¸*4%Œ0ŸdNöÕKÔ·HR8ߪ{ DÈ¡¹Ü~ë%„FÆÖ""?î L8RÝ`++ŸZU^ž˜Ô™dMƕ۲øa¿ð7slz%b±ˆ |+`¤Ò—s¤ØµÉVûmÕ˜[MÆ¡ìhµòk‚ Ëú=Oa>’̯kFЖ=êç»Ó1fˆ 1GºU¿zofvºMw_–•7Ù!%ûUòh½xêK§ƒú…ôGyîu 3^„ç^ÑExHF)Öe©;‰]Âh£QZ-S³Æï÷¢ ‘B1’—pR";zÆÁ‹Eûè£nH"ä$ÁÎIuù|!F¥mAä3ß^ÒfÓùfŒdŸˆ^÷GKúG*$8‰—,žo|Õ·Þåß³iÏè¯wck‰&iÑ!‰onv3^ºB”EÀÀ‰ ÞDõu,©ÆÇ[GGðÁdz°†p$È€ "`‰… ¼>ÛêŒm# E{’~4ò¨m|LÚÌïîþÓ%u§bNÙΧ̀<ãu í——´°©>nªíg¿¼›K (º •ß眘\%4c$o‹Û)Á®5¨)ê@J|Ñ–TCN\8Óž1rº„îTÚeW}Ý— p„D9MÄšJ(ÆÀ"O{ÆHŒÃî ,´OÞýn^#ïh‹ Øâ?+pB“öŒo­-ïÒõDµ7Ôä˜Yµo“à)Ç\ö—áˆð©í“ó{Š3úË—”„}NÄÍùÒNŽp³Ûï;yíÍ|IÏŠ%-á=£G×FR»œÛ–6þʽµçеÃþ齕A`Þä1®Ö¾,FB ¦UfÄ"²Ö›ÂŒþ(Êá$Š´O¢ðV¡1­›ÏÚŠ©n¥Z–ëæ2­yLŽ—=ì¥ÑX— ï§½ËÏ3¾®&¢¶Ã˜Ùœ_Ú7Ué—lZÔAÜÝÕ/ýNFAÌ(6סvÏS'ŠâçD}­)™Âºkûf\‡8úC¹ sÄÓþ©E0rœ.¿û™*Ž›ú—ê„Sùÿ¶™‡„"Nu¼—Ö$÷’ É͉þÙ:Áþ­ü5´¼‡l!¿¯3Û€Hâ5Ì8éÛÑʼnµsÇÛïBMP›ú¿4îNˆ%Ù‹|Õ–[ÀWÕÙi­¯*àEæ/ò¿¼·:ž†_—‹j·óˆ_g>1dõt3FZfq;‰Þ1óÖå&ÔŒ!ISI— œ’˜MnF; còŒÝ³žØۺ܇xSë,ß!Ù¬oòŒ/Ö7…µ%)¬š^î¡­ÆÓæ&ÆÜ{i$*Ì’–Í+NI¨¿cÆKo#üsì=áŸ?ð)/DŸÙíÉöÖ¢bF¨õpsû¼ÚSµ±În<åŸßŒ|uý—çd)9ý—@LÿÙ%jbú¯ôú#]b”ÿ°¼¦œzªE23¾Ä»XDÙv¿Z‚ËŒ ·O˜ÌâwÆ@ñn>‡1óoùÐ6P¨8Ĥ¾t3Ké—ôHL¬!)»'¡#'œ-RÌEàH઱yQ¤#Ÿ1}ù„ÇûЩLjÀS…(ptnŠŽƒ‰ËTÚ3ÆÜhýv}ÏÛQÕ¦ ÄdÍÆBpW ßÙç¾¹ Ó›˜-R¿ÆqmÅí¦¶Ñ%FK:À<øI2Ôá•Öû?û§8ãK> stream xœí]M“Ú8¾wÍà6É!ëÓÒiª¦*µ‡MÕÔdû²Gž„Yš&&Ùýõ+cLKBBnB7¯lUIŒK˜÷Ñû©W_'“¢ùsø{öp÷õîëï¯uÍ&¿ÝßýòS}©BáÉýŸw-OT1))EŠLîîÞ(ùöþ¯;Š’JêÏïçwo~{ÿñŸï?¼ÿwó‰à¨(IyøäÃïÿø}?GŠ z¸Êo.þò‘êK)!¨lF|Çp©Ç)'ï˜Br뺹‘#ªÑü€~\oZ4£…‰Æ I!ðá.ÔÜÃÅ+û£Ëè]ø< ˆIŒxB£Òº‡—ÍMï°*‘jòN3œ‹ ·Ô*4© vÉ7È•·^ïY¶)㪞ØV’=Û ²m{m¶xÙ AL"/e—'l;£Û¶A»3žeò$2ð¸%)%î\7“[q»±ƒi7±½ô­¹$åŠtwUµ—€É’ÇMí5f üIz4Ya°†&cÛÖõãÚË¢%Ë¿J–âá=¼Áʰ©¡¥J›7²Y  1‰d€n•·3t’ËðrMòcî{&1‰ |¶I„ùÓ“°9ä–&««Ÿ¾‡,@. 'åeªÇÔÞQ˜„GK Ãs"İí8E½xXl7ŸS‚gjª~õÒI!IÁŠô~« ¬ ¯a§éûú1ÀRÐPŠ9Má¥$1‰”'HñDO øÓA ±Î@xÌx뜟Pàè­/VÍgX ,E/öGÇXã|°‹¾Ô_ ‡¼¥~1ó'ÃG®yµÞ~Y6ªÇO³QQÆkUA¼ø 4‰ˆPF‘÷ÔÇ] MR")°°g“CKr}ÖsiºÌÂXÏqš4—(¢œóc}Ëb~v…§H*žè۩ЀFJÍþì9šùû*,LgÇm0³j¾«áNíÓRÊK¾[–˜ |9·Ö*ñ5 <œàfPÞýÁM-ï§& Ì—’À€/*ïÜŒdšò.zÊ»?’©å3|Q}à(™ |ywÊÌOÖçä}¾›üUÕà³Á>Ä$nΧÈÁŒ?v,)pË“Ÿ•_”Êð>²àeàK=|3aVék[ŒÇ¨R¾m¾xG4) ·~(‡L 1 À—°É%GuµOT˜‹NÓù ]âŠ^V—”ÌkÌÀLæ1[eöËG,&X£™ ûfK-!éä-m]®?¼OÓ ‚Mî?ܽùº«vÕÛŸ½…è’°››~‹  °Í̇[zÎÚÂûu÷¸­æ~›Q¡_µñŽ2ú$è"3¼ƒáí†$‹jÕ|¬IQj5u€„ åÙ×ÊÀ&ѧ<¥4`m¸Ïo±‰Öb#mÒÿ£÷ioêé|Z϶ӕÏXcX£IÜXðž2Ø$^·ôÅNQü¤;ìÚF-î³@ëJ"QÁIáëÃDzXB ÃÇd‰ÝE³dÓ7ž²„#¢Ü¦(ýæ—Ì{Ë@`À›«Û貈#lâ¬æ^âP¢]•˾E2ï-á¯gqŒšÞ:7‹ëióISªY°3§›Ùbá%–HåØef¤ ½ß ™_=‹M÷íÆÄõÌO‡¦À€Ç[gÁ|lzÔ”0`İÜJ;00 ôü&ã"Þä!KAÞxsºÙ›'-ºYêêj:ßë7‚!ÇôÌ—i _ä¾kÞŸ rÂŽM“pð ȉ€jj62ôØ¥–Ðo•Ð'qe#L0+V 8ú”H’|d_–¼¡c$1v»9qM’åbã/vÙ7®s(‚ù2>)¸q1[Z(—û=„ mlu[™R™#^ïY‘F¦ê'^w›iÓøÇ|Ìr±ªüfF%¦NøË“|¹œdà0€±"HÓ¡®Àï“„¢’Ï «ý%öM¥t£L0ßH&¸n¿hZÑnCjYJÂö±çÕŸcâôÍJŽîUf`’À‹X"Qi°Äl‘g@VóÝ,`ID‹«yØ Þdx=§Û‹#Õ4Ð œ!Yº£øöIAL"ƒºÅ¬¡§~û™íë £¢èq!Ìw’Å}°Àˆ¸[Ó™­&ö8&ˆ²ãÙVU½ñûàX R¹%ƒ ^ˆId`rÀX3î`n|ñyŸòÃÚ—<Ö{QÁt72ú$Rz¨ev¥{×…h¾QÌ&¢Ð,!-µ–^5#x1¨~ &ñCÀӟó=ͽÑóÓŠ>À<¢ÿYÕÖÝcG:-»U ý¶&)u3—¹ðU€q*õ~2•Éë¿á•òoy#dË›MõÕK¬ÿÍÜãÀ^Úz "mÆ0bŸI ;Wˆš N{w¯ß‘j p0uúR ØC R^ù`DœìSaP0jdJë°ðºÍ¥Z¥«D@L"«À!Œè1KÃòd˜:3q·ZOCvZ¢‚ÉÜã ÌÂ>†/dS`ËLgÞa³6ÁÕ. «Ï^0ÞÔX÷c)!½xë0íÀ’ï¬íåQÊy¯«ÍnèVT")e> r2”öˆ‘ؘiô–üÎèùæ•}Œ5ƒX¼¨Š$8x&.v1Ì'µœÀAÅjò®Ù}ܲï_Þ§i†6o¦ovN§è½/§9kü³  !…y{BåƒÆ 7U¡¹ ›ªpã9 ÆÇ¶P„Š@,ÁKžƒ×…)è¯&:ÁC7. ü,­3¿‡FŠ~Û#@â6À¡×°/1bF2Ói³ 6³ºªVí®í&0ýÔSy¨oZÊò• ðW¾Åˆ ¨ùܬ';iPÐf³z·jÏžàˆ‘ãCý½šÈñ²î´;û*?6"Z^è¾`.;óˆyö=tÖTˆ%hØ]Jpsj…£’¯Mvyœ(÷1¦ÌÎe¶¿´u8ÏGP^ØÿYIˆ]ñŒÆ‘FëÀ¶Áæ>{Êm/¤Z5a‚¸:v2ØV«PkZ­mh‘Ó©ãª1Œ9_Ò$qlµjûiÚÚjÌ89ì?ŸÃ[|(C‚¹såövR±¿äî»g ãˆî˜\ÛOþÚ0B‘8ñ% .¿ &‘Ì2—GøÐ1Å;߇Ž0û‚>AʲÒwD†Ú…®²2n¹ÊÄYÚÛÊßü˜T"ïÕJŒ&Éík»Îv3"ëØ"æ(„åâS«ˆ×ô䘢±è„›Y&³XbçšM÷Úî¤Yò0­?/V/-´SÀ.;Š$§â9d_¥¿Y$52ÄÜáÈözº¬¶[ÅÈð9i0Ò÷ÂÁ¨$da #z䘇õš±Ré˜<íéA¢‰¢v¡Ñ€û«Ä…ç2‚u(@K{B#¾(¹"Ñ$“I%wUÇ)“ÚŠV_7ŽÇ°}¤ºI[üaŽÐ@¾ ÀwÂË›Ùã2Ã& ]Ö3²l{€JåñzlŠ´Ç² .7éà÷õT;µ_[h·CeBò]P¸#Æ ³T[öY¨7‹ÿöçp„¥g4tHª=!ë½ßˆžÅ[œ·UÎ.Þþ@¨¶ñ òÅ´¢L·––<âÕQ>äY…'š£®~úî¥ Õ\RÅä8 ù#‰ÙYÀÍ+ÔÕ4pÔšB_Ö^&! =aP#¾¨)I-“sÙˆ†&{‹2TpÒ)—çØXƒT Mù<â9»èi¯ŽáOwçS“¥½!D:GJõiE–ÐúÞûY·þ•óˆÏ±Œì%ßê¹ä¦Í¶þt3)•=úSY¨Àg½úˆ×cjì,ó¸17:µ­ºý êXª*è`§=ÉŠÑ­Ç É›[„rUGHë¡””ìe½üÛŽ°Ö Û7cêDu|߆k.˜B«k© ÀÀÛ‹$̘ÎëITŸ«án>iCC]µê·z¨é&B]Ô°±„ _{D.û7%ç¶ñh²¿ŽJÉ#áWÕ4jeñ/El_ÒHYˆÒ1R‹g…_ÝZ<Në3–˳oä„TÎÀV‹H"Ãjãvøþ_¿yE‘Àe"Ñ#“ƒølÄHW«2ªŒa~"qíýP>¨rB“€)QyÄ3wùx9>ÜRS–½÷¥ZúÏZÅ ¹:jp!“˜$¦=b,ZŒ ÙjëË>LjiÓO³»ý›—YûÊIüð$0¢˜p|þIB#zt”zª•'æ©{4N­Õ¯~µÕÄ)ÊܨíYÀœo2âùý$æé­®çåÈ:dÚQ\ܼéZ¸ ŽtÄH'«Ó#ŽÏê‘í®Þ.ýyÐñ4ýÌ)H¸#F"ÐæiÅN.g±ò/ÿÚC¬G¼Ö§ë¥ŒaÄ×öR̲}jFì²ýõrÑì]© ®ABõxP¤4;#±×áàïï'Ü5þ ÆÆ’endstream endobj 448 0 obj 3798 endobj 451 0 obj <> stream xœí][oÛ6~÷¯ð[Ó‡°¼_ž ëÀbÀ Û]ÛM=ø²È2ÒþûQrd“òa¤¥IMÊD8üDJ>Ïá¹é~Œãêçñ÷l=ºÝIýYók¶ÿ<½ûH˜ýlÈxòyt±ÁcÅ2t{÷‘I6ÖÈHÉtuÛfÔ-7H×#w÷EyËvljÇäñ‚¨ž1¢‰ñ?âLÝ9*30ÊEôžñH"íÀ®Ý£”r|kI+ä\;Z BÚÔêwq>  ¬ìG¨œ1œž¨˜G@X·%EÀ(‘Q#Ѐ Ø&àt3ßîa2…¨f<Âç{ À(‘ ðŒ•9!úÄ¡kpÞ0 (—›»†Òc· P"ÚÏ>­¶w[˜+ÜÜp‹+Ri¢RxzYL/$×…ñZp)¦ˆšöÖ]”ûai¤cÍ¢»×£XÄÀ€g”ÐH‰̸zâsb‚„¥ä)Ü|fî¾&“¤“äÄ$ÅÛLª©D Ò”>Ž_ÌavD„`ÑÝ}fF|ÿÙA‡$}8òL¸Ô4º»¿`‹HØÁWmHч«L #ºC˜q>£H‘?0Âã1BûŒØ$œ™Æóˆb8 p$aÆÑ-Æa’ñ˜´ÿ´+‹å涯8µ+’݇dTæù0€€êÀN`€È“À æ…&‡ˆxe ½ô#Hæ{ÈÀKíð~4Úx?k¿™JÙ{›1.â’Þ[ú˜ElÄ¢¹¤uñÑ›Ku£I&àÕ,Ûÿݔӻ·oÀó9Á=üºq>½ ÌT|M*RLjSnŠ£’,kØ|£ Ñ*|™ÀÍg`üÀ(Ñí6ó#ù^üQ´i³š– :L!b/óœEGðL20IàËþÝPŠrƒ‹-ÅÈŽ'-c $F±ˆ ðYêÅ*×—ìdý*ê“ëk€\öoÎ_*s2Š™Ã^ÒPnIÃ$LŽ\ÚÍŠÅb2ŠSDÏŠ¹b}Æ×Œb»ïÝþ!ï‹3c"ÿÅ©iŸê%%‰¤BF±ˆ L( áŒ3¬Q_Šº€Êb¤oŠé ŽáPŒ´lç¤üŒ’Z}F£‚üfe2ت¥¦\IÒtP­£XDFC?ñͫȤç$ E„±—2¸²hg`LœçîjÁF1ÜH•Âýg`ÞizpÂÍÊôÒËÜÊK‰Íîó¢qBsѹ˜ü}f`„ÀŽ£ºv(!¼BårÍ£XDF¼¸Njõb­ hO쌪1c–†‡Fÿå¾(W‹uígfarôÏa!³„hýÝns; ð@.‘^׺2´¯Õ{Ÿ1 nš$g'uóØ)¦1ÁjAGLÑT¾Õg;„ácY3,ûbdÛAêÀÞrµ2y)ææl«RdN0òTA(ß2Œ­Gþ^Þ[óat³ß¼}S1«c.Û§}ñ VD)ÝN9À½Z§ÅƒW^Ä¥·ò<ã&\(F#½Ž–6 ð†h$N4™®V0™(¢=Zî§%Ù=Ý_q2õàfìò>»”ð"2!Jl¦kضã1)Z⨓„tÇßÒ&}¯g…„8ö!v{é áËv°›>Õžõf“A.C'IB3¾IŒsq/¸nºÌ›r°ííñÛðD:¾&ÆÊt%vø3ˆ4!vÅOäRÇé'2Š)b¹[Y̦H>ã< Ô¦4ˆ`.ËþÐpŸ¤pc’-ŠÙt`‰@wg·Ä¼×g’ pÆ Ì}cËÛ-¦«rQl¦å¢r*ÒX$"œF!ÑÙÍy‰;Rç`8t&ª^ªV›ö?ÁëUÝTëþªÒÀ7íÊÀ€ó‡0„¥IÛöŽ8¤Ýñ3¾*Ca:ߤ\kÇ3w¾,Wˆ!AX:^ÓX×gz'4#Üzå8Ÿrò­´W>ø°ÜÌëäBKuLo5^ÑÊÐ;LÆÖN?°}à9E> stream xœ5‹± Ã0 Dw}…ÆtQ¥ÛÑ0 Z:§t(xðÿ/‰Ó„Þ»«È$È-g¯*T”ƒ]µî‹èNÈØý ÿƒ 1&U²½@'Ì7ÿJ¤aHûÀ?Ðyyæ)¿›‰8õ—™æÇ|ìYˆzÒ@¡Áìø‚– ?¨"Õendstream endobj 456 0 obj 125 endobj 462 0 obj <> stream xœíYMsÓ0½çWøXZ}ëm‡é …B3ÀÕ¸¡5Ôq«¸øõÈŠeËŽCJ¦IãÉ!™µd½Xï­Ÿvo#Œ Âå§úN²Ñíè6ó_I½Œ^f†iÎI4ù1ZÌ€ˆƒBRD’R¤í…lt¾šü´ã ‹@"œ•ÃÇŒ¸qc¦‘Š&£ƒó«ÜåPNPFíÝÊða>+ƒ”!Ì©‚ÅÔ‰@’Ú›TÁùb¡°1@ Å.eW,!Ù¡àfSDu5÷ÄÝ0¢PßÎä.Æ¥ZUÁ‹»¤HˆÊ…D Q&ÜBT#¡¯F¢rŒDBb¢Û!F1‘íçK¡žQO|ÈQˆ'±ž9+&²0´¬U\Îó sbS+;IH4áUBº*9Š‹ØÅ4Â¡ŠžƪâÎLxí*„ùKg&ÍÒ"ý]^aÄŠ¿6­ÅÚÒýID­èÝÜ´}Áî5Jÿ›…6Ïëš…ºa!! i—…‡y–¹W‚±:]ßÍÒ$^™›™BB‰êžÜ¼cÛ0€x |yâºDÜ—b)4)¶b7“H ²›uÙýƤÅU6-Ò¤—È\!˜´á<¤ÉØã}@<¨ÀfòZ$PÀ»xŸ_ÚL~í,ƒ‘VþÂÇ›2fý¸fÚœ—óûÍãK±±‡ÚÓ½vOm_úŒ o˜KyÀ\RWt©ûÎÄ7Wi²‚öxÈ^Ú£ÜC¨»b}_–±?IÈFö¬HBv%ñÕål@˜zæçæ×ü&NÜi±¼©ÇžÆ³ørš-j;# µÑ)z%%·ï‚µa óŽ‚X[ÅÐÅf¡Á(-¶D˜¹+ªËɪ¤H¬»P¤f˜Éç ÔþTY×6ús:göÛ!àPñ{± —ÌçA‚å:L°ºKæÓ81ù LjIu¿R͋ڧ­±CPŸ_3±Ï—Ûäê5¢h£¢Bö"ñm›ccrS©•öÒ9«:< ­ý{ ™Îçéì²WPÔ.¥X篼¸|¿CP·Ä&Ð;xЖdžº{éé}¾¨ŒØèºÁ’¤‹" H€×Ú—©<¾Ø¤ñ÷ëǾB€ÀÓZìmÞÔD¯¹Ÿú›>¤ > stream xœ5‹± Ã0 Dw}…ÆtQ¥:r­5`:4¼tN)¤àÁÿ¿ÔN]n8xï® “ ·ôÞ2((û×–qJp^G_‘©^0½á÷4Æ«sdföý”>à8P]1¦ S\ïqŽÏ&¼‘±J7ór[Žy 1¨ïTIŒ ÐòDZ#endstream endobj 470 0 obj 126 endobj 473 0 obj <> stream xœí]KsÛ6¾kú#tLFˆ7pmšét&¶±¦wY¢S6–dSTÒô×_ ÚŠGŠÚñAÉg¤Éýö…]èi!<òŸòs±šo|I5m̨™çsõgŸ£9Fù¼¯‚÷8hòЦÊ¡®›‰Z-Ÿã.LjG{´‚t~h'Q¿PYåÐÏ!ÃÂçJ˜mû§ƒxâGÚ/:I ³C_ïT¬œ½w÷Aî’¼ãø³H žØ!îé)|Ö@K$ݳ³º w t¯›Ì"D; ¤Á<¸±C i.:ȉÒÝ|í‰hwۿæ؈Šô+‡ÛLB Ðù¡ý¥ð Û>Þ¹w¬¡·wŒ¥­ªvluÑM¸ÒÂLQZ]È¢4èŠ÷AL> stream xœí]MsÛ6½kò#tLÞàà±é¸=43i2¾ôÈHL­V6%Õí¿/A‘@‚¶¬J2(íøàÌ#ÄÐÔ¾}Àbwñ8$@‡ÄþT¿G³ÁãàqHK¬þ5š ?Þ >|¥¼@ ! Þ}l>@‡ jÎ!aûÙàýäïîþpªÀ$¦¸~7¼ÿxûõ×ÛO·¿Û+JÑLWW>}þås9^B"¯P Ò‚7Ü0 BocÊK „½Ä¢ëñ¿åÙx2JWÙÒ^ûðUhí>¨¤ (IªÁ`ÇH`*!Ú‡¨HˆD¨÷~µ¯‡X ¼Bjúƒ¸s#Zòô†iÊÈá åÀÊ O× EB«¡‹|ü$nA{M·^¡zÂ"ye!½£„àràƒMzPózkIKz“BO'ËUiÁz)bxEhž]Ô09k…¦½äš¤× MBT€ô,q4=ÍóÔ^¢ ®êÿ÷ß°  5'‰â=¢g@èí¡ãHøª®í¿H½P§rGpáŠz6{XÙKv!þ2Á‹Ék$8Bè6“ë}¨»‡\ouì²¹š£oä:{\§Ó0w¹EE¯¡˜¡‹då9éÜ §àdëäî|±z†¾’-&×1¼„L½d!5ϱ°š³ç‹Ë¾/ò¬CU‹»ê¦ªö;&‹ÐÛó¹æjψízï·½¾Ýˆ*dAÞR Bh~Ö?‰…еúòS­Šµ3„ª¦¨$}–ÍìÆ@í8Òù¼#ì¥ Ýx¸~‹|ÿ- ¡^±¹MÝÄÝr¨«˜£ßËõ·å*ŸÌÿèXS0ÒOeÜ[ÅðšB'Òs­BS›»é]f׺TT* úm÷ƒ^£¨¦Ð榢FóªÑZ:%tÐð‹ âçÞE­\é¨ä®„„mgÃ-§éò>ëH× ëKðéŠÐ‘ÔrݤYÔ4ªXÇi±Ôt§±lS÷à7|Ygù¤£²Û%'ÇY,Ò¡ô·=oæîòUoŶ.‰¨Äv´XÏKæ37rä|Y:6Œþ¡·'xc»xGp?i#]Ž&“ ›Áš5gd÷!tÀfñaœoÔD8œ¯j"*Qß”D$Àù.#«]üøŒkà ÔÅ—K¡›Aètzø`; ¦Ý ‡Înl» †‰B«·Ä½Oó m©Bú´F=L´ÐÙŠ Ê²‰Ð$Þõû§‡„Ý‚mBÒ,Š:qvZ+Boío…ÇoBâpÙßÞš.ì•‚øÔÐ:1¤=9ÏòQºÌ‚|æD«PÊö!Ÿê?Ôar§J31n²v‡¯Êígj@™­?ÇT "éqI#²¡Ã¡ã×D™-ýš¨å*ëð¶•(f»œ]¡#}:QèêEbnó!Í;¤‘©bºŒ!f„âƒbv›g LyÕ‹ÁÝ q¾žwS\0à‰¯»'¯}ˆù»CèZ +<76…M5F ©($V1;æ† rxà ¢Çí0&€q^“ü§Å¬Œ3 U 5ºžÛþ֓żâ¸òn¬Hf¼ú& JÖ€'¾'Ð e :ñ(|ˆW?*o®™ãïÙ¥8ÙÆIÈ`o8)lDÙ4D¢2G •A:ùÇwR¶j žhæé|9›¬VYÞÑo]BOŠBa?*t”9Ÿr6#“í”Ïï¢þOJ-  PùBư*÷Dð{CÎ ttè({–”4å:П¢$7³ó›þ«”Ûe„WÍ!tMÑŠ~£ù£ã¼Hîò¾L[ðÛR=_ü“¨íc{e1BÈ„ÎÇøè×ëdFJÆ—ÁÜÛT-¨o/ùkò¯Ù(«Z# µ¨ãN]+òÂa¨V#'+õBgpmЩª ˜“ã[Ѽ½œÏ³tlN ²—+ô°Ô 4c„.Ïsž­m‡ñjöúÇYö–³pfŠ{Êú‰ù8¬Æ¡¶VWÚ(²ÿƈP:˜Nr-U7…¹,„oÓ‚Ÿ¦“ygŽ”&‡åH¡õ!­Ã;Õ)¡ÚÂ莇¢!˜eE-³Â·L,©½t=bÄêŸÖæ®#¡aò†ƒOŒ‚ÒÍS¼£y•h :N[šçËuÉìò>›NܶSѼ3d.B}€ÜäüçÕùµ•°þîmÅo§_ìvs¨Î v6‡~žLË•¬¯»?ŽFÙ²£‹¬èw,B=„bv×Çi Y¸æ/Ûê³J”+ÐÙê!ÏÞý¤¥  “æ¶Ï~aâ˜_.B×ý/+|«=žU½©t7MmkhŠ”G±B§Ú2nË!³¿ ´ØdNS÷`¢ln#[AŽ3dÒjötþÛ‹4„b‡^:bh?B‡;µÕCTeÏ0µÄH¾Åžòɪc·¬sD¾bèŠçÑ‹^+ªé¦]³Íݶ,Ìæ©Q…€÷æÄ?´c„Î7µõ#J|GBï±}år]—JmjfÓ.e¶È¸±ƒ‹ ‹×]‹ç9J¿tS¦zÛÑtÑÕ•Í6hêË™@±>B׹Ǹp#ÆÁ½<©t:ݨ1+(Ïœ©oô…›Öù={·!tJ+<àð®½ôÚKYnÑÙ‘ë´#ŠKPº¹Uk}-ò¡8Lî(»·¦C‹ýÃø²<]fï¦=R py½Éч t¤IòB럴DŽs{7ü2°?ÿùÛL,endstream endobj 481 0 obj 2018 endobj 484 0 obj <> stream xœí]Ë–›8Ý{æ#Xf­è´Ìœ3ÛyäøL:Ìøc{’ùûAà‡©Ûƒ€:^¸ÏEZÔÕ-•ŠÒ.ˆDØ|NßÉz¶›í"Rbç¯dý:Ÿ½ÿHX 5‰æŸgÕH$ˆD”G1cHÓh¾ž½û÷—ùß³'&8â*z¢ )Í—³wË<ûôi•š£ï?ò8¶ÏÆR˜É⌦%2mÂTcQ‡ W!*5Žû¾‰@´ 9þíÔä±F”êSÊKêÒX¢˜GO„!Zâ›­Á AJ¨ó%_a3Vu6ssË:m‚ÐTø*äè{ukP“§ ‰‚@ÊËT\‰ì>=äéb飥¦M‘›hÀЬ°òªâ>_“Ù‚»¥ÎÒ‚¦1;5þ–g·ÊÒ1,xßO !ñD¡¸«‘¢š¼¦»FtÓÜ-»QÁƒèŽ!0~€\ÐÌmoRâš-ÜJ\Š®‡ÍI`3p Ø¬¹Í§9ñWs”cÄ=_g»wrœÄbEBè·Þ! êÔ ‚Ê ÉkP¹ÅÊk¨ÊqLwK¦Ö…ÖÇTŠS;“h|£d'k=¼¸ÏsÄÈ'—­¤1Âò`ò3P‘&§òLè+ÔíVoBby CYÔÄÕ·ê'A¤¥Ÿ·å]½êêÚ  `|“?l>áM·Ÿ¿:YJ ±d}÷õðŸ.@½•Ë·I¸›ñW[ºÿó*õ2žÙXÛí2˜ÐTó{­,ÙMNŒgÅôXRÛAg¨\B¦)|‰zÍ $‘æ?Í×Ùf±28+¦í×ÜèI’îÝÎ<3Á°æÒT0½P0P?6Ñ ínb"¶26®Ò+µ´´÷ŸêlL]Å=ýÏ­ÆD#Aãc\‡…:IÑŠíe`ËٮǒUºÈé÷ƒ“åܼ£@T}?|:~è[³kÜË3 Þ§‡ä˜ï·î„+n4zô´œ°åôpZ–9͗˵yyÖK?+™Y8jÎ5á…ÝB0ò žÎªàíµ ½2»^äÏÙÆ=QâŠsÑq„€˜@ ;Ù'z…fšlWeÒ$O6’Å4_ž Œê$ÓØP㼎R‘®h##Âã’š6OŒ+Ä•Žž¨F˜—-Ï‹0”±³ä}ȳ×uzÈ’/eí, #©h- #FB`×!ÎZP—­î|z¸‰‡ÜDÓD‹?‰¸š±v™úÃ1’Bb"?™1"'C¶V?®Ó¼²bÎâ—µÃ?ÊåâZúúvKš/ÙÖã2$£N1|4ZìD´º:M¥*w¬øå×NÓ79w*näÜM4À1J(dzÿXÎó0¾¾ ¸Ì~Jót“¸Ëªp3BŒ~½a@Œ>ýBÝ/³˜i‡FÖÙÆ qá³^”÷øÒkg(ÉDåy  ýiq z±†¨Wv¿æUQ‰ˆ¼$Ó-‰;§˜ÒNó€`”éH†o¢n- MÞJšwÇí!KKyfiy )¹É+kuYïÜPï  ñ@÷šðÆVŸ[§ëE¶ñU'I ÓÝp ކ¦ ±½éuו÷ËkEô«­“•” }×÷?Á ò˜\7ܽÎõ×8nѹÕ*TU°•›îó…™[íX!Cð„ =¢Ò¨=,ÔË€oÏæ ^¯Ößíž8`°õ £“®i²Wä÷»Üœ.Ȭ›Ái‡{œ¨h`Vx¯ò,Ê*ÈÔðŠñe‚¤,ˤ^j„_Ø}^mþf¸s«Z‹s˜ q uÄ?iÃ^Z¤v(þÉO¿¿¡ <#€ú‡Fi…]oÜåõñWÛg‚”§iÕÜ_ÏÎ0 ­ÏÀÆ º×[ï6½!¹ÕÆ-è¦Ý99I1¢ Š0ŒNê$ë…ZY/>%~ð ôh0„Wv¹xFKÂ[ÛŽV„ç¨> stream xœí]ËrÛ6ÝkúZ¦ #xƒØ¦ãfÑ´i<šét©È´¥V–lZ®“¿/’"H‚²bëJw¼°æ¦hçžûø0Ĉ ±ý)~O!qXùkr7ü0¼¿"Ì HcM†£›Aþd¨ñP1†4Žîïþ›ý<úgÀˆD‰NÌñÑõà݇˫ß.?]þmH°¢ª8òéóÇÏn¼@ZHV  ^0.‘jxAJwè6KÇ«4KžÆó{;èýWÊ¿,)‘P )N…ì¨ÔXÕ!Â5‚Çñ¸9ô¨IOÖ¸¤ £9£E’/CÔá1{€r”`Uòïj¼¸^ÞYœ3¤//ð'6âjðWÇjĽGšfAjUÓHî9@Ñ@°:¾ñ%6I— å )HG•DŠjÇ:œËX¶fX‹$L#¥øÑ@§3×OÚ<šÌ~,˜Ê*¦Öô1K7PÕ¸§ZÐÆÅD¡g0©Ú7ô²‚ÚY¨XAí_ñ:/Ûʈ¯ q{¨î¸þ™Íň+Yžde!…T¢±, _-$kò2»¯V³Åm˜êVÙIRÿg˜wF @Ñ¢O¡`l›‹Â¤$—§‘RKO#o u‚¤1äÔdՉ힫ÇÐNRDÊOµµ¶Ì‰¶Ô~˜9Y%F‡“5ø<{LÝP†¶ÖßÏ÷ÅH]åe[½š-á<‘ ¥_ ü<7h'4£4iJ­|öëleBÍ0!ˆáN3't¦„ˆ¢Fí'ǫ짦jºÌ÷DÓ°y™ÉLmà(îy÷  h °(¡|P®Kvó&»+±þÖÁo†Ï¡€“ c37èj§°?Ü¢óZ¬ËU›%›õiÊí@šíl?Ng7a6Sĉi3˜€Ž¯Í¯)õšX¾èiÏ7°Y HGq‡:Iè\Œë+²Ü[Ëu9$g¸#‡„#Æ%µc.OOôðÂh³9dG–å&ÊXi>-og“ñÜ}±ýfVö]äÅ%JHXY†j—dí …ë©Ý…„ÀõzSâl¯£ö|úþ_D3Ò«=WB‘ðšDhBy!H¹²‹DœçÞbGÍ…bDâlV?£PÌЛfá~ôFcàéM¾ˆÌy”¢Ö;Ø‘¸%a’¾ôè÷ “…ÎØ˜ïÆlå‡ú'ò킟6êÊë—6hn"@@ÒÓ‚v@ø|qOïÁ¸SââNœ‡Ò¬Ç³ñýt6 ‡’R𝑵¥æ 1‚iR‡¢  à"zx›£^†¤ª¢^bÃà I¡ý¨W"RLv¯§wd!‰4_w+>e«yÞÑ+®š–~_ÚüJP-™±–¤™“ ,”‰ÆÜ€õh´ÿöL׫£ox…ͳc!FB¯ûêÇY8sküØ”BûÉ6ÕÌŠºdÓ×ñÄ"F@éZiÿ 7¯—ÀL(:¨g³p_ùåÄ«ÿ(Ÿ«õ<íèW0î·Íz}gû Á>iè`>{cýg{<Ín§NùÙ×7£hoZX[‰ 3 þCÇ™…©,'çý ÒcºÊ—ºkã¬u~Ù±"A¬µOi. l@û“ùvNúž}7¿¿}’™ÏžxM/0 Ó3ÊûêDö(´ù]¸ì–àa~c¤Z;Yc‡à õÚå·”t{€P?;Öx…d{:Á lÓ^ Ý¯Þ ûÓt|ݵ÷« (¡ÕQܦþBÀ€>@;¡amÙ)ž.ïÒ ÿLp-4l# ؘ7Bûò´q‡§]+‹³IÞygLŒíj0y:>´ëYx ›vFÀ{ÝXájKäÞ‰ôæ¾s¦ü­?¾<¥Ù,íØLZ!ã<ô·û èÌñN\bí­‰(èâ4Ó¥ÒÌûœþËõºÊÉ%}^¼ÍÃ茡ŽY¸·r,«á=Pï ÿ6éÚIšØÎ2ŒOƒ·¢og‚±rˆò~&ì;þ ! üÙ~Sõ‰/Ÿ|ü “ ×C;àé¶ÎøjihDIBÊl—[›­¨òWãì:¦S†˜Œë>Ù¬m2¹Z¯ÑfsÑý5Éž®*Å ý«|ò4È]e-Dóê¢Øô$§@=„^ænÇ»‰7fÊê/ïÞP\r/c{eq©ØØÄدËÑÍ×NññßÚæŸÛbZžõ—¼0Eìnbë/_eËyЖÉÖRðhž"Ž7C‡X§Äq¥kÌ—µ©›²D ^MÅçÕzÞ·k¤ÑääcÌ~C@ˆ¨äe€•µ6ãéì:Ý@Ba]Ph3>gèŒ9¾ë]_Û,̵q2OÇ‹ ÿìÛ„ds ï?€€Þãò›|ß&¿³ÇI–¦a– ŠX "=úc‰â"ê)´›—çnAÂz&Æ'a}ó«çl|ߥ²ªUéQØ P”Ð6oàÜJeïD>Ák•“ç2/JíÖ¢¼–ç çëÍΧÊù“ƒÀˆE%ׯas}¯JNZl.äú&]L:ß½æÞÙ æ"@QB,ÅÛüŽ]Ÿá~TüÓ¼£ ÉãåÚÛX!0D”ð?lw; ?(w6àr4ü2°?ÿXX:endstream endobj 489 0 obj 1973 endobj 492 0 obj <> stream xœíMsâ8†ïü gÑèÛÒu¶ö¸U;STí™!Î ³™­ýõ+ÙÆ–±lÊ ºrHêÅvˆéG¯ºÕV^ŒH‚íWõ}þMÊH"ŒFy’2†4M¦Ï“o‹ÅoÓ“Æâ*y  )•L'–³¯ö‘â)5§[1[Zí㞦­ë›Ëjµ?Ùc"\c D¥ÆéµßH÷$r†<'z¤Ö‰‡ükÄœC8)§©D)OC´Ð·Ù¿ÛÍ<ϲ•r‘XSo¤Û‘΢ÐF!¦;‡t)Ä¥ñ>í–Ë ¹D¼ƒa0w¤È¤øÇÎcfx‚?*ƒ`s!—LªƒÜ¼,ƒI ᎀtOñqž@H;Vþ¸É,ƒ»ÕÜÀ™™ÚUôÝ‹¥ê{ÓAÜLâ—‚D.E¦2à~Êé’é¦yö”g?‚Œ#-˜#HAbªtFÚM:µs¡>vWë!z¹@ZÕ&[ýfL¹I ½Aè9ñHI¶ä’Š$u'»qû åHá”UGO­$-ؤRvùv™ZTžÆ4[="A×k8/Vk+3‚XsìO+“ÁÒúªŸwY¾È6~GOͼüÐÑCî%TÃ#ÁŸäÕaÏ;bn¡å{ D Îë¨ÿ¹zñF¢‰nç¨À#¤¥È†q’À“`v/äÂ,H«bS”LŸ ¦9CZÐýe3/ÒÆÍ|3’~"”‚AzüÕ‹.†Õò~1I¬(4žÉŽRÈŽ™Â`>c‚’.S$5?bY§N…EBÇ\ %ö•vB÷—•R{~]e-— ‚²A°Iç°ªÓ¹O³b!„¤ˆ«ú‚ÿ|Ë×»òhn¼TÕ‰ÚïëòºáfμÍ×=}}Æáµ<˜ZV1 CãT-Nr÷BÝŒ®š¹›,:`öÇfU‚R„™¬ë+(š ¦ŠDý™€ÒyQx©¤rÊ$.ºU’ö£[¸F‚Õî´ó—gŒ…ÖžErû"¾új  Årï‘*¹õËlQ`ψ!šïßàÖK½™š¡E]û~ƒã_ÒåVó#QM†É;ðØu–Ï6þ*HªXòâ–¸à¤w\+1LyÐåGm7ÏÞ¬L…»ZŸå=8t§d8»w!ªµêOȶª¶TÔ°e«ùz¹Îý.+í¸,ÄH·7ŒÒ´ÚjŽ p¶Ì¶[¿r‰4;|P’© O ´7']¦b¬ZSIÌÎ3Z^ƒÜ,þëÉB1JSÄ 0 VïZΞKÑo˜>*_fÆCó•ßES$%<û˜D#]Êùn4º„1>/[„"¬{€­ $ 98é]¦¶ýúµl¸£QÂ÷¹¤Óp×µPƒ9‡‡Ÿàh¤: ŒÿuýÒ×+ ˜Îi‡|<Ñ61]rU ¤ëK=çζÃNQêTO‡”ZžÙêÛóD§%žè ¤eŒ ¤æ²;M:sÙã½åbT¸ùkßb Idkï=H0~'2o®ÉʺC&;Ð`âß| H€t9T='v‹H¬‡^·ˆ4Ôµ`@ÅF!èZ€Ñ¤ ³Ûï¼üØœ¹·­j“C[H0ÔýŠ4þFcš‡¦Ñ^”Í9‚µ7‡ ݨ£·˜«t‰@šúvPé.èbØÍ¤Û'/ÕX!ÝÆŠ’Bw%¸Þê6µ/µ—‚73«iÄX³õÛbõ­8Òn%Xר½{Ý.׳Çêh¦ÜÄúe1ßîòžÅc÷jvG )."’B¶úwÙ,mìÆD¸ÓBä éòWØ:OÝñ`CÔžT ÅÁ²oÜ%¢ƒ¤Ð¥K-¢¶fέ ÒZL/ªÆIxzè$q{Üï¤à¤ãôR§°ÕÖó¢Ti娛^P½» s‹@‚QìúÒ¥Š4ÔMKv„²ïVö…vrøçzWù@ëñ`_°º‡>îmd¥óˆRöšºóÝg ]±lÂ$"Í3Ûk?p„x6‘‡e“ÛÀEÅùF#õ`ËmÕöºÆn»]÷´Ø›Ä4žßÁR€zrbZ“ª:¤V¦ ¨ñ¾@ŠAz?Tÿ˜&Ÿ'öë#-Çendstream endobj 493 0 obj 1623 endobj 496 0 obj <> stream xœí]KoÛF¾ ý:¦O÷ý¸5Š¢)ò€‘¢GER\5zE–ƒæßwù’–ä®eǤµ’>Xø¸”(j¾ùfgg‡_‡èdåÿñbðuðuHs¬ú7^ _ß ~ù@¹CÀK‡7ŸÅ thÉPs– oƒWßf³ÙÏ7ÿ8U`´r#n&ƒW¯¯?üqýæúï숒@4Óå‘7o{›—`¥â%*Af ûH5¤¸P,ûÈ+Aµû|9¼bŒÉ‡êl À8·åÙe•À%©Þpµùr·§ù( F–þ-G·ÓÅt™1$—¦<´-.A¨Ú5P „¹—ÅÈÆhœì¾Q’ò¥G¥r¼}žð¡æí~ê'¬7 <±õ)_ðÏ÷óy”ö\•Lã‡:‡ÔWø]c/ݳ—YO°Ç«uv„J°l—¯ú>™~«8¢›*žÌDè<qÚP?bœ-EØ]’º¤3§Ì±Üc³–¨§¤?fjösƒÑf6ú4/2ÒÒåÕÚÉÃiaA·2ÒÉÜø£CH³Ó’H Òq¢2}O"•Õ~„»}É5Ò‚Ù¯é„sV ˜S]\³¹à¯PÂ2j€‡)_Oc-G‹0¿™i1Fýa¢ü&‘YoÉïRÒçùb´Í ­¼Áx4rž* JÿÐ 5B'!OÓví0^“}Ìís^x’a|Ûsçä®.+¬ýõØ!µ‰Ò¹3¨Ÿù¶{I¥QYLœ·ÿÌ–·A ²l~Ý, I殡]#t*ЋL¯=†ûR|;_}ŠÄÚœ€ä-ý,!üÓ&x;°¦~`]°9°æÄ³­mùº2ã~¾lºÉ«DÜ;ø‹ÍT”—U_ãÍìn{¤s%}h£½053“ XôÓ+4­7ÄÓ^e•]¯×%7ƒâÛ —È—»šó"¹:>ÔµöJ7 ®ùŽÎõ•ªÛ‡ØLΕO B™ôÙ°pŽzW¾Õfs)Λé"JhAAÞÐâT÷C%!—. ꀪäÃT-„w=w“Ô Om…Ñ Ý!äB' õ3wÖ ý¼uÁù<ÓEl-Õ%²#õTWѦ¶´å7€Ô¾Í»Ít2¶ÓpzK2:´ƒ‰ŒP?ò81Üßc·në)¢‹ZýÌRÙû¦V/Uô¾‰LQ-(ÑŒh“¹™¡{8&3Ÿ<‡,ÓÍl1Ûξe‡¹ñÛŸEXèΤÚÐîBÈÕS$&³ÝéfÍíx»ðòOévé!¤å‰CÝçvDDB³í?‘ˆUô\€rëü ¨Û(ö¨[«FÊÓ²aî27Û´ÍÚB´2„’„’1¹¾ÊjÕJ½ÚÂ2fÖEoîgd\ßßO7³HºÕMÁüB/MÙ¾úY0ó«'‘µFÌ㢻K½åÓ¶hJO]|ëaÚ¸—‚6[6ãÞ8„’åÛIJ¤qSÍ–D¶ÓJŸî¾MÂúFA7vÓ³JÉÜH„.JÆäºáî£èì¿Q›Îeå‹b£l¦¸7¡D8Î$ïöÆEØ|·®‹}p̾?Bp|“V\ÌMCº!t|¨ê62ÉrOÝz-þåL‘t’†úè Î zÁÙ±%ÀKñ¸ò¦H¶Šk©*ZBLJNe'jm©¦ÅËR.³¢‰ˆ.R÷M±h¡gBÝ—@µ£_¯Ž"ÒƒEoå¡’¹EtÁu#ÿ1€>ÃË'ÿx‚ÝÄ*(ŽîB;F¨KúH#Çæ¼óøfs Š_ŒÑø:>Ôµvno‹z@Œ †6³¢5¢IU5ü{òÁ>ä—@ÀKøŽ¥-àgl·óe¿USÓ«ð»X]¢`ä.;=‰å°; ArÉ:¿â÷AI·`ü2ë‚ßùÖNkÍbò#ÏØºðûò®(!`ø¾‰ò8ú|Î@½gB¿B'¿Gð¥hÃF÷˜ì€Êµ³z»UÐÊMŒÛIÜ0„PæÎêþ©]ž[¨¯C¼ÂhyPŸÂñáœç ¡c8ÊÓåÅƯ£Ób!pZŒ\Cè™P_’k¯[ÿ@è¿DÊ#å:;Ê? òóH½º_+/·U „n- Ê766{”E>¬ñŒm6¤EÂ#„ž"·l=ôc¢v †ù!GÓÔüÆ#!žÂøp+e`.²÷R¡¾¡~ê`}ž”Ý‹u`Ê~:ºóúšýû3si²1×7Ã÷ƒìïé 7endstream endobj 497 0 obj 1903 endobj 500 0 obj <> stream xœíË’â6@÷T>ÂËÉ¢5zYm¦æ2EUÖ íÌðè&•äë#ld[âdûV/š:¶ŽîÕ“÷#’`ûwü?_MÞ'ï ÉYño¾J~™N>~!̤±&Éô÷Éá$I C”'’1¤i2]M>,þþyúÇä…)‰˜H^(CJ%Ó×ɉ¤=B9RX2ój ³Èœ—(MŽh³ýs÷6›göçHH*G>mÖùÓ5¼<Ã~»YZúñ —²ò5"©(ž†ìsRD…ƲŠ×8¨ÃbB›Èsú ªgJ3Ö¸(ΩÊ-£R i^÷b5ÌdÛÙ.óú@S$hÊc¸€õ¸z>„GðKÎ×WH™/¨=‚óÜo¬ Á—þ€G â Á£¹h1"¸8€ºü ç¥}ä êTW‚úÛ.¤<–õÓH.#Ø(:ô¿JáC3Ì3¥±¸æ× < @Ï.…P¾ òË€òö=ê‰}›Êƒ¦€úää“ûf×w[î:ä÷Úk7ˆcY{ÏX: èÊ4 Î…¿¢PVÙ` P&õo®;ŒXc¬*š‹8tÞŽ µÔÆãÔ… ÿõÇö¿ñiÆG ^è)jEoÐ;%nH/§Äú\´ÑCCtæuRÔsýh. ž¡AVP]µÑ©Ó¤>®×³•MŠgTŽàŠ=§Èµ2…MyÛÈ‚: þXÛ„ •ªâ=ÏeѬ–Eó|H]<û& ² ê!ºCÜ+òc…´3¦%ðÉæj~|Nç«sfÌ¡<uÏsQ+#Ò©ÓºuíåW„â`†Ì5Òi5CG8±ö­w»Æ³ßSÒ"{}óêÅ´y6—Æ‚FlÜ#³ÝÆÚFŒX9›Ã“Ù‚ã~{\£è›®•âÁ¯ÃÜ;²Eγ~ñö©Ê9Q3ù=Ór=#=GR]±º´ô|ô€RØN·“5uvOjËææ†òj”‚¼zÌªå ¨«5ÏnG® ~wwûÌ/.5aÚ$”`@O©ùø k¡šÆ—ÉwPzf2mÆ£¸ 3 (Q7c¾Õ}º\w+=cÖÜ\]šš–vÙ&eßD#ÑßæJŽAÕÓ;yý³—‹ÄØcj± éu±÷J ’†‚ÀæèP7ѹ6ÂhK[ãZúû°Mf­ï_†Rèùh3£ ™ÜøÏN²ü€ó Ë ØQ+v§nŸWÃï2íòÇgâ®{cE` 8Š\ #Ðæ!§~1ÇïJ¿XöÚÒü¨¿~Ÿxh?aç]îàj±±¢VvïW´¿×^·‰†==Æ„ Rè½îµá1Öè…ñ¡íúˆÝv6ä4M‘ëj¿÷)®ò•>¸ÝÌЈ1EŠ¡´¿oaç­9‚üLä{ ©î®k4÷ЈѰPgëîfµ@oª˜`Dµª}2wlL7Ð`Ñ £G+[30çDÁÔ`¹™½zý6­¢»œ+7È(fÔçŸçð [[‡°?ß-wAëíf,i}7Ð(îÝ ‹ ØQgkN>½ñ@pþž-KD¡«ÐÀP4Eî!]u åmòloç²o¶^í95’“»âF|×õÝ•Z»}c^U%’îÌVGÕÊïWW—‹¯Ë=Ì8"¤Ì›ç^{…ßeG:x ¨Oèr m¨zU ­l„Ö´·Ëö‡¦pî¯BüYýþJ›³÷ÅßÁ!¸ÐÑ¡ö{©Ï„ZÛ>¸ZÍ‚ý®ªÐŒâÂ9€ži¡ç…vEIObòZÝg«BL;U䂘iå6 „ Á}¼E¹ëô½°¹`CÌCÀüæ·DX}ÒÜ5pP¿ÃµÌ¦œû¨ ×»ìÛ*[ç§Åˆ“²y½ß-þ lNÍû×—y¥½þý³§èS(M˜­¦¿Ÿ§É¯û÷>èendstream endobj 501 0 obj 1453 endobj 504 0 obj <> stream xœí]KsÛ6¾«ù:¦oñ~\Óñt:ÍL¦©.½•‘éD­l*•4ÿ¾|‹I)‰”v|°ç#DÒÐ~û-€Åâó”’ì§ü=š|ž|žÒ«~ÍŸ¦of“ŸÞSž"`‰¥ÓÙã¤øZ2ÕœƒeÓÙÓäõ¿?Îþžpª²féåÙÃäõ›û÷¿Ý¿½ÿ3»¢$Ítyåí»_Þåí%X©x‰J˜>OM©.Ëžw'¨ËÍôŽq0&oj²†Lã¼zÚÏÑs &m\€I-ó0”‰ý#‰7ód‡ëâyBµ¨%()«[@ÖFƒà¤~}?$e­N|ûñ¿ª<ðÁ]C¢ 4%•µ)]¶i÷'TjÓw©) QÐÒÜ Ñ¼mnÔ5X™[jRZ·8“ÞÃÖ†ž¿¦,Ñmˆ K$BØ9y ‡M°£ ]×Т½Éí­’’Â5Ü1­@™º,¿ožÝô¶ ¶®Ù€ÐUB—±ÂÓ0Þ‚m4i0^Kš3ž˜Šòiœ¸Y&Nâ FÑV¨(²‹D ´3Bè”Vødí2S¸µX‹¦‡«ìMJW÷ 7MÓVæ¤ú<þ/!„939ÑmÕ[¬]ò»ÞÇ(¿d×XJy&«× c7Ã)XmèzíÚ!ô<#…NHë4ÞmϪ)×ó¨O3„«Êµ¸%\ƒ`–˜!ôãUAÈæ‘B‡xzuÓ?©±•h:ÆÀwNFZàÜЫ ª:„ï*ºa[¯`v½ŒÏár:=“ÀµÀoÍ¡³‹üQ§dK7ÎlC÷“pí™N³`q5!t‘ƒõ]ÊóÆöˆzo<¢®@Ù]QLºa#Fè´¢®óu烢¾ø!ð†í©¬sdø-CèŸzÎ6_'ÑÊÍe œ*ÇjÝ ú¡!Cè^Èåã4½».Þ¼‘²»”/ô;Ú$«{XÎØÎ´~å:ƒžj <ëúqMê¶ÒæA2Ï.QÚÖâüÉIfçzwŸ„”GèòÐh)oZMºj]èɧ8Ê)oAmS\¾:)Ÿþ)…Å6ôN½ êeÂ\ší6¯¤‡q¹3R³Ep#q>]Êõ@½œ±* ]|¯‚²\“ï£7"Bèûö÷ÿO–77s6ÙÜ—5$X¶­Ù°(@Ö=kài#ÙÙe2ä¾Eè:82Tè4KÙdc)»+ΛóA´n™ƒ…'_ƒÞî:Á¯!t—”oÇ».€4fÔ5Ýue|þ¡¸Þú€oÂÍv‹©[ËïíÑ«ã…Cõ*ì߯Öt ­0ž‚ì Õ@·ý·ÜU¤<£¦.±o1Ý#üp—AÈÌëú ¼Ðþj ΕJü1J"'‘ŠL´Í"ÜS" !tŸóíTònð]n >: OPm#„ŽhLnáÀœ¹}Àâãs»Ç×YÉíïÜ/††Ðå¡ÁXa/¹åºq£.›Ë þ/'“eî n°ôÒ`,¡†Ž·Â^…iTyôÉþ£'ç¦o{euV‡ ¡oBèD> (S±Ø,KÞ>"|–A*ÛšZ §Õ2H»iûMë:ìÿ5 ã Y»T»Sê´¡7¸ uЋüÕi"×ôO¢¶ƒÕ­Ž)«›B¬VËon%˨‚SÉc4)„F¥QÇѹ9÷¤j:ïœì•+Í·Âò¥xDseôO†¥÷Ô[­r`³å¤Nªnö@–"´:U wklÚp;¹\a—%e”¬3¶ÝeI»¦oÁ¬oáDhÀ’nÀîes ?ÞdgWÖ`ºì!t(#…Îv @± ³^MòÏ›2< J< ¾Ç|¢r¡ËÇÞžÄÌóÆ¢¹¢ËÝR®_-“Ð[?˜Üdj&’¡Ë v‡ôn†×…Q:'tâüÊ·îK@í씹ÜãDÙÈ tWƒƒÎqjv“ð­p<6sO8ž%yŽ8*„¼jèçåvõ»ÊÜŠ£õÚ7©&$ØÑìrD^"4ÀPÛy.G½rí?Jo=<2›6V»¥;чá74 V'³Î¢aê¶µ n‘1é”ÔN–ãˆ2HЊº4S÷/_=Ï8x^?zf£¹£{‹t‘$]êÛ ûÙ3LT¥ QïgÓß'ÙÏVcËendstream endobj 505 0 obj 1830 endobj 508 0 obj <> stream xœí[K“£6¾ûWpÜÜQë­k’9ì!©<\©\YÃLHa<ƒíÚM~}$6`1³5ëÝ[åÔGÚrúšVë)"€qŸæ¸Þ,žOVX{Xo¢V‹ïGf0Ä`´º_Ô_ÀH Ê#Å­6‹wŸ²ïVÿ8{!Æ%uöKN+Ã¥=h­’Å;ãì(ʘ±÷rÐÏñºÜîêïsÙ»  •!8œª^„„˜¦UpâœF:R@$¬1Ѭ±é±gI‚RÑ%p^ßkãb¿ }{©cÍÃ{¡/¹! ÐE * QoíÄAïégAC.÷xj@ÓÓãj.[îJP-y­¢ÕßMÒûqúrŒ žÂ(Ý 4ÿОô¿^ÍÕ!1•;#-§´8“W¼$uŠY‘òÑ/ª».Q ¡ ·§³‹BþwuϤËÝž¨•›[‹Ö>ýô‰ŸÒ )MèDóª 0Õ|-èâh@hCd`gõÆ5J£¥¥©_A‘8KFí¿«Z7îÊr[:˜3P'‡m¨)­7Gj®ÓÝ.+nöË7Ü€1²—Ϫ80#W¿Ãù½_A;“Ÿ Ê¢KF(ìU@ìe¬ÐdÃìËÀUüY±B·dHÒ¶tØ×´ŠC”‡E“ ü BA=&­¦s£#}ÏÕƒKU©‡½TÑÏÕãêÝËò+‚m·Îâ¼2µo`­HýYÙY'PµÄË,þ§#«–ÒŠ²îï˜Ý$z Nð¬Î´ƒÛ4á¤Æ«®x®‘wµ#ÎóZ$0#Û§~|H÷»tïæÒ&»Î„y/@× ÀE¡9·z¡n:7ªyé©·­ã]š=Û2MüU7Iݳp £2E(L3…^Q);/‹ 2”¾.ÅêªXZ–ñzDÑгeâQz{hfQx6»bÅgæý!Ïˬp—aŽéñÞ/ H=ÐPãÐõ±ð*¯¤mBÜeªO›oã¤Øf»,ÿ×KLaßIù<Æ{ª~h¦ÐªŽXwÍjŒ…­V¢Ç:Ï>I÷çÙ&ógÆBºžã Tày€¾‚€ÙS"} ÖË5G¸ã æúÛ¤òc–u‚}8”U•†"<¦ºÛ"MF’ZF]Ùn€ÝÚÔs‘e ÕY„ìR®éÍoäò°Kã|Ÿ–E¼O‹x3Òx©µ'žÙ ¾9Æë cüµi#¦þú^$uvýÈ÷µ>qxÜZ3'ÛqžýW4ü‘ƒ­äÒÊÒ ­Î ¡ƒ>ún0œÞæsê}7UK¬ ‚³hi£nW|ÿËOwyÿrÁÁpœÜï N'.ÔáÛÛbªÍIw«è·…ûü´A”µendstream endobj 509 0 obj 1123 endobj 512 0 obj <> stream xœ5‹= Ã0 Dwý é¢J1²ã5`24´tN)¤àÁ[~ã|pÃÁ{w™¹æì%C‚²³«–Œ½Á}·ŠíÇA02ç(¶hšßºÞì N> /Contents 6 0 R >> endobj 19 0 obj <> /Contents 20 0 R >> endobj 38 0 obj <> /Contents 39 0 R >> endobj 42 0 obj <> /Contents 43 0 R >> endobj 46 0 obj <> /Contents 47 0 R >> endobj 50 0 obj <> /Contents 51 0 R >> endobj 54 0 obj <> /Contents 55 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 62 0 obj <> /Contents 63 0 R >> endobj 66 0 obj <> /Contents 67 0 R >> endobj 73 0 obj <> /Contents 74 0 R >> endobj 77 0 obj <> /Contents 78 0 R >> endobj 81 0 obj <> /Contents 82 0 R >> endobj 85 0 obj <> /Contents 86 0 R >> endobj 89 0 obj <> /Contents 90 0 R >> endobj 93 0 obj <> /Contents 94 0 R >> endobj 97 0 obj <> /Contents 98 0 R >> endobj 101 0 obj <> /Contents 102 0 R >> endobj 105 0 obj <> /Contents 106 0 R >> endobj 109 0 obj <> /Contents 110 0 R >> endobj 113 0 obj <> /Contents 114 0 R >> endobj 117 0 obj <> /Contents 118 0 R >> endobj 121 0 obj <> /Contents 122 0 R >> endobj 125 0 obj <> /Contents 126 0 R >> endobj 129 0 obj <> /Contents 130 0 R >> endobj 133 0 obj <> /Contents 134 0 R >> endobj 137 0 obj <> /Contents 138 0 R >> endobj 141 0 obj <> /Contents 142 0 R >> endobj 145 0 obj <> /Contents 146 0 R >> endobj 149 0 obj <> /Contents 150 0 R >> endobj 153 0 obj <> /Contents 154 0 R >> endobj 157 0 obj <> /Contents 158 0 R >> endobj 161 0 obj <> /Contents 162 0 R >> endobj 165 0 obj <> /Contents 166 0 R >> endobj 169 0 obj <> /Contents 170 0 R >> endobj 173 0 obj <> /Contents 174 0 R >> endobj 177 0 obj <> /Contents 178 0 R >> endobj 181 0 obj <> /Contents 182 0 R >> endobj 185 0 obj <> /Contents 186 0 R >> endobj 189 0 obj <> /Contents 190 0 R >> endobj 193 0 obj <> /Contents 194 0 R >> endobj 197 0 obj <> /Contents 198 0 R >> endobj 201 0 obj <> /Contents 202 0 R >> endobj 205 0 obj <> /Contents 206 0 R >> endobj 209 0 obj <> /Contents 210 0 R >> endobj 213 0 obj <> /Contents 214 0 R >> endobj 217 0 obj <> /Contents 218 0 R >> endobj 221 0 obj <> /Contents 222 0 R >> endobj 225 0 obj <> /Contents 226 0 R >> endobj 229 0 obj <> /Contents 230 0 R >> endobj 233 0 obj <> /Contents 234 0 R >> endobj 237 0 obj <> /Contents 238 0 R >> endobj 241 0 obj <> /Contents 242 0 R >> endobj 245 0 obj <> /Contents 246 0 R >> endobj 249 0 obj <> /Contents 250 0 R >> endobj 253 0 obj <> /Contents 254 0 R >> endobj 257 0 obj <> /Contents 258 0 R >> endobj 261 0 obj <> /Contents 262 0 R >> endobj 265 0 obj <> /Contents 266 0 R >> endobj 269 0 obj <> /Contents 270 0 R >> endobj 273 0 obj <> /Contents 274 0 R >> endobj 277 0 obj <> /Contents 278 0 R >> endobj 281 0 obj <> /Contents 282 0 R >> endobj 285 0 obj <> /Contents 286 0 R >> endobj 289 0 obj <> /Contents 290 0 R >> endobj 293 0 obj <> /Contents 294 0 R >> endobj 297 0 obj <> /Contents 298 0 R >> endobj 301 0 obj <> /Contents 302 0 R >> endobj 305 0 obj <> /Contents 306 0 R >> endobj 309 0 obj <> /Contents 310 0 R >> endobj 313 0 obj <> /Contents 314 0 R >> endobj 323 0 obj <> /Contents 324 0 R >> endobj 327 0 obj <> /Contents 328 0 R >> endobj 331 0 obj <> /Contents 332 0 R >> endobj 335 0 obj <> /Contents 336 0 R >> endobj 339 0 obj <> /Contents 340 0 R >> endobj 343 0 obj <> /Contents 344 0 R >> endobj 347 0 obj <> /Contents 348 0 R >> endobj 351 0 obj <> /Contents 352 0 R >> endobj 355 0 obj <> /Contents 356 0 R >> endobj 365 0 obj <> /Contents 366 0 R >> endobj 369 0 obj <> /Contents 370 0 R >> endobj 373 0 obj <> /Contents 374 0 R >> endobj 377 0 obj <> /Contents 378 0 R >> endobj 381 0 obj <> /Contents 382 0 R >> endobj 385 0 obj <> /Contents 386 0 R >> endobj 389 0 obj <> /Contents 390 0 R >> endobj 393 0 obj <> /Contents 394 0 R >> endobj 397 0 obj <> /Contents 398 0 R >> endobj 401 0 obj <> /Contents 402 0 R >> endobj 405 0 obj <> /Contents 406 0 R >> endobj 409 0 obj <> /Contents 410 0 R >> endobj 413 0 obj <> /Contents 414 0 R >> endobj 417 0 obj <> /Contents 418 0 R >> endobj 421 0 obj <> /Contents 422 0 R >> endobj 425 0 obj <> /Contents 426 0 R >> endobj 438 0 obj <> /Contents 439 0 R >> endobj 442 0 obj <> /Contents 443 0 R >> endobj 446 0 obj <> /Contents 447 0 R >> endobj 450 0 obj <> /Contents 451 0 R >> endobj 454 0 obj <> /Contents 455 0 R >> endobj 461 0 obj <> /Contents 462 0 R >> endobj 468 0 obj <> /Contents 469 0 R >> endobj 472 0 obj <> /Contents 473 0 R >> endobj 479 0 obj <> /Contents 480 0 R >> endobj 483 0 obj <> /Contents 484 0 R >> endobj 487 0 obj <> /Contents 488 0 R >> endobj 491 0 obj <> /Contents 492 0 R >> endobj 495 0 obj <> /Contents 496 0 R >> endobj 499 0 obj <> /Contents 500 0 R >> endobj 503 0 obj <> /Contents 504 0 R >> endobj 507 0 obj <> /Contents 508 0 R >> endobj 511 0 obj <> /Contents 512 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R 19 0 R 38 0 R 42 0 R 46 0 R 50 0 R 54 0 R 58 0 R 62 0 R 66 0 R 73 0 R 77 0 R 81 0 R 85 0 R 89 0 R 93 0 R 97 0 R 101 0 R 105 0 R 109 0 R 113 0 R 117 0 R 121 0 R 125 0 R 129 0 R 133 0 R 137 0 R 141 0 R 145 0 R 149 0 R 153 0 R 157 0 R 161 0 R 165 0 R 169 0 R 173 0 R 177 0 R 181 0 R 185 0 R 189 0 R 193 0 R 197 0 R 201 0 R 205 0 R 209 0 R 213 0 R 217 0 R 221 0 R 225 0 R 229 0 R 233 0 R 237 0 R 241 0 R 245 0 R 249 0 R 253 0 R 257 0 R 261 0 R 265 0 R 269 0 R 273 0 R 277 0 R 281 0 R 285 0 R 289 0 R 293 0 R 297 0 R 301 0 R 305 0 R 309 0 R 313 0 R 323 0 R 327 0 R 331 0 R 335 0 R 339 0 R 343 0 R 347 0 R 351 0 R 355 0 R 365 0 R 369 0 R 373 0 R 377 0 R 381 0 R 385 0 R 389 0 R 393 0 R 397 0 R 401 0 R 405 0 R 409 0 R 413 0 R 417 0 R 421 0 R 425 0 R 438 0 R 442 0 R 446 0 R 450 0 R 454 0 R 461 0 R 468 0 R 472 0 R 479 0 R 483 0 R 487 0 R 491 0 R 495 0 R 499 0 R 503 0 R 507 0 R 511 0 R ] /Count 113 >> endobj 1 0 obj <> endobj 4 0 obj <> endobj 17 0 obj <> endobj 18 0 obj <> endobj 37 0 obj <> endobj 41 0 obj <> endobj 45 0 obj <> endobj 49 0 obj <> endobj 53 0 obj <> endobj 57 0 obj <> endobj 61 0 obj <> endobj 65 0 obj <> endobj 72 0 obj <> endobj 76 0 obj <> endobj 80 0 obj <> endobj 84 0 obj <> endobj 88 0 obj <> endobj 92 0 obj <> endobj 96 0 obj <> endobj 100 0 obj <> endobj 104 0 obj <> endobj 108 0 obj <> endobj 112 0 obj <> endobj 116 0 obj <> endobj 120 0 obj <> endobj 124 0 obj <> endobj 128 0 obj <> endobj 132 0 obj <> endobj 136 0 obj <> endobj 140 0 obj <> endobj 144 0 obj <> endobj 148 0 obj <> endobj 152 0 obj <> endobj 156 0 obj <> endobj 160 0 obj <> endobj 164 0 obj <> endobj 168 0 obj <> endobj 172 0 obj <> endobj 176 0 obj <> endobj 180 0 obj <> endobj 184 0 obj <> endobj 188 0 obj <> endobj 192 0 obj <> endobj 196 0 obj <> endobj 200 0 obj <> endobj 204 0 obj <> endobj 208 0 obj <> endobj 212 0 obj <> endobj 216 0 obj <> endobj 220 0 obj <> endobj 224 0 obj <> endobj 228 0 obj <> endobj 232 0 obj <> endobj 236 0 obj <> endobj 240 0 obj <> endobj 244 0 obj <> endobj 248 0 obj <> endobj 252 0 obj <> endobj 256 0 obj <> endobj 260 0 obj <> endobj 264 0 obj <> endobj 268 0 obj <> endobj 272 0 obj <> endobj 276 0 obj <> endobj 280 0 obj <> endobj 284 0 obj <> endobj 288 0 obj <> endobj 292 0 obj <> endobj 296 0 obj <> endobj 300 0 obj <> endobj 304 0 obj <> endobj 308 0 obj <> endobj 312 0 obj <> endobj 322 0 obj <> endobj 326 0 obj <> endobj 330 0 obj <> endobj 334 0 obj <> endobj 338 0 obj <> endobj 342 0 obj <> endobj 346 0 obj <> endobj 350 0 obj <> endobj 354 0 obj <> endobj 364 0 obj <> endobj 368 0 obj <> endobj 372 0 obj <> endobj 376 0 obj <> endobj 380 0 obj <> endobj 384 0 obj <> endobj 388 0 obj <> endobj 392 0 obj <> endobj 396 0 obj <> endobj 400 0 obj <> endobj 404 0 obj <> endobj 408 0 obj <> endobj 412 0 obj <> endobj 416 0 obj <> endobj 420 0 obj <> endobj 424 0 obj <> endobj 437 0 obj <> endobj 441 0 obj <> endobj 445 0 obj <> endobj 449 0 obj <> endobj 453 0 obj <> endobj 457 0 obj <> endobj 467 0 obj <> endobj 471 0 obj <> endobj 478 0 obj <> endobj 482 0 obj <> endobj 486 0 obj <> endobj 490 0 obj <> endobj 494 0 obj <> endobj 498 0 obj <> endobj 502 0 obj <> endobj 506 0 obj <> endobj 510 0 obj <> endobj 514 0 obj <> endobj 9 0 obj <> endobj 8 0 obj <>stream xœE“}LSWÆï¥´÷ò!¨¤›LloçÄA”¹nlB§¢‚ʇNDY (Š¥0•ÅahûZæ¬)êø¨)\ÙŒ“%̹,c:œËœŽÍiЉqsâÛæ¸[51ï_çä=ç<ïïyMùúP4M¥f|ž´H™’¸yI´wGážM»Ã|ÜsDvRæ[îÙ#î §ÌÄôøn0FO§D4½29K©/Ûiйpe·$..†K(Ñ´¹êR.Em,Ô”¨ÂBÇ¥ësµãÎ(.A§ãÒ¼'ʹ4M¹ÆP©É{þ¬R_RVaÔ¸}žÆPJQ”rbæúi«Ö¾EQ‘Ô\jµ˜Z@½I…SoP¯PÁT€ žò¥©.ú5ÚJßñ©)D¼oª¯ÑôÔ§ý¼{‚§'q–ÈâCª–Ô®¬"Ñ$ XÎ=¡¼d‹%6A> ”ÚXÕäÔ„Båþ† z*’Ï;Ñá½ ÿÄ0ÑO¢ôEÏfãnܾÿwìe2­AŽóN}~¾dÇc~#Ked#ùAŠ\Í<:Ÿ¹"OIüä$‚ü.Åó˜Å _ ¡²“µË#ÞIµpÏUâ y <´´áÈg ¿{Œ—è-PzP‚QPÇœ€“pÂ\kšE2H/ÉÃKâ1^Rl™ÐÂ(zî3h›‹I•BÅt؃ zá!t[XžÃ*ï\ÉãL½žé.Pá^ƒ ‘Çw¥XHd¸€H9™C’R€Q`™P*°@F¦Èˆt $wi†³®Ö݃«p©~¬ÿdzWFO\„ð­ª#»'Õž !Ü›¹Ò ÍPÅ+¸pKg8ðØ|ÎkÆ ˆ<›žyQI"òãI"°d1\”ÜoÌyO>€jÉòjõ"ÙlÆÅŒ皣DÊHJ±Z<õXÀ?®PyÄa”U²“³’Ç'ºø™“‚½¨x5äc÷IïD³]ÎQøš}øúI‘M‰Ÿû&é°ý'0qÁcè˜(°‡ ÄIt›Ú¶wj¡’„ÊùJ{¡ð¦µ ØíwšZjêwï°Öî¶Êë2u•zX µ#5㟠ÕþL('K­Râ‡.ጩÛa]JÞö:kL¸lâ1‹wÏäŸÁŽöưwIå%å‚ëŰVÃ:Á4TÌg ô¹†vëªÕáM)WóË/£–+ƒCß_{Øx®NSw’÷m{À¬lír,eP_![®L?—Ôž¡¤†D‘ù$Ÿä`‰@ËÈõ£CýòÓÅÃåõÀÚ¡±Ù+®ì;îåçpkÝˤ¸³n8tByf½ÅÙBôâÁà ^´[OV³VfÊŸŒŠql’gJ… „â^~!pOžÁ}ònóè/ÔnÛ¾Oë`o¨y TÈTL·í®ÊN¸¡«ŒÙ{T7y³m¦L}?á Œtþƒb{+}á Ô ú0ÊÝ,=]s ŽB; ÃH×± ƒà`€Ýdµ@]µl[ÕsºÀ-ëðÖ–ZÛ>Û>`MP½KNÎ2;ÀÜÚhÛßxHforýØqˆ|G sIp~rÓ°V>t¤¯ÍµýT~IÑέK¯Ç`FMÜÆé{‹ÌÉͪ)V ¼èX38OðqžwŒJû‹ºòòŠt99NÝ™3ή~YÉîI´“ƒ øa«„l;ÈðþHÈü}cZýN7"휶?0ˆ¢þÑ„›) endstream endobj 515 0 obj 1290 endobj 23 0 obj <> endobj 22 0 obj <>stream xœXyXTeû>ãÀœ#âÞQ©<™Š;.…dæ‚â†b‚â2ƒ" «Ã&›0È6ó̀þÉ."ŒâƒK!iYi¹äòUZúif%iŸ~ú¾—¾~ï­®úm×w½pÎ;ïr?÷s?÷sdŒUF&“ ^»Æm•û ®ó}¦NÛ1ÕYzè ¾$_î#Ž”‘ì—­"»R­¼<,z~8· Ä×1r™ÌÍÝ×5<"Neïè:Î~ª‹‹³ý¼PMÐ&u˜½‡:*Ð?TEÿ ±÷ ßä7Ù~^HˆýJé‘ö+ý#ý51þ›{wv ˆŽòר{„oöׄ1 3Å}^Ø&øðÍË]#üß^°Ås¡& 2pQTWôª%1Á!êÕ¡~Þ¯½î<ÓÅiê´é3fó ó6³€qa&3¾Œ'³™Â¼Ê¬`Ü'f4³ˆ™ÊŒa¼˜ÅÌ*f ãȼÃ,ef0«™×˜ñŒ7ãÎx0ógf9ãÊÌd†1ÙŒó"3˜ e^`xƉâÅXÑIïÉFɲúLèsR>T!ÿ»UœU·u¨õŠÅŠJÅ/ìjögË]ëß÷ŽMŠÍ™~ƒûµÙÚÚ®µ-³íî_ÔÿÜ€%.x`ЂA7«_²jÈ…¡.CS†>}!ç…[b¿¿ö©ý‰‹Øi‘=Áò.kxµ"Í-L#‹³;Ñ΢X«›«a „9Õ“îN•ø!;àWù =XÐÉ".­”‰º\ø´Ýº]‘ ]FZ1t?‘–ºð,MV&D§Rì1~ PW FÇYØhð‡ðÂì|0s:pجRœ%NÖ“TŠ&c'‚&øÔщYr[Là‘#-Ö$I1 ËšžÚÆ,»ˆ2Ü€2¹¸Ïð?ú½Kú¸zÎ ôØGAfï´V±ŸäÂf%¹ä¦bkŒ—a/½[»a‹ÌõŽs«"ç¤þ¯ØbVz³8¼Yh‹‹ÐF.b_¾(´ z}r†¶=bñàˆàÄ£g 8‡çžÑeèõz^™•µ#4œz|]Õ¡âã_Öôq[H8Â’—œ‚cqj#r¹Âs¥ˆ[E{gcLAqŽÑœm·';‡‚Åí±(¢t³ B`hhØ"xö%“1Äg‡›­¿±(t“À‚À"èŒN5äYOªR“³²³ì4ô\áÀE¨5ÆôŽð÷`Ùð°"tÃÔ¸˜d[Ï” Øý£žh ­&8Ì}F“ãâc ‰}8”'iâÔªTˆ;Diq^Ñzý¶Ì8]¬>¸(i¯/{ýªÑ(6t™–£7@5'ž2°X×ýtWŠI[vå`*ØUˆûºúŒ0H SÔÃ~:C=ý±ƒØùÄB‚ØH…ÔŽÆšÅ~fˆ.rÑ]Ïç‚L\…¶ äߊ2׺Uaú±º åÀÝUÆn65…îŸf›•‚ØOQŽk­ÕŠÑ^dpN šÓRòÍ=!/B[¹Xá<¾4å™JœgŒ"ÃÈð{“p*:ß~€Cb$+x2 °ï×ÇὊfeõ‘£»-ð4G”‡W€7ør3Æœ(eÓÍte|§½gqe->ìšÏ?§è6ºbcƒåÓ+c¦{2êÁëhwêx…ù°Ò›E7“µ…õHƒÃJQd‰¬û.¯^î³#€Î8ô3º{õ!eãé3¦h¶8óFŽ+¼ú÷¨¥—£¥ëu^[¨7ÄÒŸmûffÅÝß&ôÅ`W ¦¥xƒ…jƒaOÎnc¥a7p5UgSª†Ã›E‰XÃÖÓ°Ôf5dôÍu¿.ÉÆÄ&Ù‚Þ•¸´ ý,ÑÐ*ïÒvÍàk ;Z˜ëêubqí¢¤Ì’-ïHoF¯|«—\©÷ä¢nãkLP·/íÚúãJu«Wñ §×G“!Äþ‘NÀ GŸ”—&Bz‚>kGºrÛÒ%1¾tÆh=¾tZÙ`el1®j®h:Pm§Ol k¤°»ßÛ•|¨kPs°KÑAÞUƒßóHC4$’Œ$cI @{â€tØ£¤›œç—‚{£ÿ¾W2~ —ú8ûfË…¶K—ëÎÀ øHÕ°áàŠ" Ž)3׸i‚V©fƒ´ß†Ïi†CÅ—ñeù!‰Ö½eÂ…ÅUèˆq+Ɖ8x*‰ç/ÃyZYƳ·áRÐAᅧµ@x }½×®_¼uª´¬Ì»ƒ–&ü—#Ͳ«¿ENŽ¡âhÒï‘âñgeæB£^gµ©ñÃmjŠÛSÝ\ÚÖкÀ‰Èý 'Œž§ºJþÕ§k4J ôµ”Ö3$2iéꥇ°£çÜxœâ„ ø!o)pÖ÷·!3ñqQvO콉¢Áøšéx ’±ø¢ØÉãpY´œÉ%Qb‡$!·CRè­,;!Ut¡Ì^ÝSWcȸ-³É|)ÄØzFq¿Ào޲÷©sµê ‚'–¡“'yi)á¹VEj­»ÿIw¿ç ê²¦KËÎ%E<+{IplÆhÞœ‹Ó±¯”’qœŸ9¾®Î\ÞÒî½×÷Í 7u­„r™ùçJøg8$á#ë›pÚ½kM¸c¿ ¾ÆÈ'¦¯å8 —ò'¶†Rš©/.µ‡5'(ÊjsÊY´¬ïàbJ¶ïÙSRQUפVùÅÄÅ~µ›ó}è5…Uo- )ðk RÆo „PÕl©JˆL÷ˆ‚•œç§‹Ñ߸ùþµ;+4E‚oí2˜N­ÃFÈ0¨r“AäJ ‹9ìgâgÀÅcÇàâíÛà¶~=¸ÍPž&¾ü•K;¼WÐLpúй³PJMv¢ƒ¡Bk¿O0á‚\ì/Îá+ 71]©‰BfVJZFVxÙÕÎP2ȰWpPtc†²>ÜžGRh@ͽå1>îeáBz¥Þ\ dE) Ën‡´Ò\#”U {*޾»Áî.B»Û̱»•~ûƒLï,+|»NpŸ~ U(7-ÔÃŽüü˯ò¨y©ÒúZÄ!½2;MryZŒç¿´("©í†å°–S¡F‡Ñ,­äá›4±;B´jX Ž%W6ü˜ª<*¿t´ãT cÿwá>ÿUiG‹rð‘ÙÀAA™©ÖžbËZpN¥ì¢«¤ ÕB^E/µBïèëè˜Åm½AY‡¯£._m;}UèP{³KBÃBÞ†ó5Ô=Éf¦H2!¶ÿŒ¯Ò¼cd—œoÙÚ¸Ù/$Èß¿1¨å°¹±E ÈZiÏü!.RºÎõ¤€‡H]N—u²¥‹="ƒ»xå®sEwÞ±:ë2”píæ3·×‘áUBv è+ž=Y‰XiYzmª Z«©Zsx<½ú¨9S‰lqóº’$åIï½é£FéªcŠw4„ƒ§Šy“XM'Ê}8f§ ß Ù±ÏÉåÙK.ƒ!¿@(,Ì/®«ûpý×;¤JäôÙ“'?xÜ%²:e¯à~g>—ÿæ!|Ø9–Ïž›YwJÀû,qû=íµìØóaOk¯Â ‹`xCó~÷VQ¤¤¼sR†%Šl¦^þ—±ŠX¢¥&*ey·ðUàntß!TŠëÆGÔ–} ƒë;2A¼s¥¯óœóIª[4&5Ô•ôT´¢«áÞ®áËÎÙ²¢ÒâêÝØŸ8ÈÝI¬ç´±$¨ØZãgtb;”@«äÀ R IÙ™Ù)%ÜsB‹½ç íZÊÿu«Ï{¶úü·<ïóÊ-*zèW3$w!G?ISTx’¿7ÿâàEl2œÕMqõûªU¤íŽ/ÌùµT`¹ -þ.ÊM,m÷¦o$r'äb/~ñnk[¥r ¨~ÚUyPM~’ÒÝePÃÙi~’s\ðZ?ó±ïiüi׳&µª«ŸEÖØÅð¦âœ‚«À•[!:WØI­à‚^«á ìMÉHAÔÝ$DÔZoQë&Ð0˜ö-Rgs—ņ_úåÇæëˤh@~•ä0öõ@ò¬ßÛØû'ïºE5óÞæ“Äj̺EÁ B­E¥Ë`x{ÄørÿÏPvãäÙƒÕѳÿ[ý?'°4õc¡d#7ÿ)b?·²ååe•í«O¥‘Êè“›8GNºKFz®Ûì§ÜåË8qrw+}7ÈÐ%`eäeˆï:m0,‚-'’ª)Vz§^ÿÕ(þÊçî6šnJ)±†¦ÄJÊöùÙCÔ;¤]fª’¼Ù½’,C¬”@žLAñ=“n²-„!#»âF_ÿ`Q„éÆÑâ {bp“ÅÔ_8S|vZ5ØUCv®© ç‹êèÚ­6%ô<­€]9¹\¯oH>ò9ÆIæŸÑº¨Rvò†K9?Y,ã÷ﬧơ–öCç[+N¥ÚEÉzdh…õ kS¼èÑ} ו§³ŒYÀ%ƒ6^IÚ¨¦T yBQIsÛ-àîÁ¤7]a¸Å½äƒ eGñ‘êæmõ[B·Æ­›ñ•3öÃÉßâ 0ó6¹Éwg°JùühHÌï£Í^É ó€Cå8ÿÍSgûÉÞ÷«[ÛJ³ 9«V㟙\@}TÓsyÛG›>~… &³g“’Å@JQ‹#~ú’údûñWI¿Øeðú&eä#~hÞÏÌK2ÃuÈçp`ÇÉ3`ÖXG˜5Jxv‚*±m(.t{Ú6›Åû|~íˆÌ P¤·+Ù¨ÉÑê 8µb+*·ôÞ—Ê óMßÐŒãp‰‚¶;B<= —:Ör‹Û!¯®¤87W(.£¸ pR Z½ö[8Äoéu¯ãG×%ócÅ¿·çôAø’{4¥ÈˆÝ‚9ãß©ûêfX¯ÙîÞazQ›êxû:r({í¸Ï^,~Ädž×ÐS^j¬¹ubÿ8ÕÊ­éûß÷…j_œy»%’V³Y³4®Ž^_]9zìDýó+©E›Sfü·úP Ääâp<À/âNœBòÊb„SU4qÍ5ÁÛ¶Æo\xÊç:ù,<XLˆ0nmS”÷ç¢më{¥Ÿ7 D±šw„?݇Û(;W³2%GYjô€­ÜÂ0Gçç[›Å½íU’Ô»—àeþ>`:I!Z iã'IÆL1`â>lçƒ!²8¶JS—P˜ —à\ÞÉ’—s«¡ >I,q¦.ö êHJbRhhll„6ž¡Lå(ÛÒFÃ:­åø ‹åt,Ì[FäÒ—®íª Åè0)溫‰RŶÿ ÇéxÒ£ùdä3Ï hƒçЮ]rgvè)AeÄ`Ú+dŤy&jw¦Í†Dj¤§(5}÷·ÒB”s¡îshcÿ9µ½Öã—M\mI¬il®:ÖR’#9Ö‘SEó¥m®ëìÕ®~*% %±ÚTZ}âìâÅ™ìóF‡¸‰/´6˱zHÝO Þ¤eFùnÂÄ,ÉÞï«´ä—6Â>®%¬ÁO¦žòðÚ˹|õÝÃw5?’)õÂú?¯¸k®g‰’X¹x¾±æpž†Çj´û×å ­-ÀÜ·àš¹žjݶ m:]²>VŸ©KÏ‚4ÈäâMP)n¬Tõ¹¬Åeý+çJÛ¾ûómmQVcÛß`;€aþ Ía§ endstream endobj 516 0 obj 4708 endobj 15 0 obj <> endobj 14 0 obj <>stream xœYw|åÖže³;Cèà@‚8›HïUb®@ ÔHèP6!! é½—Mß=» I6½W’°J²¡(DPQD)÷* |/^8ߨß;Pzï÷ÝßýÍî;sæ-ç<ç9ÏyWÆXõad2ÙàÕ׬Z·i²“Ë"·™³’vI÷ìÅeâ¨>âKòb’3Ê*¼;Uqx”°q(’!7ç fä2™ó*w§àØ0?ß» NífΛç`·0Ð;Ìo§G‹G„¯w Gý`·.x§ŸwDì4»…vk¥7ÂíÖz‡{‡Ey{õNìáfçìåÄ0) V-Œ Úéæ²(.Økó›N!Þ«». óYãî»vi„ߺe‘ë—Gùoˆðظ2&ÐsÓ+“^íï0wê¼iÓÕ3f:Κ=GÖÆ2ÌTæef ³šYÌÌc¦1£wÆ•Y¼ÆLgÆ0kgf3–™ÉŒcÖ1˘YÌxf=³œ™ÍL`60+˜9ÌDf#ó 3‰ÙĬb^eÜfãÀLa63o2NÌ\f8ÓA§±al™ÌHf3˜YÈ a†23Œyá™…ÔËŒ}íÙBÙÞ>ýû´Éäûä¿XmµúXᨸ¢tSžcç° ,áÖsm}­û^¶.²~Ô¯ _Oÿòs$ 870xàíAƒ2<~ð©!ŽCn64oèãaY/Œz¡“·ãÍÃ× :"fÄS_›ol~¶µ­°ýÛÈá#SFž}±ï‹É£lFù‰ýþÒ§þ;Ìâ³ì ÚÈ»9¬ã=”éÎñdYœømÍÊ-ÚY°vQBS?éy`¯ßgþ"_£µ3Î0‹+ªeâöîy|z¥vO8„63=–è{žÚ¤Çƒ68;,; "‹U+ g¡šà2Ôi93 Þ\”cƒ!· ‡Û`òC2C1U­Ügxaü¨á–ÜãyäH»‚$*éÂ×t1d«IüÈ,”ÉÅ4qŸWš[pè¨~Ú,ð„ÐÂZº^V ’²³3tÙ*Ò—ì!/`‹â”Y®] Á®JγèÒ36391(3Ù6j»¿óÈ‚dHÉ3è[Šá g ¯ òÛÚéqöÆ»W:«…Ý ê9k“ì"Êp»´†½x†ÿÖómÒÇÉÅwŸ Ã>J☦P³çòÁKE>uV³u†K°—^½ÛwF?™k]çÔ„¿!¦?°ÅìŒ6qDÝe\ŠÖrÑûòÅ) ‰×é’3…ô˜eÓ#ö€SŽœÑã‘F›©Óé´:UvvR„qûãj–»Aؼ Äy áKF};ÇãÌVäò…ç‘”p îíxtĨ’\ƒ)Ƕ1'—Œk4+#´ó©Ã`„I^-†·¡%™Œ#n6d"z)¾4+}´S©ßý`„P‹,†‘ód©IMÎÎöͶ £ë .D­¬3\§{l…ÿ±—M7*FgLµÁe$G1W ÿ#Kø[,&S°YM¶_ð ªÇÄ$O´à0ž¤‹o¥Ö¤BØ? Í JˆÔéB³bµÑºXà"¤¹>·xô ‹G#X á9A¹:=Ôrâ)=‹ =O÷¤äi*À¶ò ÷aKw½„re“áØO¯ ‰¾l/>xb&~l¤BjGݦz¯†&À;&¬“2hþŽ’ê^Ä?K7ç]¿sÿ۹ɣ Ç4í½Ǹ{×Èl óX‡ËÙÇ5Ž›—x9‘¾*2‘|Éã;èÎbß Âl_å÷aUÐ&ö3É@œ'W‰“xc «Ò@Œ@~V¦ŠeÞ·µ(î®’´ö°©)tŸé¶ÑF¨Ä~Ê Ü¢ðP¦ÙG®#C›!eЬ†Bk¤É­bì/›0˜Ç§?$3‰ÃœÑd8qo*ÎD‡Ûq¨@ d O†ö½q Þ©jSÕ>Ri†÷ -¤"¸Ú6;7(¶x)52LtdÜpÂ2xÍ|$¹åY*lg#«v4;SܾØ=¸ÍâØh/ï®Ã¯yô%Ž#a$œ¼DÆâƒvÄCèe‡öè#r_«Z½ßs¿œù ÝÔ97Û?éüôRøgÕÍÛ¬)vñ0!eîfç0¿õjGæÛ¾ø9Ìp˜8вËÁߨe‹ëqeÝE¦à âª"®?àiÕžÄÞ†Oýljö¬Ú„Ò7a“ïVßmËvÏ´ ˤ_¤¼Uv»,#ã1ºlÆ÷yü‹ç}ë12Sn‘yªž)½s)› Oi´QW4KDÈâHñÓaÞÒåà@¦«ˆ »$R¹Bî0cùqIRà<нUE&îr$‹¤ `ÇåýBÏ7TØâ¡\ ñ˜,¸b9ÎPâT0­(#<ס B¢çŸtö{öênZv>1äYÁýá1rrôÂHÞ”³±¯˜’±œ§)®¡ÁTÑ~bÓ^÷×ýœ=i –+ÉÜ?Öà«VÍÔíõt+sØ^*$Ûöá¬{W÷aÒ~ÜÀð'y7ä8WðÇCOC…¬pêoŸžjK.T5—×çV²3©¨Iâ¢JcK«jêc÷y¨=£b£Ïz/£ݦ°þ/K =;üTq1±¾àêº]5ñá.°–sýh®Â×n¾{õ«5ÍaÅ‚{ýJ˜M…ÓÈÔ«ó“BèËŠJ8ì—ÇÏ‹GÂÅÛ·ÁyÛ6pž£:MÜùËŸ&mòõ]CsÁÆçôÁóB™ªŸd#Ú··=0‰{$”ŽBÞ„‡(pÄÏÊx|åÜ1 hÍý;ÄÛ¡ð˜ÐHU¯ÿ¸Ç-8èœÊ’t)i:U†çú´`*äüÁóŽd6ódäiÀåpîÿÚñqÛ©Ú.Áûp%âØëKrfÂj*®ÈÄqΞŸx×íÎm‡ïÖ¸œ C¦ gó:ðŠÛFo¦˜Êš›«÷¯Ù½µ\JæÓS$5ÓO/‚fSYw;ò=wzÁ@¡ˆJ8]pÞ¦$¶Ø|н_°cQ/œ¥í˜,¬§`­ÄÙа¨”  p¢ø9ÞÅЪd×"ƒO0þ¹8@|ƒ¯‚ü„ -¤&YÙ)é™ÙÁå»òh¡ $“€ G¶fªš2M¹p8õpxp™Qn«Ê Õ:}pQ¡",éeù(¯«Žø¾ •`{ ‡£íñPSt¥Ês¿_ކ•E«‹à8÷ѨAyÞ’0ƒ O*¨³rêTÏ¥T6ÿ,*ÇmY(ú;åï™òýÿJTþ"_*H6E™ñ€ ÛÌC% 8ˆö#†%ˆ½Øfºïr^¾I\„ůðƒ…þÙËx€vû)þäÚÐ? Œeôò<áwÒ÷†®¸ß-­HËIŠÑ¥'éT™›¢‚a%¤_H»—Ñ•~…0&*[«yÒÛè(è3Ïu½n™/Á8báEZÅÜÍâÐÞ6KêN4Ç. w;ŠÀ7a9¼I‹ Úe©ú Þ ñ€µ0¡Ôå²×‘ðh%€ÇŸéú÷Å ƒØÿ»(^ø¢¬«]µßÿ½ðàŠ¡PB¨¬Ã"œX3¾Q-»Nã4 CŽ>âXǘÉ\ç¡ÔMpŸ0!›Û}´²ö7".]é<}EèòØÄ. X ê¨â–ÍM¡Š'¾Ç1”ÑäÞ-çÛw·zyøy{·úµ2µ¶ d1YNUәߑ×EÚ=í…óòr©2îV$›»ÙÃ2¸‹—ïÊ1_\ÅO¨Í¾¥Ü Ó™no%#j„œ(ÐU=ú²îÓ³ušTA½%¬fó¡Itë£ß˜IdËÚ¶–&ªNnÚ›ñCÄ£ÈbmmTIRs0¸qê¨×‰Õl¢jÁqi‚®r¢Ÿcßµûz½±P(*2–44¼¿íF’Tåg|üäÉ7.w‰¬Aõ\1á3VZºM¼&Å4¼{ÿĬ ¢1õ¡—]o‡I*É5¬|bfÿp_‚!û‡R„Gð9òçûl¯ å~Ë%|"¾ù«ucߨþ¦ã‚¬†SÞg‰óo5BÃŽ¿ô´þ \7 ú×”¸ð79j%¥Î@Ÿ4M¿:)ÃÒ¼hÛûÓxe4ÑP nDYÁ-Üõž¯Èdµòšá1í>€¿Â5‰ª&‹_]céã#éÓËJuTÔöêV+:î¥þ@+©•ô>È­z+5ÛF»¢z=‚6i8i9R#œY#ò´sKòùe¹J=°Vûû¸©63]ºLÔ÷K=p„v 5 ‚5–øC÷ 5Æ2ëÀ¶ Æj®w·i:ž°õšxúâÂ"ãE°5³¡ÚhØ¡°®W\×g§eediµ*²‚ŒSˆjöÏ|%a¸ .>ã«‘lyqYIm% 3lòÓè’uœ&5[oø˜ž€RèÅxˆ†}bNVNJ©$cÔ…®ÉfQ´àI|ù( †ØÍÿ;Ñìø/E󖌷†X§,ù¾ Îý¨›É›'¤nC—›T$zuv¯ÛéœøüŠœü÷%·i“苞d‰k|’¨Û³4ª—I añ â=‰À\©×Ýè>7S›3lNÚž¤ÜÔœŒÂpÈmvº.û ²Æ†0X%YGh—Rkp‡@‹5Ní’››^ ¶E”È ªŸ`%]]¹1Rúi[ 9yù•Üs‚ô-°{ÿç8|f‰Ãg¿–…>/ߢ5=›pޤ¤åè)• 5žäï-:Gì×ëL}±M-Í5«Ò+㊓±žJî“vïyª,™Efï òÈE_üÛÛÕª] þ^8¡¬)€ZÚ¥'ªVé¡ê8";ÍOuˆõßâi:úwdZ¿Ûóì"µ¦»õ©o7Ãç•ä^®Â¬ Ð:Aàâ^„ÕÒê¿7%3цxôø’Q£øZjß&ÓöÍ&XN'î²ØüS?c´QW.A¹Œ5^BÎÙývÚ%ú‰¯ñ˜ŠÛKŠŒw$$¯¦9³6ŠŽ½'µP¯kÔp:¶Çš\RàÍÿv³¿Bo²Ï› Y¶)[ ’"yŸákÚB¶À7g‡° k¦ô÷ù%û¿ÒwSJñÍ4(kiPA¸…ツDh³RUäõžµd© øV‚ã4 ǘd1ºÉ¶†¼ÔÃgúø©ÞM¤(ò‡)¤Ýd1õ'./.GJjšÀùyå¸Hô°A§¼xËÝ*Ø“›_Åõö*ɇ?Ã!8Õô=*Š«e'b°T:¦‰åüþ´&Ú¬ÔÃ{p¡½µêäšj{ 8Y§…L°-~KÊ:ºt÷¢­é†lC6pÉ ‰S‘NZÁSª ú¡¸´­óp÷`êëN0š Úµªô=?UWÉáڶЦ]»c·ÎùÂûá´wp0œ{›¼´Ó=Í_­ê]ž©ÇWËpþ—rqž8‰/KÑë ) WU74ÅäkrTdìIs²dOE4Ú6ÄTGhtº” žZ‹#s*(7çÚ6…&Ƨ„f6'N¨%#ÉàoŠtz ØFÄD‡…T¥f«pì&2fSRf\„Ú†UE×êõEeþ&’ŒÌŽ£ìšeÒ¨)«¬/jÌO;šÕ($}®xî?$¦wÑz¯Ô ñèƒÃ䏿iS~nﻵ'}DI­-»>Ì;+>B8Ÿ¦ˆ}¦ŠÎ³;?x™ !ŽŽ¤t2Ô ÍwŸÓßnÒÒ/z%¼ºS@9˯„°w³ Mp Œê:yæ!Ì?æî=6ÆO^Æþ5&Ù•Ћ²ó#q=ŸEÆÀÕ•p©3a ·ì4”–äç %å´ uN-E«¯þŠXñuö5<{Mj¼¬øwO€Ï¹ÇÓ;‰ŒØ.~cÒ†¦ÕW¼¢Øã ›8Â>ZG%â„Û×(Ê^9æ¶W ËóÑEÁut•מênß¾Ü3V½v·@ú¾Â·ÆþMÝkŠ1‡S©:~˜Ó„u]_\>rôx“0P쇋ïÑ@wÉñ#\Ìß#]ÓŸûáp=ZŸ2áφ¡/¾ Gà[ü «ÈŒŸ‚ò(¡9¯¦öqm!uþ¡»ãv,9åö˜šNû‹.–x"LœO[hÕýØ¿ã²Ïö D¹‘Ÿ×¿»·Qv¾nmJ®ª0Ð໹%AžKªúéWŽ1—,ªßkw€§§)àEõ?;‘È©ùq]µ Äår1µ{=¿§rÁÀU&&Åd%'f=ýž“™ 4KlcK5%U¹EeyφGÇà"ú2Α/†ò†ÏMçN1èõË“ 3Ç:Ûå¦õ§;›L‡ÚÂÚ¶Å&¤¥=›9Ù$>ì=IK”Ž…Kñ0ƒ¤ ôI“$c ¦è1á¡@ožàý!¼$º&¬!¾0>…ó'K^ʯ…}p.¡ÔÁè¯Ñ†¤$$FG‡hÂá.hÉ1wR ŽG…v³|³ü……+‰\úÃ(F]¥| ºò—p=µD¥f; ÿ„côzbуä%Z~AÅ)t8%ƒîTyw1ÞäËaoS$©~š¥L àF(SuÏ$A| M†½¡ úi†2!‚Cš äoZãy´=!µ›¶è*!Á€þ¼‡2;*Ý5A“–î À‘éʃûþþײ"”ùÉ ¸Ï¡µÝgĆ(&­œ²ÑœP×ÚVs´# & W8|´+·†Òhç'ÇNžj $ÑšTÊJ±¶qâÜ_xúÖM|¡£MÖŠ}ÐE:ˆ+¥»@+í¾ì µk¶FY?ÁÚÊ¡ºßýÆþýQV×€¾ÿ@†ù_GXv endstream endobj 517 0 obj 6227 endobj 12 0 obj <> endobj 11 0 obj <>stream xœ­ZtTÕÖ¾aÈÜ HËx%¼C“Ò›"ŽÔP¤'„tÒ“I™LÙ3“ÞË̤3 I(¡IDAžˆ¨€H“öEQÞ¾áäénPÿçó½µþ?³VÖÊ-sÏÙûû¾ýí}cÇtîÄØÙÙuwYå¼tÉú‘³—¬7V:Ð_ìk'öë$¾"ó$¦§ê–dû†~#~ußìÙ=ñµ^ŒÌÎnî¢õ³ƒ‚£C·øú…÷6{xÿqÓ¦MéïèºÅÓ}[ÿ%îá~Þîáô€þ+ƒ<·x‡GéïÐ…tGXÿÞaÞ¡Û½½Ú:;(08"Ü;´ÿ’ /ïÐm £rYì½Ísí’Y1A^ëÞ™ì½~霟eo‡ú.Ÿæ·b^ø–•ó#¶®Z°Ýß%2À}õ¢¨@5“Fl˜ü”Qºoœ::vÚ˜AÓ_s{}ì«ãfŒ:aØÌ‰ÃãºõèÜ`×µ‘ lb¶í²ëÆ0£™Ìzf)3‡™ÆŒa1˜eÌÛÌtæ5f0³œ™Ë¼ÎŒe^eV0ó˜qÌf%3ŸÏ eV1 ˜ Ì0Æ…YÈLd†3«™EÌ$f³†YÌLfÖ2K˜YÌf³Žy‡™ÍLe^bº1o0}˜@Æ‘éÎtb¶1o2NL&ˆy™éÉtfú2½g¦Ó›‘3ŒÀ(Žy‘éÂôgx¦+£³ëJ—ºš&Ša™Ì-»ÈN²Nž²á²“çt.³ïdo’¿$/a{±,áVsõ]^ê’×å×®]¯w[üÂøîu_Óƒía칸緽&öJï=¯÷׳j¯(‚w_T¿øO~ÿÓKðÒ¯}Cœ&;{9¦ï°¾ïöý²Ÿï+½_‰|eÿ+­B¡pP9[¹AÜß®ÿÀþ?=Àg@ãÀn5ƒÖ *tðêÁæW_µpˆÓíC>ò`¨mXÕ¯vK\–õh±zšEÁf÷øÞ¬”‰W1•«^'½Éà¦É]uYõJq» ¿êmr_íXð/˜~&. ‚½lTù*[+X_êM!,@,•÷hI¦ßºÎ&.0ÛA‹³Lز˜O+ÐeÅB,hÕiñijõÇ赞q.z.€-7ì36‚ Žéêôœ]ZYe2äŒÊƒØÇA~œŒ6hŒjÐ8®„`!€m4}»`Ô7ë8[4»â³Tõ±Š¹<Ú“+ö$BÞã×N=Ïô"îÖÒb„ÍnÈÄ x‡¯:{ÔP ô)áºmúpˆWc„®Á¦/ŽPHÒëÒ‡½#‘¡U“«K‡t§ª&(llˆ~.‚ÁÓh¤7¼ ePè‡#ZíÓâ·ª"VÍ]iQ¥¶ôl+sUQÅá‘ ›š}œÝ{êT…@W5Ò4l¢}s„ÕáÊÙÅÐûBE=v‡<±°›T0Ÿn°ÁpÔX U4";¥ˆÌWÁ%.fºøÞ¹³y.+ÿo®\C÷ ßÁáJn- 1¾d«y9ÌW· %œâÒÏ, ²`?ÉN]¯ìñ«ÝáãªJ¬¿ßTi×qÍ}ñ%ÞC«„.¤4²¦Ê\²ãã™»ß$½_# éE^ü~rør¾››ÚdF­¶Y˜èÜê ûpNùªùxÎY½oƒ² -v4ö-+dâúÅø n´Öí¬»cp²±^zW](xÂð¤0b÷è­4vI:]ªŠÈÉ G£‹Î”–M3ùÖ’}º=?í,ð†Xbð¡9(cOBYjY.&6G2•¤ÅGnN †fc=4ÁIhÔÒÛ6bª¡rLéYy8}qÙª¥«åÈŒ€ y;´l0¸nKÉaúðz8¬kR2U+ÅF‹êvÊHÈHΧ<0e§ç¡¾¥»£¡õ¢¼ƒ9ò&Óǰ›~þMtÙa웺¼F¥XÁ6ó. 62C O&A­g)”N¹,£<;oÅÝ6‡Ç×ñôÃYú(D ;ñ¨gëY‡ì%Ø0yõ¢õSˆLy/™Xvá|ÆÝ~í+ò’ÐÚéùê+XÅÏÏÜOŽNwïüýö´Ï‰,_¹„\åIïvÀ*\Æ~ß]-Žj}蘓hÐgWYeJñ0[ ‡ÓÅúé×ë¶ÂVXoô“öö\ƒ•­3Yš™‹SoFØZFSíx,﵌n™Á—@–J£Äa³OãÚ##Á‰,%“ÈâFO‰…±¼Õ–ï]Rìs¯ ¦¿_þy²ØãÊÊrSŒiÉ:uŠNé7x$Á:ðÜÞø.œ‡FÎ`á3qøÊÀ=Î%}½¤­zö †â/4¼¢A&îoéÇgåÑdqÅjˆZWQÚFPÚf¡ýŽk8•îkœ¼Õ©•¤ª@)N1`DwÊ[3åm QF&K(B¦Ò¢+ër¦WDUËÔJ)s›ËZ¼ñ>nd$MÐB2Œ&‰qÇ1d,ÎÅ…8'à&Ü$_ó#ÉË_c!æã¯ßÆAsH)%¯LyMZ0ùZÕÌ[¢â‘¬¡e&ÿ'Σ“ß@‡á2\Aúâ82SI^üg¾ÝÁìjWÄGòáBÄÑ9û–åL¢†È¢–ú® ^±|H›&H¦¡#*#Í’(Ó}MìõOæýUòÄS¬÷X{ÅÚ³¯÷%ÜÀä%Òûáä>Ù»¯Öª4aO°à–ïì ܬwîÐ$vûäúg_6O\-)ê¸v{`É7²­vWÏß¿-ùâ`å6Ò9ù×ï¾»ßT©EB¢&:B¹ðâÈêÚ"sE“Oýê·'¯ ö€«äò³µî62ÖÀ8{(×·³ÎRQ¡­•„»ªð¬U<òX†‘xÇr|™k¾ö5yEIžü®D<“Óg´Tî‚Ï¡á·:¥ÅËÛc|GŽ`ÀzW ¦aÂo;cÃú’Ï\_)kéßæ3CɘðYä-ЧŽc¾Ë>Ì󟬬ÄÒPù$UÀa¦ÊÛ‹/ÇÑP½ª˜(¹JyFØ·žy¾<Ës|Fqh§‘Šv‡Í:ÿäVÅ|ë chùºóE–ôFA«L„.Èg-­Ì¯« ¨u›å;ß-^P\ÆN,Qþ&ù–¿¦¨%å¸âôr„r8ù9Îú¼áXÅ?0ßâ'£òjC]Q¥2;¿¼fp·ahx°Þ?.T™’ä ܰl~wÐ^mp.\¸ÜÛZ®lÜÙ˜Q*I;˜ô*Mš ¹˜‚Äâܲ¬ò’Ä:¯ÈÍjwÁ½ÞÝܘ¹sßÜlõ®Ü®Lˆ‹Þ ~œ¢ ¼m‘KcüÝÀ“›ýý*ì]:z¥!þèÚauÍrx‡ZE7H5ø§o·A¤Cy‰™Cù•2÷èñƒ»šö›”ïËoag˜ä2gÝpe;·ÉêÇ*±§U¬¥ Di‚ûÉÄ¢,»¿‰/Žäþ…í›p$™€ m ™9µBѨÂ×÷c:Í……ê´ÚÅ=Ð \!tgØ9ެÍá]̤ó%À °ÿµû±ß$’=#‘ 0CˆxÏÿÈ2àÖ¸yDtJ|-—ß寡‘X›r°¨ÖR¿û„Õ}yž„<Ù^y‡lx° y«*qÔä´¼Á·üWìPh_¡uq/Ük«Œ[ÙQPРDý-öÛÜg˜œ’´u¤0 3;0ù‚G@åÊb"PLRàé©|[ÅÉePþ.ÆÒ_}wÐ WóVÍW±0›[ëç9cŠï©›Q‚¶@Ÿž\¤F+‰#©yCY™`4‚±´l¿û½…Š/{ðoŸÜ‘˜¯ÜZç•ížÍ).¯Ì›_pú冪½·°SƸ£`HΡXá £Lù+•Ê4$&ZMR²Fë]ãq”c=¼ç¯ô+ªŽPÖ…Ô¨?çž÷#mÈîŠÔŽÈĘÁÿ¾˜›—ÆúrzüAþ;#ÔZòÿÕ®ÐUÜìa¥‰:nÅcÔÌÞB=ÚÏ|ümUE †ãóY(§}€)×X fàîbg yunØt2Lù(Xqå¸Â}Kä7ÈPüíODëž§C´0“UAV^LÖ]¾Ôh͇…à¹×{¯ïIõà®”|U“ yÔN$§R˜Îñ‹…õr4þA—ŽÑçÖׯ*“Z„^¨_I6c¨M|Õæ@Kßä;þu’—¼{–/ˆØã™\d)q»;=ã#ê}|ô«t´ý™ ¾´ý©cïšT>ÊE¬âéLÉA Éú†6¿²®þÌ?î#CÍÂïí &±¿·Cþu.'†Q;ô™LÆwZ_'RÆ­¸ôeÕû;¥¢’úµŠZŠ¡f ²áT³ÝÍ ør¥ ¥²2ÈFáâP¹~Z`ÿá.â&©eIωk.žN…®b½}æÃ½Ú¼Úñ›¨ªb÷'ÍOÞ¦vù¾-¾Ã“þ,>ÊQS±´>Kvᄱ‚݆öd/ÐdìV*~Hwñu¡– €ˆà`kˆ­¦ÒR×ÑSË7¶ÆªBÎáÇçVÓÜ_ÂEGž¼h[RäuN;}râƒ+øº•LÝ”)Ô Îë@fŒyYL¦úã¶-ç|ïP>vùò;ìôhÁWSÌí=.~hÃmó“cwdb‹ø#ßѰÉý´Î´ëð†·~?*! ä&°yÍ*¶X„ÇHÑ__ó»ǾÙáJû¤!Jì{•ÇâàçÝ -ŒÈ’¡¿»¹ìÄ ófMÑ:&àÍŽ3W@;^IF°3`,Žzo͇µB»W!îÖâ¯Å°6@Àýc?/¤xŠ>$FI7^Α”¢?»)yÒ¢´p(ŠÒÍ…PÍUE›ƒ‚¢#CÖ¼têóÏÝ­-c:׆UlÛ¶m[EXmmE…ô© ˜›fAç&;¨Äì;˜MíØ–i|+Ê£ÚŒj!N*ªÇ‘´Ç¯‚\E*çh ·@ü@Á3@¾×ô#¤ŸÇ°—ÆÇ“…;¥Æš*Iaiz•¤2Z¹ hk!™Ô®â[¨CnïȘ;2ŒrjÊ»*TIùzƒfË ÞhËW{ÕÔ‘/­ê !DÊÅUš‰Ýpµ-!ìÚö\Pc©²ˆ/Kž;^&NÄ[|Nyɾó†ç³¨0ØhŒ‘ú &}^8DA²N£Q½J²Ig¬SPy7:Uí†R*ú•ºðßfQg!]]€ƒ :fÆÓ  ÒsÒs;ì, [‹!TÝÏËpózcZ&˜ ýâ™Üì³G›i Û´ Dä%Æxi eú\$@d|bJ*@z8ŠáìŸj=uDµ°öè÷èžiÿcöÜÉËšWB´STŒ&Š^UcxßhZ¨Õ×JWù@x—Ú^Jù>mÔi±I£ÇXž ñú(WÒµWbïÿÀ’î,€±Ã~ÈÞ}€òÁd†ØÃá%¶H=¦¯~ƒn øÁ£ïó³TÙæ“¿â¾ôˆ­ AŠDÍFlƒMÆ(éŽF½5šþ¥]ZÂX’ã8 ë4ùz©å®Þ fú„múµº0„míÉh‚b]nB†:/0+jIs…æ´|i&òìúöäi`µÁWºþäkóýÑüÃ1#Þ”"%Ϙ™Qø6:þHšÒUÒ!§0µ'´][ìÚ³ùvËBþßd帱*iGÞô¼"KCkŒ ý-Õwßµ:Àå ÷qÊ…K•}±*¼õŸîYí~8Ë…הd—‡ªU[52teiyÜíÛäµ{]ñà¦Íu]hŽ©ª)5Wå§Õo4(«çÕwø”×x¥­¨ªµÚ·µ‹ßÚº6sÓ†ž=pÏ¡2!§òCÙQ³·lZïÑpädóuœ–)H(°´ R±AÖb'~Å6U×~lè~„ÐÐv ?Žé-!)ZµNMµnw$+E£º°µ§ ²mþ1—¢d¸µ§û#iJëq­O³¢2´PÆŒŒB®ÝÌv´”T´‹SxœÎÙÙÇ^“¦“!ZÊ/_X[Ú§“™á ±II”çÉ1G¼øðÙ,rØ KfrN$:zÑÖ[CJ³íØÕ6†d]`{zàþߘlßÞ³S'ò;ví:\QekÜ[tH Vˆ.°-X« ÒÖ-ºìˆ¥KNHS/™á8ã‡diP”éEE9æ¶ëõ t±°\ Á?ƒþÐÒï ïèºt®+6,_¦ÛôD•Ñf¨¢ÜmÖUHXŠ0¥@Xkë?ø´Ö+[µ{]¶ª –ò#99.X¤î0¼g´Òæx·~Gû¢áµRÄ¥qå&ßm%©áÿkøý“K67Æ;þ¶sÞ¦ç#óÏÿ×ȼ½¤ªÌâà¶™á•óXv½â0¾%vçñ“?HäƒJÖ`È.¬>Ä)⋚×}Ö÷Ùxhø÷D>ÃÍ5:Vi"Å® © 8/¿ 7U8âûùÊ m†Ö¤Í¦¶?¯¨ O““­l/Ä´çé¨=v°G†ÙÄÄïñtÔÃ=ä•_âØ¶‹˯ßÛSéwÑëþ»}­èˆ×ø 3±WãÑŠfõ«ç ›*â¬Å;rvŸÙüîTò"éKx¢T<%fäæ<@Ù7§÷)ÆKdó|Önˆ°ùœ_ gÔEчàK Å+uî„%6¡ÔÖÒæh¬‹ñ \º‘Ú½ßúK{[ŠÙ;V‡«çqñ}É&Áë´9˜•à¡$åU¸DK’cõôœtñÀ)®“®h/ÿþÖžw4&…›:b¹­U eååÅ;Þ_Õì<†t[Kì"ÿÃ<ìÏž€—Û¢f?ºœo¶ÃîËÄ`ñ Ÿ#Õm G4rÒtš2.T¾•xPÃi*Î9[Ÿ•y…Vk=åªØ7ˆ]ÄÖq¤ïV¢„W)7<r…£,œ4Ì>‘^^xkÿ‡œ¸Xð­'vßXe8¯˜7ôñ‹‚ÞÙìªT«é5\j†&#ÿêUdÏ…íõô‹ ) n,ÎÏÌÎ}Ö‚=¹fã($ŸÈpUËh¾>¸4$$8z«°»uƒ!Î’N¹`Ê0”p»ÉXþÏ<õ³¤ Æ¬jK‰/MÈCQAòבa}ÕöŠkÐ4FÿBjµ¹Änå ågôµñd+M݃/~–S É5B²&6 B :;®DÍýÝ)º'´$óäχ¿ŒቯÈÛÐÝÒ“"ûHø~¬Ú~¤â2N7òwhvB ÷ÁGÍ/[3{…׆¥~‚5Žÿ´éð18ÏÝjìÐéÎc¢›š]…¼Ä¦ÐJÚÞY¾mÒÊa/øqþÏhÿÍõ4ªx7 Q–ØÜE{¸¡î|MÌ¡Àwj¢Â;œó[k¦MšýáõÓuçn’r±Äe.=mX*ÃZ\ÊŸ&¥Ë%$a¶ôFL#5˜Í[[5í¤l¼£\,‘rá}ôº+iž /òþ,I´qyŒ‹qg°°?»¶ÄV˜ì5ÿ„ÇMZ/zP{ëO9‰VÂ~<~ÕúèMn‚Ǧpwx‹#½¿Ž?ØÛ|ºœJÍ›|,l„€³ÑMpà 8diª>²« ¶>õ[J6åû§/†ÜÔ-#&u½yÉ9ªXm‚J+L'ïÙ“eÿþT¸<> "#Ë H‰¾rO2ƞ̔ǵ*TâDù Ò¬×iAã¤ÊIÎ+6䙄køž=.ûÓS¤~Ë·­mYÛ·=Û2uìZìñ¯Û&Wþ¤ µÄdyºR*}dâÂW>ƒ:r0rÒâ5IIZüý—Yi  ]Û ÓssMA…'èLïµJ\ÉWÅTûFÆ'©Õ‚^'I§ƒÂôº¬OÏ~¨Ì—ÇÄe¥¥§©¦Î$]—VlÚ×PZ]%ü^7þrùQ­2žöq39§¦Ðº¨m“¼O¿D®V÷™Ë31É0‚Á dòŒÙYmÙÚâØö²)ûºLtÃK<|™ö¥ßg¿VìKaVˆÇÿ¹i3àux+}ÜÞ™û¦_Š”àõ…eÿ7u2®ÀUŽø’K¼,«ŒþVuîÃûpÎgŸ(ÃnŸçTB=œ.–»fÂbê“ç©ÅZ¸ :\áJ++XÑd½Mû’qE%N—~÷QSµ8ÓhgæMÙí¤´ÔTµ°nÞüàYð6,©\u,ªd{‘?p3çL!]H÷O§~éÔì\‡¶S~äs$­¾€£¶ÌtƒÞ±ÕåŸã’ MJRnrn®1=/[¨Çð‘ p:¾þQåøQç„Y3{RqC%.mú§ç(+çñÈ.»=ç=V UÖ&Û~ZGú|&ÃC-/ò` –,šþ’Ÿ6Óà«âZ‹¨J'øKÂmØC?·Û:vœ6¯©cÞŽNù(óFËZfã—üs޵~û[ÄoÈjþ9![ÿþi¤Õ\ÆŸþÚÄŸqó=5Y³øPyZ`êæ¤¸Ô”´çÈ|ù“Ç8…3'à‘ÊÇ}Iz{çׯ¯<¦’†ü½UÑU~):Ðk…òN4îÞ¾éÓ^_÷ƪ%J²ŠlUI¯óÜDVÞwe[yûŽâÝC¼ÅŸ ;àö xæÂÜÌLÁ`4 À!^ãŸ:{ñebâoX½þvÚäò"í—c×>¤’‰'ÿˆ¯ßŸù¸‚0¸濪>ý EÞWÞ9dæÒ™[­Qµ6³µöˆ+Ä ¶Ãç Û{2b\¢nyÈfeà†-ÚP}Š>L— )úT=$qŠV•* J„ýò¯šæ 'ýænÛìöVÉû~ʆ4›vqÁæmaþñ›Ç>X€vØãÞ½¿Z|eEhŸ§>„Ó2¼ARyI bJHotðÇ倣gíÂYØ{tpZcR'›GË„µ¤S"‘ÑvcFé~’ØŸ!=o-Ì.3Ý”%¹»ËSoJ/Üû˜Òá¾åÉÂʇ´É ˜ˆFÐááņªj³¥š¹Óž—ÉpÂ,™·pKy|¹Ôp‡xÁvütQ35&v0ÏkYltt´rÁìˆ×hÛD ²:¿rJÅ?÷I"û~ñe›ènvÀ²Ës.öQüPƒÓx,›(ýŸŠ³°]§ƒfú9Þ6Nëx vû«x`*n ÏŒMÖJ“ir¦u‹=V¾D´rÔŠ]ìÿ:œEc׌&®¨°û*´_Š='}”œZ£QS-‹V~7ì™ÄÈL2‡ô" íHQ§k2sï~ŒŠ÷…£Ø)epƒëñ4®­î>•=•êî/±ÒÿÌko;m˜!½OEŸónËÄUÒ웵QÉÉï¼{èÀŸ¾RmôÛ¹rÙfoMš°­ieF0p£·†0ÿÓAŸÿð–ÔIï5ìÙ‡_5t¸& „Xm¤4ƒSB«“µ ‰aÙßç6 }¿¾Ã¯u¸è£*ñ§ÿÚF{i×kR`ƒÆIqƒÑ먑îûŸ]ô„žqÑBxƒ»yp£Ij©ÿËøþG3¸ Ã >º½ûýІ´ jÁK—‘‘[šÆõ ui¦•T—à¶<9ñÈgm]/tºvžb~¡‹5ç….˜_èÎ0ÿçÒ endstream endobj 518 0 obj 8416 endobj 32 0 obj <> endobj 31 0 obj <>stream xœy\S×ûþÅÀÍu¼ÔÞ‹»UÛº«8që@QTÙ+Ìa¯ä #ì°—RÜ 'Ž ¶³µÕÅj§ÚÚï‰=ôÿùŸ$HÒ_ý %è½÷ÜsÎû¾Ïó¾Ï{bF™÷£ÌÌ̆¬Zc÷ñv§i+œfÎÐݱю1ÓŽí§}[ÅÚý¯,šÇNþÏí¢á†¢™Ã(™Ùêu;V‡ˆE¾Þ>á6ï¬x×fæ‚ÚØz‰|=݃lÝÃ}¼ÝÃÉE€Íæ`O_¯pñû6v6›to„Ùlò óEzí1¬º"80$"ÜKdã¼ÇKDQÔ¶uvâ ÏmŽËc‚÷l_¿"ÄËåã•¡{7¬yo\æ³iM¸ïæ"œì#ý·D¸o]èá¼lîÔó¦íüpú¸]óß¿àý ¶ì^8cR좙q‹gM‘,™ýNüÒ9ïRÔ{ÔxÊ…ú˜ZI- Þ§&P;¨ Ô*Ê–ú€šHm¤VS ©Ô$jµ†šIM¦6SQ³¨)”eOͦޡ¶PÔê]j+5—šJ9Së¨yÔ6Ê‘ZN}HM§¶Së©Ô|jõ5ZD¢Q‹)+j0ÕZBYSC(5šJ™Sc¨a”5–NÑÔNêmjµ‹â(KŠ¡\)žIõ§Ü(Š¥PÛI˜È NÔ³MfWûñýêkçÌmÌ=Ío[,µh§ß¦óé_„ÂýŒãÏhú¿×¿uÀð¿Ìøÿ 0øÀyCò‡<Z:Œ&ötøÌá¹#Ø–--¿¹`ä9ö#öÙ[Ûßú{TÂ(l•e¥¶Þ`]n}kô»£=GýÇŸ1Yc¾ë;Vúö’·£Þþäí߸%ðãøþ•½M°Mû¸1ã\Æ=?uüÉ ôß ':L,ÑVÑVƒZ+Q›}©AiZ­=ÉvÒ¥ ÐÜ q<žGdžA@`”ñí=’½Æ+í z_^A+ß-T‚Ê×¢"¹Õ8M¨Ÿï5ÒÜ7­Ÿi´÷ÙäyA,${áÁ=*+ „Cš41-- â™Àz¨à^ЕµdÉ(ðækþ°@óèš ÞQd©Z¨ä_ÐõÐ\’^˜Ë§eG@0x…6Œýf­h²$ŽVk÷«Í* ´Ëµ4ÛL—Õ‘Ù –Çýé8ÔB9ßH¯À¾ñ{ÓÄ©Ö2:½*Y•Zõ>JµªûÇð> [h4¿ÊI)ȬA*Z/ rò–ÆÉ@ž›%L¸R#ußïÙñì8²*ÊáôÖ£.µ“zÄwä¤eù%²ÕŽd[¡Ì“[NÇŠÈÔõPÊÇ]nÆ+4›.%¶ˆÈÜÐ*Úòø³;Μ+ þ˜ÃQ{„úq ºq‹£Ÿo;ºè#Wßèhݺijô¥Ú 4(¬[ Ý‹ÌØÆ H‹M’F¥riñÑ;퀙·âƧ‘Q„d^îS%©¦VUÑt{¸âeã±³ñ '¡ˆßÿkß"­«C_±È…[TÓeõ½è˜`ðm Ôð+ñä%h²…²ZšE†G¡äQ=ñc ál+,"ŒÞýÃ0M„óOÐÖßðV‹ðˆ>Ò­N\:AƒšÕfç:Q]§ÕZ° ÞÉAiAŒŒN:9KIµ"³Ù°#´ò=¡dïŒ Ž^*íº†râóÃK¼rS)Å©ÅP¥ùù¥ÙŠï¢ø#ï ¥ßø²Dتêµp3í’äPưÃH5rUø\ƒâ4;HܵhaNWíèçáo?•ŸH£-Áìµêcg¡‹¹½þp8’–è¼TGÀÙÐ#¡-_†˜ BF#‹+Ý÷4;®ÛVñö¸˜Å–(qôwÍË]]öl˜Ã¿F›Y¹Ö´[Ð+V¥”gC³?¢9ü”öKIñãw £!b¨”\=Êâë¸#2J– 1Ö¾ÕPÅi‡ÒÕ PBsIXÕ„Ë‘Qœ®š¢ªŽÌïˆEïÿ†Í±ùûïàáØò§é¨ê÷ÓÏh‡Ýñ\ÖÎñîÓ®_¿yëšÃŒ÷—Ùñú)œÔès5²P ó(ˆoâÐ_§YoânÓåuÄ¡ á]µ º%­Ð÷Ÿ4™E[v4ùy”ïƒÍ¦MÇ–xØã©vihjä‘¿ùJáf×ùKV~|³ûç×o\ëØìÄõy‘o 1PÙÝ‹×j¨åÇãDÉ[4?Ie][mÄìëT¡¢Ñ;ø²^+öÝC3‰ÐZºo©ë(’Àr“ö›°/.;˜5Æ™êz$"ãÕŸ&Shƒå4ZדYâS.«ëæâì¼VQ'ì1ÎÈ–ºž`™nÁDµ6_ϯ´ÑÚ{l9ÔŠÓ“RÓ9iHãE~»”ÛH~dIFc¼‘Ñ[ˆù¾ûñ¾0HL‡ )Ÿú®m˜03æþ‰¦¢wþÙ}åÂ.ÛR>;&+¶Rt‘Ã"5ú@;C:Ó…î>²EìåKç®Þ¹´|δU«û<:ÅáÉæ‡Ý&·ƒÌ~ù Y¢¡³~·ÃUàË[þÒ$-õúGT{ÿ»äG 7ö I¬¼…ªn ´‹ÐfVUíˆ^û+~ œ6ÅCžOF,²:ù¸N—æÄ)™Ñ©|Ķ-ÉÁ° –Žýž‘_aKo_¾pÛD™¾`kÐ'{µGÙÂ2P@a/W¸²ÜÈ•s¨Hˆôˆ“â ’ \A/ U)+p£Ð42 dvt‰EG"±#vŒ ÁGñUrDëªÐ{à|v6ˆT §ÎÀC¸]ðyщ’Ë-Åà.´%—9ï$v¬GX™¸%qshä,0pUƒ*5‚+ZÄöú°Œ¯î‘DÐ}WȃF£!4Í™‹¦bk {N²ZÉÏBdÑIò0ƒûo$>˜ÄøŽ~ë5dëNZÖ`[ŒÒäQ¿‰ É|’ž{?NEý>?Ñ^£â±¿‹ 1QíB¯FˆÝä²`ÃÇOnh¾¾{|‰}_aDà 3Çk~y(@ R¨Ñ“Ò;ä$}ï3hæ2 ö´)kʯ,„Ø…KvÍá¶N1Ô@žã®ÉÆÒ‚j¥bro©X§F™j³›$%rÆIuI1·?}j÷ yn|½¹Ghâ7Ö8Y ­•˜ÿIÿ|tõÖ­»WO#T4L¡FnêdòQšãš„ý¢fMæÐò¯UQ>Vc¥Ð²E QBˆmÛÕUÜÓÞDZ…Üt+Ý»ÛB}ìéo²OÚDX Á´úá(ËãH„Ö³?^þ æäaQuÀT+Ë” Gæo[+^çÄ[jö¦ÂýŒ è>î²5^¡R£ÉX WRâ+Èîâ…+hוp)Z'b^Úxk”å‘­d·¸Ÿ/¶¶F¯¡…©}„NÀæ.;·c»Qh zïëßïµ] ÇTŸ£H¨ï%âõÁŒLOôã|š=ËÜI0MÄc°=^÷¶F/i®Qòe€ 7Ÿ«Wš¡‘4‹ T¤KåóMRùüt_þ[0ǘ½áLzÚçÞ·ïÜ?Ú] *?Yd 'sÜDlf–ÀÙº>I{ÿÙ4êÙj§¨K;š5ä±ñ&™ßwáÁ&Ø>eÌdãiËçZ©ycDuppDDppuDccuu#÷ºJ€ë¨üº×uÝä¨mLû& æ0λ7, vÉiðäÜ2ŽÈ*e²Jÿ^Ôb+=l«¥­Ü¡@uì5[æÖ£îkÞGJxC!y‹+Ëç¶•îÅ^mpÒúLÇ©›h@Ù{ .;¢(MùÚÛVê¤Ç¦pm[Š]‰·ËÍûè„ý7a|Žì—ðÒLÓŽÂŒ€Ñ‡ÄÙžÀдO5‰tvÅ>ÈõŸOÿOˆŒD>8ÒDþã)ýZ»wõ5³Ñè¯VVJ`L¥;zðéîKúØ™¶ þ‹`_+‡jþÍZ\@OÓ„Ý>|¸°±Ý¨Û ®­5ÈŠ ê´®²zC‚ó©fÝ#q6Q$vÿ%Óõö゙–2©{LPEõH0er}Àd¥›(ã,ºK6© ù_N°¾‹ÍÐ]‹Æ7.4ÓHˆŸû*AÖUPEû˜>‘4PmÖMŠC$£¡HhÑf²‹÷Mdh<O·@/ ~q0®ßÑ#q1 «IÞw¹O}‡ÔÊ Ç+zL 0NÐÛdT¢.Áw5¿Ž5YŸ5‘%øGÚÆÞÙy«ÃÙÿpèÇf!™æM£~£ñЇ<{öð ª t† Ùi@çÆDv—κ¦: ÄD©Òâ0ý‘BßAoÇg,dtF}ü‰„Ãâ«™E>DjMbDfª'æ2¢H÷ïŒÎXtÎŽÂ!ºïu4óWpwNxvÜ!°>Ù•êºGòÒìjFNç:·ãþ9)Å1•P í]žSmT×h‰"ŸõfœY&uå-‚ ÖäúIdßêcËLõ3]£»»9ÆDjûµ²Õ§d€iìí3Ý“r³Sx ¼¹å[y¸¦4ÆÃaôk¥r÷ƒþ×!éB% zV Güž`.np¥øC $,‚1 T…þ,æ»×g1¶Z+9¼AT)è(ˆ$5_YÇYv¸&íý˜u÷x»ùm῎ôD4h­.626˜€°èµÃ™'Ú Ÿ²>ÕYL`˜vm'r‘)’kÂ!™0= ’Ówâ鎄é+«J=וּ1=®]dW#ðrúV2×§–pÚº”P¨ÌÎ;âsÆç¸žÇb¹4OTyäy-ä¶¼qFšÉ/3èü¡­êh'jÅlf–ÎiÌB‡¹Ø¼a{§ãç#Èî: X¼%0…?ÂkТl{±©1’b2!)‰÷ñ÷Jô%šJ×xôîó¿7OZ_ïÅ7ÙîWî}{â‘ãÇ6ÚÚºnÚÍÔ\‹Í% £{«ÉH<~AÍZkÖÜR="´ ¥ƒp5í—šìÏã*¡Â[+sr ó¹†ÖÕ—€±|ùàør‡…+?þ0xmþ…`>77?”LSxyd\`òžùß®Bæhøo‘àù’_‰f%k?ViG 7ÿŠ@»BK±Åy%yPÅä@“'‡‡­Èª— MÄ“ûüüÀ/9HnŸÊaꪤ@ ©`/Ž‹.J+Iå‘ÙLmHHOƒ(ë :Ä¡a·¤¡2{²N¿}û`_A“ìSi=§öÝ«¼áÞ›ùÀ(K*Ë* ¤r^T±f_h©.óÕ¯&è€@ûñ«Á¬Ñn{ƒÝ¯(’ösÈÞ$ñN5ÁP²P{Z@ù’t;ë`‡¡ØR4îÇ`?”'榓?i fÂ*£êë”ÍÞç§âÑäï`ìÊY¾ÄIÈ|ùoÈì×oÑ DÏîÆýœc<\9’…³°§#J-UÈä“c%/åI+ ϺëÊé/îŸûÈn®ý¦:§ÞW¡Å7Ðâ×7HAµ,O·A[›$ðx<š@C›ø$px/L ÿõiƒbÇèði#ƒ‹uSÍW½ WúL ‘¯>`Ó S*"€‰Š‹§ä$e§ñèÛ¿×ä&åÇTƒµ²¬¢2?£0S¡Ç”JÛ®óâEâÇÁ„wدóÅ!€û1ðk«¨(jârQ;z-W_VVfeA)£ó%‡¿¡ÓÊźbâ Ѽ{¯¼ªÒ gÒ;£h¸Ù‹kÔ–ÍÆ9îŒMÈHʧCWSÑúâ<ê§ÞsÐÍ3<Ðß«I´O‘'ÏÊÓ˺gߪ´ãˆ%Ï躶‹=ç‘“œì‘±Õ7åÊÉ=`O–‡<´JàÈÎÏ:”u^~]~^~6çœczŠß¨ã Pѵ‡è«q½ÅÚÞDòLÿ{žnrmo8—1@%Kv銴“îÈËIϺ2ÔÃ.w<Þy¶óÔW÷.îpÞäè¶œÿ*€ýºáx\dÌ»‡âA.²ÝtbûW¡œåïË"×nX6zêÓÙh8ñäÑ/w.Û©¸E¸•oß©Q_ºúÓ‹ëÖ¯¶ß<_·(ª½AB9C ]@ aÄÃMº/þºA= ⨟ü$@AÚklöIßüx¢x‚³ÝJ°›•<.;²ê ·R^¡K»ÿçct¡v±ÎÝ(þ1U;Õ³IxØâw¦‘4ë-,ÏÉÍU@S+V†Š¢bý+W¢‘ÈŠ(ÏáÈ…¥af:LžO˜B?š…ú=[qø8‡'æ°¶[?»óðfç­£áQå|½_ñ6H©L éž ɌӖMóõ( Ø!º×ŶÖû{‰ö6‡¶¨kiÑ?W¡ñ7Ðäh¼ó.m?ô!û…‘:öt%šlqÊxË.EÂÜö°Â8°€Œ YBl5ñw—Ýü-Æ“-\Œ7Ò±x(d€Œ—ƨZ²›Š³¸r4Äâ÷7ÜÇo‘”ò»~†‰´Á(dßg˜Öüß–áËæo²ÖÈm­ë«¡l^¹ Ÿ©Œ«ˆŠH‹O#Tü{uj¬ ÅZ\£¬Î++QèÞÓ2ÏÐFò¢ZG%[¶!ª&05]R. UÙ·¾:ÁççæB9SS* ·XÒ¾÷ð¾ÊúZë÷¬üo÷¼¡Çœßâ—’–)I…X=¿«>Ì? lõò ö ®ðéèë¦uÛA’k‚tgÞë'¡Q¸6Ÿ¢ÿòaý < õCæÏÐhD‹Îg;¼ƒ&k~»sûÆ»x ~ÇX¬Cÿü.4¾ ev¡ ]¤wuþI>¤4½ÎæfåBžÞ=a©Ñ é®ÿ{UF’4R­£Ëc«jó*‹r8ôÝì½—·oß»Áή}ÃéÓí—ïpsV² Ñ ÇŽU5W…¸¹E‡ÖmÑÞcïíéÜáâµqÙ⃛Ou¸t×0²ñØáÊæ’’Ê@·èàý®Ôè´îÇ -Õ7,aסìüʲڀQ(µ$yŠWa³øÙ1¼, ¶C03SÞçë·]LZTZX`­¬¯—!³Ì¬- ¶B ¸ž :~!õ0¤iiÉ“y<6›$ÁÍB]æa§æ#ueûäu:&wª´nJCÙ e‹òJòI¹®‰.ŽMΔ%K8ü{&§Å§@´5Äç'¦¢ï±—Uir¶ŒtåUÅ5Uän!{ ƒ~¢~AêÔÛĬk½_$E§%ïzÍsNŒ–ÆÊ"¥ÄQezYÕaÅc\í ¡ñ!ÇXƒgÐFDëŠÞ«1l_û{©Ð´¦!çt‰ÐI uDÏØâ}„Ì{IÇ@ZDÉ^BÈ}ºBøOgKÛÉ?]Šü‹Nð#OÚ‰$5l›´¦ÐÊ4‚Ï.±É)ié atý‡žR|}ïit0‡“éËg~¾{ôÐÕÎ×àk š|Á-˜··1±BUSÑXœ^’œÇ•8Ùr˜_îš½Êe£½“>_P¡ ÏÌž®ý¨Mc¿ÜÛîá' Q†7çåÊ!‹Ëä´èÌ‹vñ)éIé„'â IiíŸ4‚{p.³ÐÇ›vÔ¯Ëñ&†èìЪ ÒfpR?“{–ù ßì/Ý  ^-„ ðÆ“¤zü+þ¤¼_ÆËp™ÇB‚”²OÊ?);%¯5±9LžÄ‡Éq¿,içÌ&’ó :È@IJQRþyYI 2åÉÀÄF'„G“»DËÂö˜|Sõ8 ¯J(/È–”r½eóŠî+nèþ¸…h> endobj 28 0 obj <>stream xœ•W{XSW¶?1æxTDÆ™hRÛZ_µàhGë£>ðy‘ª¨ ¶…"Dƒ¼ÞòHBrÎYç$ð" ªV+ÖÚ:êÔWKçöVG«Vm¯£­S§}ÒûuvŒZïw½Ó¯ßùòÇÉ·÷Ù¿µÖoýÖo˨(™L¼xQÌÚØu“#¢Ö¬˜îÿG+–IcH¿—·DÞמ1#T#ó7hõpBÉe²%+^ŽHÏÈÏJÙ’l11tê /Ì]¦ËJILØ•`HÖ¥%È‹>tMzbŠÎÿ\è½>4Ú¿#;4Z—­ËÊÑ%HOË0tY¡QéIº¬mEiW,Xµ0}ÃKº•‹V-ÎZ½Ô°fÙÚåërõ1±Sž›EQS¨'©¨ç¨§¨UÔ,*ŒzšZB…S㨩Ô3Ôj<5š@­£¦S©ç©IÔ©õT5ƒšISéÑT( Deƒd7tÈçËÎدئ¸L/¤ ŠtÙÌ|?øÔ’!7‡¶åù†¥óŸ®îIÙ²3äüO²¨u«‚½ ðxeH7ä^ªQfÑzL¥â¡x0sèôÖ–mŽ÷Tp”€rÃ)ÎÃWxTÙKàÝJ±Jp6t)ýþdö±¬ÔÕPQåt¡ï¼Á*žäûχշê{íÁ~Pï‡sð:{¿9ôŠâ ·]¨ ߺ!u:»5µ›0KçÐÙ`ƒÒ\|ÚwBüÓ€?¯[EXsÖö{dÒá;r4É;OiÕדô4ðj7ÛÀîá'¬Sٲْ4k›¹`Õ«¤Ñ4dßß¹1çøô*í7;o~7˜ÏæÃÁ\€û•‘èì\oƒÑ_5¼¸å…Eáx°OÀו?³¿µ)P}·ñ‰a Ãð@m°Ä–¶Ián\D}çåR%ªT"ùܢ"ŒÆZ¬~êÓ™h R#% Bã4¸[”é3ªQÐëuh€ç˜öèÅ~G#0]—Šð@ƒSÉ˵úèµúX`ádºÜ+]Vö8^±ßÏ*=—Èg@¬3\OCQÞvS©Å¤Å›±D‡ÊëÀ ‚zÏ[Юqz’Ù µ¢„Í"Yjl;Rгø¦j{WTÆ•°Æ<«Ñª‡T²zI×ì'ÏÇÐË’ÓÒIWæŠF±Ä-ÐЉf;;·O޾ö†)Í;xÁ@5ë¡vÓ}Ðh«aÃ}U¶,sü8ø2]“êg™ÝªFÇ}W*· \5¨kApÚ›nJÇUŽvWß?àIæ7’n̆—D½P®Wíê‡+pl¡v‘ïE!ÊÇ3¯=Þ)Û¹×íý¥«Ü^nc9–Óp‚CÐt‡Ö£(_ãÓøÆ)ÇϺº+Ñ”~Di?¼ûyÏÀ\þf%^8+Z¦œ4{ÓBÓŸàë¥2xGÜ’£‰¿¦-)­!º‰¶¡iãÑp®ÅQK•Nd¾¢¿º½‡Øð²¹cµ›ÖFÄ<̤G†9»ÃNTa_;:ETáãÈÑ^ô‘ͦÑèw·Ð€Ï\Ä£µøÛǩܣÃɪï±ÿQP"O%¬Œ<]“zàúœ¾x2cîv6¥,I›3sYr8!Ïú!˜“´·›4ÆL¹7òÞ$Á 6®ÃSɪ‘€?Œv*®Ñç:KbrÙ"¶@ÛF¿‰šYôöÉé9Ó™F@Vg—³â‘¤ßÐHÓ‘€eÅÏ—•UȨð$¨nút­%‡Ž3iÿàëø?Óö‚KfóË¿¤vËÐÙkrd@_*¿ÅÁ¦|žçx«X[.pÌŸë­ä2im–º¶ÖæÎ®Œ]I‘cb³5$5ÂÉ’š#ÔçOÍ$9êB”Wè3%±ùl9ôAøEá¹™aÀÌ "׃ð2bÚâÇCÞÏÑ÷ý»èýå¼àŸ6‡à:ìó‹ØVzN‰Ëí$™oðÓæê˜ £›z×ÞñŒoÃ7£~kJÐMå×îïÏÂ-拉ýxŒŸñóÿ³& •ê‡Zù(cHŠßFƒh¤€0³¬¥+´å:Î …Ìóç·ö_k»[ç´UšËxK «)ŽMII&ž}ãÓVa´j‰hÍêÉkKnÎv1ê”XF´ÃÑ"T7;ÔUbqCÌ'?–cÕ¬5x˜¿×CáCÛ=Ò¸€ö­BqÊŠ§ó øü*·‰ßé!¤Clÿ0ðÐm´96Ÿ+ÓÚ2Ìñl™aõüä`¦àa'ÐÒ @ó?GCµ\ýï׉¶1yšŒEà ¡´*ïëZjUÝÓXž/)Õ¬X¨?°±/Ô8 ¿†7à\¼)‰¼Ì¾r±ûX¯¶ÆØ•XC¶ÝÞàDËõR2AGzÐÌfYï99²HO+ÑSô}¢á§èN´‚ТpJÌä0–5ª®Ðq¸Í'¨X=é’¹óˆÇÓݤi"ž´î2“E—,ä¶gš‹ I:`ÊöwÔ¡Ò_òÉöp2Â÷È®ö£Ê~¹tõþd(ç¹R“&.:§ëÕ}¤ªxXè“x¨QLè×z6·—_ʹ˜£:éXÌœeáÏ>3ýmD×9š VSCÜf)o-`5)8Ž3H¬ºÜnuU BµKÓwÂmxó•}GÝE!hH3wL×§MÛ·Õµr‡®Z•ëL­²ˆ©õún8Æœï? ÉÎ[À×B¡¦ ̵v§ Ú5«üuF­7^ú^°IŒß&%³óý£= "oÀu8_ß!Rb"®½öRÀ[ýÒ¦_'Œo¢F:FÇã¦_±)0¦‰(á×I\árÉAâ »JÜM„iƒ{ ÆgpÙl&éøþŽGt46*ÚèC(¬z?š;`Tð-œ“%Ř0-*ëV¶x,0:¢M|Ú@}[胻ðKŒ¼BGÿ±ÐåÀ!Ö ²”1î=3äè¢ôÉ­X{˜Ö{—›¹Ä»“4Í…äiÚEXósšvYSËËfƒ:ûž\(Áèa‰¸Š1ÐWKÀÝJúòÈ:>—{7Jç•ýŒŽ{…ODŠiÿÛϬÆ_g)Ÿ=™Ü=Âv"U-ÔÛ›´ç¤‰å_*f”OAº¥JÕøwwf"D4‚”-š@ J[¤'üÜZ,÷Î@7”íÇöÖöî3ré¼ô' åi*û[¬ŽÜ;x^Kœ Ç–óDwY~W©Ö£VÞÎ6ËÙuš‰åÌà×s™ .‡Xa›H‚jƒV¨*©´8õŽ\<[UQ ÙÑHîJ÷wdñ˸BPÃF!Í¿ã$ˆå•›Ïà¯TŽ<»µêÀ᪨EP¯ê8ÞëÈk½ß:*+jý2¢ôϯ¬K¨NŽúHoãe¸j–³eûÈ€›îk|dÀíÞ MZám®×ïH7 ÍAXê¼W³ïXz^“{‰wèn? -x*D‹Ù~ þN}fAÇ™‹´x‡/'T"WLÞu×ÐvÏ/òiĈÿò y«6!¥ï•#×Îî ¶OtTùõp üdËý3Ì“ÿh–.)k[[]¸_C\ëfX!æ þ‹¨M -PÏ¿g!L5±« çùU/J\ ØI9ºOÁnM€Éìb‚!^âýºjXW¡Ã\» Lä“ÖòRœà›F¶æÛ-‚óßl=CŠQwÛ÷O•X$šëÈ›³ÚYì’SuÑö<\?Ô?ý¥‰Z· ­|Ÿfõ#N‰›è²Õ ÔDß/Û÷2øAŽ^=©ìʪÏIÉHK34:;<íÝš Pz`M•¤Tº [õ©éiiƆlÏÞ=šµøÂcvÝÞyn¼»m«¡ñ¦ÚAž!ª2pFsÐ`wUPEý ¦Gë endstream endobj 520 0 obj 3617 endobj 26 0 obj <> endobj 25 0 obj <>stream xœ%OKQÅß­ÈÌ,pUé[AäJ\XÈD!(æФa|èÀŒ#3c ´H¤À„h'¶ ¡U«`–}™–}ƒëx]¤çç`~‰@èâòªT.ȹÒuühAb“m˜ìH“]߀ô©ìÝ.}àçžoâé¦ÂÌp–­Ôe³Õ±´zÃá{ò>'“ ž6„¥©J“ç§! Å™—LUNç§u ›…-¬;Qû•M£Õv„ÅsfMXMU³T]¨‹}‡±X‡/xfsIR54½'Ýõ~]¸Þ·ë›ÊøÁUQ¡GêS…TÒçŽ}|ÂTpågDz)ƒìb³˜GmÌPºÔ£,åÉŒ…Úcïd¼Lá×7ð³ øïÁU÷-dìv«œ endstream endobj 521 0 obj 305 endobj 317 0 obj <> endobj 316 0 obj <>stream xœcd`ab`ddä ów Õvö Ž´ Èÿfü!ÃôC–¹ûwï÷W?›X—ü`ú&ø=ÿ»¯+#£›wTF¹s~AeQfzF‰‚†³¦‚¡¥¥¹‚cnjQfrbž‚obIFjnb “£œŸœ™ZR©§à˜“£ÒQ¬”ZœZT–š¶Õ9?· ´$µHÁ7?%µ(/1/=©(19;µ$'5­Á[ÆÀÀÀ”‘ÉÀØÅØÍÀÌÈȺŒï?cÿ†ß½ ~Ígìþ^ÉüýéÏhÑ Ó»ûº{9fÕOjªio¬k“ûíþ'¾­¾»£»SHtL¨ÿ˜P×ß8«›cÊôI³z»ûÚ¦Ëÿvÿ‘ÀŠiäÚïµ#†‚Ô•ÅK´ÍhŸZÓÍÑTßRÓ 2QhdОD¨=5Ó[¦ÌêŸ:c‚_éŸö Ù~ Nd߯õˆ[Ž‹Å|>ç¶<< a\ ? endstream endobj 522 0 obj 354 endobj 70 0 obj <> endobj 69 0 obj <>stream xœW PTg¶¾MCß+‹‰fnbñ6.'šMjŒ ‚qÁ€¸qénYÍÖìk³w÷é»AEhÀ @+A¡QÌ" y‰Y4F3S£™¼¼$V%3š—Œ9—üÖÌü4qbê½Ô«^ªîísÿsÎw¾óÓ2ÆÝ‘Éd3‚Â÷mܸ(0dmÄ’¥…Ëž‘nÎgËÄGÝÄ9òzRõ¨»~¢ÄãÔ£(gbë ÜûþþAF.“oŽ LNÉI‹K÷]ø;ß%Ï>»Üw.:-~¿&É7D“­Ó¤Ó‹DßðäýñÑé9Oú®ILôÝ*=¡÷Ý­NËŒŽšò˜¬KÉHNó IŽŠNKbƒoNÒþÜ䨔èÔ˜´X}\z|FfBV¢&[§õ~R°d©—Û ™g/£c˜]Ì‹Ì:&’ e‚˜0&˜Ùʬg™˜mÌf;³‘ÙÁìd63L³–y‰ÙÂÒ‡`Ö03˜™ÌC2Of.E‚qgŒÌ Y¸ì¨›»[†Û—ò0ùû,w½ÇJÿRlTPü™ `mÜbîýinÓ ž¼ç«^J¯z¯!/Ñ[ëÝå£òùOÑkú?ÝÂF²Û)¾ë’Êäb©øok¨®9œ‹7U‚RÀ[­œšµ A¡ÑXn6ªÈ4r€ü»<ιzÓzH†$…TjtžÅÛ~EIEÊ̽ ÁAP E`°Y-]õÐÇ9õ]¢>3~÷ æ­k¯_l¦Ox€KôtÊ.  ÷J1Åqþ+íkÄ-0$nu¼`F7YYê¡fß¶C”Š\ V³íÖKp”¾>‚vç Æx™?žÕ¡_%Îû Øé¢±¼W|¤—féëÑS.Æá4¾ÞÅyfsQ…P–òÂSÀ‘¹€‹O[ð|Ä>nª0›Í&³Êh,̇4Ns<÷ˆ£ïÐÐ5ÂÚ¶“à –<úÕSø.éFÎ.P'Ð+z9e >+7‹óµu`×R Ùù‡Â@V{ (l_µ ¢¸/¤û6[b ø–)³j¡U½͸ËC£(›Nf  %Zj`hì¿uNÆ^Þr±“yœýÔ ²„,_6Ÿ¨°¨íE}Ð5–ƺCzÙøepá̸ðÙg¼g/S‘Hþ£‹…;ãâÂ(¯fÅŽõ¥œehïøvÉàÌû@.úˆ«ø°ç—› $_¨4Ê*ŒÉM16Ú:ò8‡çáƒÝªÎ gy5œ*9•îùÈŒØÜô×d¡¼ÕlÉ.Œé*²ÙPÖh·BS«ðJËé¸×á0(ÏáŒzTžMufViÇÛ¶ÜT÷bœåÞý(·¥YKa Ô瀪vÕ]a•šû~mõßµN'UíoŠ{[ëÍÿ—¶þS60)Q¬ WµÊ®R_>rŒ•¹ÀE`¸Fa^¹p¡‘{ù*éfç^K¿typì²0ªÙÉnÐ%%¾ï· ô”‰Õâð7¸€ROŽú 9ßÿrw”61>:º;¾ÿ¤³»_ ëȪOã÷°ìtÒpÎO²,D\ÄNÉ÷SÚxKÜò£¦E°«önY¹ºòÈ9¿fIðOœ-f{?éûŽËpÕ%XžSàšŸôÍjï ‡È»dtLNçíÕ5ïHc2ÖdºwLv¶U”™Á\Q,Ƀ„ÇãÒ˜L7Q“$›“ï°¸îöÌÚlkE;(› ÆZÛzG?¦Ú:rx€OÑÉãÌÿ©?XW{”.6Õ”1 á.yªï0–V–WšL*²‘ø{ˆjöþZJØtÂ…;µü-ÛTßx¨í0ú€YöR²™+΂AÍvXߣ†ÃÐԔ̓,0X ª*« 44ùbÃÜ'¢DÞÞ\eSÊ=ÉTHûM ô[Ѝö5(¤¹W«æ‘C„Å>7¤ !”¦A½DmÆÙªÒ…Õ%UåõP&c™Ù¸Š„Í" ¶HÖétŸHˆݤ5>q{†=§º¬ ”u”Û5­·ðð¬[¤©6CºT¶A•Í~˜»Ëñ¯SÈé&6ò÷ƒñá$þÈ[·yŸÒ&Fm'.“fƒµR¨q„¿¾öm27œxV,×ôätvsôµ”έœµT0¸ú£ŸUígÉRòô>"@.ëÂ_lUÅ€úaXá¨6G ¨6[  Ú9"ãŸXž“°Kë<ó%2Ý; ÜSn~À#‡ÊºCµ5ŸH•§œŠ§tQC²„k‹£¢ÌDß&Õ²ß-D»8é`û¤Å‡,­tx¬¨ ¬l(Õì[V+tSõ€£RA³3Ø-`±×¨n¢ÊÉlZÑa}ŸvNŒNÚQHä]“0ÞÙÇöM}äŸRݸ5BÜýw¯OÈò>]߸ ÁÎÌHîW.h²«#ï¼Ú–±òEäÿ4`ïÝU.|‡uÒâõ³*3À6·4·4µï8g8%’[A?œóÄdNèîì­ê@$âìÈáúÛƒ@Ú°¶êcT‰‘»‹`=Äœ-hã&uù½ÒtÅ(ʧ›â6¾’,¸ÉRì<žªë…¬.!±¸P©\L§þ¸óh{ß¹½oúYO|ÿŸÆë¿‘À öˆÍ§"WîÿU|’½Cdª€ô#ÇìK“ õr¢VëL<9©€S&(â\ÛJÍ–É¿Sy럜o®­±X š«-:X^à·œ(78· v:Oö¦õîNÊÉ/-¦†p‘S¼1µH e^â¿,'R ¤ìñE@ŠÐ€ æßèÍa>ô‡²iGòš‹à"œ¯i¸qÉÞ=ðv~Ãr:‡Ÿƒ-@ ù:]VVJ±¸)O”LU®ÁVÝ’=äxc‚å™ AX³‰È!¸lu‹âŒÚNân·•š°þ†èëÖ¤‘9w¶@O<ÊaéŠCñ7rÑŠ ¼FaÌ, Í/.-[ ùtxJÑ×óåÇu(ÿäƒaøšCOßéàöx|Óâ®üöî^Ç™DGbµpêÌhµ¸ëƒ«WîÔªUDG²ŠK¨Hå(sŒ׫ï]²( ¤=‹ns¿nÏJÜV©Û%ì?t¬OâK¼Tÿ -¢~q#©;Ê:æï#':J5‚¡"+—¶}Ž-¯Á@ÿ€°Ó‹ê'ÖÖ{-îkU=vÖå‰2/ÁÓ}y«÷´ãµÞÞ(k÷ö±xOg˜õV÷ endstream endobj 523 0 obj 3062 endobj 35 0 obj <> endobj 34 0 obj <>stream xœ­XiTTW¶¾EAÝ«‚8p[0ö-œ‚­¢48e@Gœ(™‘ D-æªÚUÅ 2HÈ cPÄÂb; 4®Il£&;$ÆÎð^Î%‡¤û\ˆ&ô[«ß[oÝ_Uuî9gïïûöþv‰(s3J$Yyz¸îܸq‘›×:§eÂöüs"~–ÿGqÖý7’iÑ=ëxzk* ¶FK§Pb‘ÈÃs¿[l\jBDX¸Ü~ÛŸìV­r±wIˆ:cïuP}PN>DÙïŒ Š‘§.±wвß!¼‘h¿#$1$!9$xìP·Øè¸$yH‚½WlpHB EQÎ[\Sc‚¼ÖÅ{»Å…l]ºÍ=!Ì#q‡Ê›r£VR“¨µ”-eE½LÙQ3)kê9jeC-'Y£hrHŸÈUÔlfmfÛˆSÅßš«-Ì-÷$žƒäGÚ‡î`¦ÂŒ g&úLÔOürR…¥¥e°åYËo¬¶Y Xý8ùØä»Öò)Ԕʩ–Sk¦­¶oÚëÓðtÛé%6‹l¼mÔ6o±{ÿ!òòÙ6™ &¤çE&Ñ0š#æßD¬L’í–†—â…Àlâ‡ÐD“$P¹ü !\ÇȆG‡e¼‚žü³ïtËÈûÏ™x½ˆwYÎfÖghR!ÃGŸØæ¦«•1ÊÃ*9¤#£Okºµ¯ÁYxCuJ͘è,w(×h´ºi[ X‰ ?g±R&1ê>…nè‚A0*Ó‹4¾Äï`?ÇÕØ[B޵¾6ËŒü“-æÝù lQµ¶è-T1ꈄÚcr æ"Wç*@-}'ÄÞÚŠ–fÕÙýÙ$‰Q{ª¢!öh#Ȳë4Z2:;+)qóñd»Xß°¬4È•&OSYX[ íL[⩈ؘ”`Y§ß¥^¿e:É‘[,‚çÅFÑ-$A.H"æSÐuv0ñ,vÛ¸5†S-Á¯fYÈèëE,Å×=dt“æš¶“vUÕDâ÷@!4hz½JŸëÌáÆÍ2Ú¨éÓvA/\Sé…$É¢ ñý9ݼu7 ÖMDSÅè ~1›™¥8rÆ¿#¥±¥Õpö׆µØvÅ2l<^C–ÍjAæeG!#=O}<Ë>œäé aU›Ú•Ú¥î…>æ: )ŸŸ,S)«¸É?l&¡ ôóåä>½Àâ¼:³.Wv8„ ~MI NT&)“!˜Ã2Ék“Ö¯AŸÊH.{˜N†dm¶&A¨eøv ä£ Žå7€òO”£4þk[ÍèG™¤C÷1ID܃‚±#?4lÂÁd B†¤÷Ú¬8­^#ª¸9%~¶¬cæß9Üz|Çûxb¥ôËš7®ÃûÌû=<ŸÃŽø-U#{úäMÀS]c7¯–â ø.‹zÑbZ­P'3Á.È„€Ì¨cIq~AÌd^Iò<Ý8–ç­ÈFÌG¢XÍvþÏÄìÒð|[“v,ÒÔÒll»pË Xî-¡áWsÞ†Gð|izûõ[žè»pßË€Ÿ×)‚j`4Úé8x· Í6òSºÇd¼‡ÀŽ Øõ@î’æÄŽãÀ ‰ß|„!‡%Åæ~Æ„J{hì.èºôP¦ªQBfF «o¾—­oi¯ïæb·'¶Æö{vï÷:ÝœBÎÝn1ät£-mhõÏŒûBÌ/D1l}‘¦i( M á²NÎDÏóÿ¾‚Ðfï7†“)›¦Ê=š+MôÞžD`34õª´Í\sQ‡è‡À|x®\:y$SqvD"T Gt_Hê&ô7eàùÈ »âXЧã#øš‡'¡uh3ú#š†ä¾Ø­à{&þJÔ{ê;ð>Ià`ÓÛmï_n0Áex3¬iCÃ'¬ƒµê 1nñ[vícôO-†Ÿ‰…f¡7ïuÊÐh ÙŸF (Û“°VJñœ§³üÐßéÛp#¦ÍûT@ñvÀb˜“µ3Ñ?r§WŒ›°©Èi¬·|kBqB…¥n¢ibÀÏf?7-øF‚&ÜÑ”éòAÏedMƒx& #¥¡¹Õpælx¯ÛÒyXÂ=¿]vK@éÐôjÏC'‰Fè&Ëʵ R@ÅgÐ…±Æ‡üI’PºÄ"[ ²þú=4 ‰\>Á’b<)WŸUuÃgãåŠÎá‡Ø‡dÞËW€¶’: )ìÒ&TÚ?¶ï“x„ë©Éø‡âÕÀÌCµ’Gùþë¤&Ô.“¬Ëó_Æ%¡Ò'´N¬ªÄæŒI…r,F[ÈÉ÷HÏ‘E­×¦Æ¥•Æ‡ãæœ0{c|ùqikdgÖùÌî¬ãàÅlóK÷s‹1½“ÆåU¨u)À$BŽ\ŠEt dž,ÒBùI® ¿¢¤@×{*I>­;ß¼Õrô„ôP[XQ`±¬Ô§.0ïijx&k9Mº6OÌ)(¨bFç§(Œ &ÔbD-¦i‚Ú¢‘ãŒéé|2Ñ÷ãúKoÃmæÛ…÷ðËþäo?ãí§ã¼E-ôôÞO$zh†S!úHH/ØyEI§W#qÁø«âá²:bR󲨥yþ‡bI˾œuCY—Ó§Ö)‚»ëÌÕ²kPËÇôlXïîøBQËõx@ŠšµÅ™Ð+zÑ $ùÌ$F{‰l‘• [¡2‰Ú%KžÏcÂnàFSw“ßþàôÍkÜ%™ís$<ÆÞ®!îJÄ „G__BË΋Qÿ#{.¬ý`@xx@@GxÏYcû9oÁn¤o^}FðÍíYÜűŽåÅ;Ðãež4˜ŸzDði‹ù¨§-F­N’sqqÁmª·“3ÕÝ›o3ø7’vû³&Õåveª.$Uïƒ@fÿá «×cËÓÈ>›SŸ„‚¤§øn÷D£©­ãšš®ø¿—Ývèï~‰&^K9ŸÐ.=x9¸äEClQD±"?âDL'¸ïÔåAä Ç³C 8]zªêÈãmu™PùxmÊ%ÆgdÎÈtvØ$ W:NãN—ã\T>l¢ó½€<ý›Š…ºP.îúý÷ô3K"ºôÌÊ¢7yïg~ćv ÷öÜ¢®íçÐW4öü¥¤£Þ}Üð&Üìä4$ÈýoB ûöÄ÷“ª5À\¯ˆP¶Ç”vôR s,L’dVtÙsaô#VèÐãSCžŸbñøIla•®pà׃¿ö¨00S+Ô ÎË.ÇÉ‹Îâò¿æŽN(/# ÙÕC~Ya•à®Dñý„dÇì½~ñˆ ÿ=û¿sCSh¼haÀ*Ìb{9Þõß»„Ƴ¾™Kšö’¿G3ž …º4®ÿ‘Íì¸9Chôu¢‰V2SôKz^Õþt¦x4+.Ljü[£`>& „ñeêg¿p½‚­á*§§“EkRµZÃò‹µÍÀ\kðÝ £ñ<%žá s˜•уg:z \2ì~Ä•èËá”>C«ÐHe:b –¼É®Øœ(?Ó‰Ìmyƒ–Ÿ³ #“hÄ–¦·Â¿ `ÈÕ$?!°W+€qÚ¡>¿4ºÝ»ò¾ `¯ é·1°ïÒ(ãG³Â´ü¬F°k]qQõ¿:]a¨uå×°hòjjÔåß;­ŠTG“SvA(Ùƒ®&(Õg(ó@•“‹{p—-ºöJ*–¾ù.Z‹« ³@j;E$sªÄö@ôUrz?( 2+˜q ŽyºŒ´ì0²)=QPôWáJ‘ª@u*$À¾ñÀ‰¯TWe¸/´}QçîS“Ò„iÙM¢ ì=Ï?šrˆg;ݬ½ !™‡Ë*ƒ0WÇhò´ÇŠï"sÛØÚâ€LÒ¬¹¡m€ÓpnŒÄ®ceæÝO5?¦ûíÓv½oðž8.åá]$ÉõÞÀ˜­ÌÿÃ<ûŸ ¼ÿ2 =3å>¿!öã>º¡A£1èk»cobõä.r@Ž ±È78=.BZ¸—mëéªh#4'–‡”‚N_ØŸ’q(1”È0RßEp1Ÿ°+nœ?,'l,¬Ò l<¤ RËÉ@ꢉ#Y§ ›xÎè[ìÀ{XÜØø"Ù34Ñ`B’Aú,ž2ßøŸ~E¡?š)Ȭ» (×ס¹üZ[RMÖgž»Z(,)¨&QtÕÀ;èEhîñ¥¼‚v)Ë(È+'st}MsCzáÑ)¶êCV}•…Ð`לPsøxV™˜_¬E35Åhíê+Ë“ŽÈ•8žîx_Qš›ì'¤DÇWæTäJ‘•/¶ò=š›žñvÑõ)úòâ¢bnøAž©ÎR+Ae—p꨾®¶ªN§ÎWà&£6¬øÁl@bTŠuìÀ ?˜ à…?¥ †Raà ÑÔr½è;ោ8þ ¶¤ ´PÈ4âZšxªXYÉÈ$Ḉô‚ö‚®UÅAr¦Äc©2OÅkï±[ ŠªLïpý4 "ç ï0ãEï&m…˜@kÄhçI6w±Ïö„¤ 26B“Y¦(®|2„fÝŒ¼¼ý@Tx@PcÈÅúšÒââ_]ˆ\ÿÕ‘L/ôúÉìo´P"\¿‡¿Û%‚OPÞ'bô˜§Ù?w6‚3_¼Ü?[y¯Z¼óÔŽ+!Üþè­þ°ŒÁ¶’ᆻý‰ø¥ áµvþ–UE×@'Ó¡þÒ->»¶ KIç°Ùör¨LÑ íI°‡Ù´;|ãªÀËïÜ×]]Á]‡¬/Ñ“ s7Í£÷ÑiVñªø¼­9ñéqŠÔØp_È„Üpº ®:˜vySpXœüàæÞm_>D+® ã;€ÊqàÚà¸ÈHÎÏÿèØÄàyóø¦êœ¦¯ž{é )§óš” ð¨"…êÂÆ|CMÛy¢•êˆâ²0·$ÃiÃÓ3–éebýÛÞðÔ…õttôü²Ù>[Æ›ý~>cþûwy%)Õ9¦s„ìÓÐ$1zwD̶æB·És„ 6€ ú«™Ñ2l.£;u@hfÃÐ)xfŒq=­dеèü ’»Æ†^‘0ÏÅ£{ì|×W}`ñ«‡‚Oè¤Í…mu`bz#[ü†Çí]}ÇY yw>ýîjô}lÝÄ]Ô¾ ˜»¤ ZÎñZç.kK4öÖ·¾fÈ<»«kiëÊ'>íºÆ+"v¥JSýU¡ªU¶Ò˜ÔR8ÉMV”¬+Ã…%ÈÏ ÁŠhÓDDMâ&š»è-'tYZ"ªÝÒJc9™¢þ :Y‹ endstream endobj 524 0 obj 4794 endobj 362 0 obj <> endobj 361 0 obj <>stream xœ­XyTSgÚ¿1’{UŠ¢Þ é Öµ"îV±uA+¸¡7ÜXDö@ØW„%$y„5ìHY\@AT\Z·ªS­«[­ZíNíô½ÌË™~op99í|ßœóòGι÷¾ï}žßö¼jø0J X»®~wû†-Ž«Ü=-¿ø? ø?ã_–â¼›Vm¶{8]²EA£‘ÓJ(¸®Û±J™ë0}Õ›s9¸„D‡øûE8¸ûÅ„ûÅ’‡ÍRÿ€Ø¤Y.‰ƒ§åŽÏ€˜€èø€}–5WIÃ#ãb¢Ü¥û¢#(J6wƒKR„²tߪȀ¨Àè ˜`·ØÍqña ¿Äð½ g¼e½h±“ó¬Ù¾sæ.7ù‚QÃÚ#Û©pŠr¢Þ vR›¨w©]”µššL½G¹Rž”µ™ZCm¡ÖRÓ©­Ô:jµÚNm ¼(wj%µƒÚH­¢^¥FQÈCì({ʆzM¡\([j,ÅQã¨ñ”Å FRóHÑ(š,ò¹ Fð÷a[†™…c„…í†+‡cµ×ê¢ÈQôÚÈ82}#D#v|e¤däÝQIÖ ¬£¬_9k#³]9fþ˜Ó¶¾¶ïu0ö‡qcÇmW>Þ~|Àx3ëÀ~uÖ«ÙÜ~l+ÕÚü:,ÃU æYÐÿPÈJY©H65ÅnÀ,íV¶ŠùFº#_÷ˆk1‹‚•sÀö€;xç1’zú–F(¬£U²e\¬„oÙü*v` ˜Ñ.3ïV+àÖ³Š2eQ ¤€*;;‡ >²K ^¦f$ôÁ<t@ԩϪ3í™›l†(Öh5ÚÄÚ!è4vÌ—ç*Aa¾¢8 },ïtÃ1ȃ»JÆœL»ƒ¬XÞÈàV¾ŠE#ñ+,#›ÆEüûø[f|!ä—£ÏÙRcõ‘˲J˜Ri I®TCöЭ‚ ÈYŽ<'s*ΰÃÃQEv9hAcol=g¦wªÔ~ OØGÞš>5*]$š7HÛÉ"³Ó2ã¶E¸­ƒhH.SjŠr‹ •1&VÆF'¥Dzwžú°ëý3 ÙÓì fþUƒàÖMxSȇ¢BîB“´-¶1 lÌ_×T)£þV„§È¬$ôµâ¬b\Kï‘ÁZòæ=ššÜãpÊÔ}–b­•A·­£ÿþÉ©K”íÜÄá”?¸Ò‹ìMmfl~\¸ð£¬µ?jjÀ=äóXÈSüël|NB*D0Qµ F£¾Ê|qõÁùx¼£¶ÅìÓ7ÑH$nA¯ëd ”*9›‹uÝåÌzçSh:šs§ç|ÙiUt‡øÙã¡‘·1ø)ü$¶¸4ÏTÈ!™ÃÉðb«FQAu² á¶A&ƒ<’ô6¥ª9ôXT…<­¤"9¦ya[`ðK+÷=dü ƒeËí÷„|" aÑ„IOñh€è)è3®k9bîƒN8o Ð¥€-;xäúEœyÀ‰ ¶ŸW˜„+Þf« 8=K©ÌÈæ¼V„™=ÏN{¼ /Æ ±7Þ‹–àyh Zòz(âÔ4ÈÊP‹3ñLlí2˜·ðÚ>tµ u}w¿ÿy~«A¬IËU”S Z½øÙKãmf4ÓÀOn´ ²îž•âEì3l9ÓÆ¨ÖÐ+¤Y£Ð°oÐ4öÍðÈ­;âöˆ/Ñxº£× ²}ŃÁ¿‹¼e¼‰m}ÿLm'0ŸžŸ‹),r›¿Ä;ÀØ#N«%ب±@ò¢cdpZ6Ô`å5!?%±uZÐÿ´ùkÒ]k§Ix žðó4dƒlz©/TdÈ•Y9jqÈ”yªý° öšb[C{Õç¡“Ém`‹Ñ¬‡•pÎûåâñÌs-xù–d:Â=~#- ˜¿û¶gq0)êH,pÄð¸þéhDçÉŠ3]büî"Þ»¨ÈÒäœý‘Ѿ~aÛ€qÙð%²BÌõ»·>í^¼Å†%#~$t·2#ApûúãB´ŸÌ"ÆŒG!+Ñ£Þc]%%ªœNž“’ÑLTM’ÁT]c<p`ËRgi¦ß‘ÜÆ}±‹>MYîI8 êKd ôJe)!?Õ²F§àÖõ_¾"WR¹#¥hqjZ¥&Ïa"õÉõúúŠæ–ðfïM~~ú©¿ñ;óû+ ï5¡ —î˜P–IgÑþ[­g…ȹ±†óþn`¾¾qív¯´5­\|¸½t Pf* ‰‘&Ö—W–èkRÍþÞ² `.²n_9!ÜÌUnïx5Uî«TÒ`â(!•A¦$¯ÿ@ØÍ¼û½'FÿÜwëHâÑÀnsÛ{0 25‰&B£JmEqÓŸÃ΃ïêLšÖªqE­©¢˜‡0#6fÌwãel ­^â¹ÌÛéM—ž3•%WîYúR 'LŸS'€“(í¤}Ë/â™BéiœJ•‘‘­ÔI BÙíBWz…•GÕlj[%³Nfœ”W)ë’K2 ‰ÀÌŸ ©S¢¾8Î)KÔéÀ¤Bf’§“!CW›[SÍå”–iµ{»•B£Ñ]7®K0ÅÕ‹Cº”GiW–Á9¦¥¾ó¢ Gk¸ÜtÈ&ü,‡ÂñoÃ"J`k`g°d3£F߈ž1r¨©ƒ•ÿ®!œš¤3£43?yH›ÜmB;ÙÃùÚ«Ä×[Øû`!wl¡ç¥Š7ÐØÏ„4gìÑ‹:~+AÜo%¥ÑÿIá|Ñ"¼y=¹ÑÞÛ(®Šl.¦Š+-]Ìï ˆ+Œ3£Åµ‚û7ÑkB´ÆB¯)f<mŠÔ‹‚'ÏP2Ñ÷q‡Ûwµíòuîœt+í" Z_VK¼ž9Äd(Â!!ÚIJÍ1 á’ØèˆˆúhssCC3‡§awâ—‹³ ]ô/êuL£Ï= •DÇ{I¡×åh‰y!ý¬mDÉç±¹Œ>»LkÀ™­…¢ô,µ:=‹KK*) Ýž\»ý„“ÅâÍ™²´g—V!>æS­@£¤Ÿ%«„äª[ÁƒqÛ¹bÎ2L Ø9“SW@AÚÈÄx+™ºÂÜ\]!WV-O;pêâ¦Ûò^2›Ï~øå\üјf±ïïÒuóõvo×F]†£ÌÕÓ—?Gì)Ç©å\^b®B7„³>@(ñê ¡üª—ηšž·cýªÅŠ®ÓúœÆŽŒÝå<1žAÃ:ðënJ8’uNAo}Óy&w±Mi‡ÑÏX¦ç_3 ø•è«?Ù¦kË% Wz÷ÄšTUû! äjUŽlÖÚa2* TPhol‡5_U¬Ú‚!‚,A¬‡dÅŠ@4#»‚”"e1C‘¦°ê¹ä“¾ŠšQTçP[;‘‘ýî‹îC×òȺÁJqÿpˆÊÝjY·B­Ë"é41%-#OÄ£ìø(úw©tTcÈí„#`P{I¥é˧ø¶ø´øØWÆ¥C*#W¦K†ÐÑ{šˆV5YÐ 1¹AÇŸÛü³b Ø¢ûlÝ…#ùzK1üɦB!RÁßòn]êòH"yrU¶2k6γ›ŠL„5ygo4kŒ¤{”{ɦ%¤a–ë[ V]šZ,+ó'AU¥ÚÇÙÍDeÙ–fo:4TÁ=¤‚þd±ÜEȮ҅ ÿÝN›ž'¯€ È/Í/éGì~Âòåù² °¯€¼’üæ[ÏJºa`û‡ŠÓ =P¥î}Y¦ç1΀â MOÚ ‚æÇèí›7…¼#Ò³$—µz <°«b0‹Vû­—蓦šZc—V-67sò\À|q(½UµB±&lUpÜvðgœ¿¼z÷à™ÆrNë×ÔŒáRÅñYéZ;‚‚àx%çrœ±"Üg·Oë‰+ç>BNÜKtX™è}ÇfC.ùh>ýº¨ÈÜÚÚpÁÒŽe$)R±ø¡vT¨Ê2I;R2dŠìõïØ-ý>«X¥!À]©®Þr}€*JmAóóá/ Qu{ü„Y»¸¨mkã¢wlòTŃädâ±€¢EÝb)Ntž² JH_Ë+ªÌÆfCóí©v5qäAÙ “§ÅX†¤N‚¤.ÒÄspÈ‚$‚ܸF‹.{%­x9OYþ…J‹;܇ÆÐŽøÝX;ý¤ÛÒ?ðo_oÃÎíñ{õwÿÕx¨OOœ?S½oõ;ÅqéKSù—¼}ë:2äéúoˆzLÏ fŸÒÓ`ÿ"‚ÚNÿ[»íŽŒçmd‰ä–V¶v÷V„.8cô3újð€517s¡@ULmSY»9®:2^šî?篳‘½òÓwh zeá÷X°kgJPðs¦ D"jhÁBTϱÈv^™œì«K+˫ӵr­O¼Œ&~X¢Õi¡Ú¾\V™¤P@F:‡mç”#'M™UYzyr|FŠŒ8n9 l¤•¨ ì“d)©I:E‰BŒ&®Ç×Éé$«Ù§–¦TkµP¬ãí£Tì¤J³JÓ¥Vé‹+K9U™Õ‹ÊñbÃݯ“¬þ…?¢×Èd ý¥çL§jô¾j¡;§>ˆ LIŒŒªNhl¬©n>ëß7‡LLñ8ƒÍš'HøÃcd‡ÆÍþ[mò Þ$£1øSÖB{Ò›©ïB%sÕŒ¨o*{Á½…« €$æï‚‰OŸ¬ÈÛ³xmû¤Ù°Q(¥{¼+›¢& R«ˆ–2Ø =}Òv®þ`vŒÛ—“-t&¼!¹Þ¤¯i<·åØÛÓ°õV[ýKØþ= CE éž‚´½b\÷Ÿ®ã‡ÑÏ‹¥ç/Þ!C¶dÐNãy6ë¬á± ,SÖ0RQ( cq~}ÑÙ2]aÁm('ð ÅEls‰—âW±[:^žŒ ¼»{àh×KšV‡˜¾/±<0Ú h<ŽßFÿdO4||>cž8™û†óŠÙåA \UbAÎûóý<6‚33ñç5ˆBÌwCÔ·.Ç£+9YQDuz!ƒ§}ņ×Äš ƒùð£CWn]ܺzõ¦=þ±Ü2¶3ªJ~Õ¯~ÿ‰0ØÈ¼óö®w¬¼x÷Ɖóµ[bÔ¶R-r¿(d¢ƒÈ½ˆMî/ŠÐØñÕç~¢A`|ŒÂ ùѨ›ÅJ,ôõŒõÊ?Å勊T‡Šà0cLª•J“Â×öù>D,ùØ!)jÀÖWæbzÊ,Ëpö•#²úøp_W5‡ÙwÙ‚а‹‰¡, sB°ù䡲v¸&×|yy`þFðeV†NrzôHÄ#_!ò:Í6ÅÂÃc¢#Âbš‡"Þó1'Oÿ͵à' ùí»Ø¼bM¾å#½0#%G–žÃáþ.Sf¨r Ç~¿.«¸2¿T—ÿüñüŸIQ]ÈÍȆ,Á{²¦DSpZZN†ŒÌD2*((¾Ò|áø1±F“—ZF›]˜%k¶^oôël«1™žo#Î00vh.¿'äÃÑÇ,\UÞ þÄçÉò†÷`,ñq sU,å°N3£ëž·>Mé†áfcçWÍW >; –àØpXUžˆ¬äÀ=b×à¶îLíƒËÕ­p.%ÔÌ*ÝKa¸Ã"¹G<¹È£á9¦¯:ÌG p_»%DçƱµ&šs_?›ä bH5pN™Ár:P™>‹ “ˆÚó\tB;±¨0z–Rg™…b_ ëB »0°B8àEÄ¢¼ôuq°_<ø‹hÄÅ×B™˜ÿöe+ê NŸ©âÁŠÒ >®*žË!ÜAýOûÉôñ…}%ä÷¢Õ¬T¤JËôHKÉÎp%ÆÌ`W‘¾öÊ%])ZŒÞ¸Ðý ¢gÞÁ£1½tΜ]ŠâºæÊöæø:‰B ê®áúå–ÓÀô·Ít²lñ®íb¼ï”Y£bíùq¢нMZú†üá"i I¿å /ÙûWÏÄãÝ‚¼ghoz‹ÛheDë#¢Ã÷ûÍ{ìŠBú‡ý÷]o:ê¹ÇmG?†¿0·Þ:?iÒRå¡u‰MMz}S[LEgì¼PKRûÝʵ»Ã³wEˆ%ÞÁªU4qžLÈPgªAƤA•d·zü~¦GW_&ûy|¹ñ{âš ¤dá›SrÊ\g2ÃIæ‚ï'Dî…ë׬ nH­7ÖÖ˜*3Í>\ë¹k…ÍD\†å®õ÷LJLNÏvl{)åd¨æãCãOxLLø¿qÌè53ïGPÑBÆÐ±i ÓÕêÔ 8h%AÆ…²\œDt)ï#âVZ¸—"âè–³„{ýæ)´ /bE,ú°]éð›#¢àOXŽfÈ7ÂŒ­‘•èáñîcy:È®ø÷S’Ž Ö÷b÷dùsñÿªÍÀLÂôæ7Äÿ7ý_NUðô3‹†Ñ?Þ;ø¡®UÒÌe(cäüò¼„z’ï!ƒx¦i›¸ºåuØT…"JEx¯Ž6¼9Š9|Q­õCµõÍJëW(ê#f%£ endstream endobj 525 0 obj 5200 endobj 359 0 obj <> endobj 358 0 obj <>stream xœcd`ab`ddäq  Õvö 2ñåH3þaú!Ëü±ûGîOÖuß{„¾ ~×çÿ®#ÀÀÌÈèæéœ_PY”™žQ¢ á¬©`hii®à˜›Z”™œ˜§à›X’‘š›Xää(ç'g¦–Tê)8æä(t+¥§•¥¦€¬tÎÏ-(-I-RðÍOI-Êc```4d`b`bddýÏØðúß&ËÂÝë,Y¿}>ãwÕ;Ìßÿ]ÖÙ“/çícЕÔ͑ξ¸ûl÷¡å&±guש˥¦³ÍíùÎß·¡{U÷w¡Ž…]ëSÙÕ»g¬‘ç+ŸÿÓ~þï%³¾çMeû8}=×-n9.óù<œË'óðÜšÍÃËÀøügs endstream endobj 526 0 obj 293 endobj 320 0 obj <> endobj 319 0 obj <>stream xœ•U LTg¾ÃîÕ"éM ëÞ ®‚ú(v`IPQŠ´ /©"Œ¼†‹(y sP¦ B‡Áé8‹¨ :$iuHdŒÜ~– ¿Ë„_Ò§Hü7fclËX·¥¸Ïƒ_Ƶn-‘„†ï Qçk²22µ²U!¾² ¯Ë¶æ*5Yi©y²ÈTm¦27U+T²Ýê´,¥¶xl«J%‹±gÊb”…JM‘2ÝÞ3D›P«ÔÈ"ÕéJMEQnyiêô|¥&Z›¥JÍMXKQoRÛ©·¨”M…R»©TNERÛ¨(JN¹Rîâ(C•R’„J&䣴Œ®r t,w¼ëäáÔâÆ83ü¼d¿_·ë¼CTØX7³dfsghá0NrVN,_•RXÆë¿u&+ʲ™;'«’¤ÄÈ$—Á.>›:1 }З`HÇZ™]epYŠ;™ïÿ0öÑGíû"xRüŸ"]ç%_ÈïUXðüƒN‹îcæ7´à(xsêcµZ(có;™MݧÏÞ~ãìZ"]Khòñx² —¢· Ÿ:U ºª}…ޝ*R­6rã(®BŸÏ'¦›®C±M¬ïà±…ª°Þf{õË÷iA‡Yºû E<‰§¡ˆ;q拯 ÷ôºó¤ŒÄrqj:hÓ\ÔÁ8œ‡[–!“íR×\ƒ!MOf_j}¤¢.VšŸ–\œìsø*̂ԌÊa{«sÓ4~5Ìý° &óüÞ®`Å~´áÈËß­À¥7ÇÌ6«4‚Á5ÍNVæÊÆ1©ðw&xîSŠ¡öÈ!uš¢p/( ­·p °f Fàæ‹=¶ÞËæ«0 £…gìÍç“Ь³+­x"4ž£gf9#4—Véõ¥ÇøÄ­ƒ;ÇVƒQ â/~“ñ×ÄS0Ð ]›¡©¤\WS¡—V’uÄ-ÄØÍ$æZð †ÝúÛ7Ȇ‘-&i}e}U°ÐØ)}>1‰·âj³°Ìb'å>FâÏ=ç@3’xµò}`щøºÿê;²$=º"!Qz›!¾v.ýÎP*Sþ,C‚…^®çÂøÀÇÀ~1µ™H"ÌT´çHË: :ÙäI3¡|a¿wha¾Ãyzî'=%ÞÄÍχ¸©•"g<ÆŸõ4èšKË몪ë¤~þºbHEwî•Ü+ð œeëM\Êîõ.‚â]¯µ7ét»' ƒ–ÌL#-Î!v€»¤¾=^][Q ZVÕ{´«·ÛØoË1§„§$í.âõß;“å?#—Á7 nÂq˜EpˆÙV×òK:ðÀ>ÿä3 :™»c€§ÓÂÈIî¡ Ý cQA6¡œÄ“=d {Å=¾F6büûç M¾{ÅéÍ_ûÄ„¯|ÐmGËôåUziuT’&R¡ 7çs–d9ï‹;ž±XÞ_# ò«É1âžN¨WßäӾݚìeºâÆ’†*)¸¬#¹µ`*‡ZÍ=ýçÇz3¢ÛíÚ=½i½¨­%V”wIÌà2 QÂr}­Ä#TÎúõû׬ӱêÄÄEН|záÖ]~RÇ„ª(Ãà/F^¬²ÒÇm_tAZĘÆaŽë×öeçhs2û‹L¶î~OüH”¨¦OšªE<;þ…ç$´C+Ü›ÝTÂk ƒRb^Týqx¡âîÙpî9åö1×úÓüè‚ ü‰)-˜†5}Ö‡&‘X_aÞÌ´…äx•{´f|½|kÎÎÜîb“¹³«¯÷HÇA?ðÞ4;9™ U1Ѻ0ÝŽ¼MÊÃÑÍú?.ølúòÅ gxƒÒ¤¶ù^Ã_¥7T±Ìþ#%EàJ |•ó (HKH±þöö\oQ¡ænyaÇyö—ž=#:ò3? ’Wy%|ñïcºÂÁ¡¥ùìÿëÏ_Ž}<Õ’û_üùtwÜöc~Q÷,o•ü,|ɵ]ê{ïf½ø;G—ª…'î›ÍLôä×@]M©”lšÛO‚„Ã5­¢NxY®A?oe6ëê ”"c“íá×ÁX×RÒTzú-Ѓ¾¶ôÄwn»§˜W²wÜËr}!Ïÿßó>„NhUâ¹gž†£ ÇŒÐï65´âvá¤'nŸkl(o(3‚—š mv•‹— îš’ÚhÁ]ܱ…3®â@ÁÝÄÔŽêfg’ÚÂXϼÄ/v|½Ëe‘Ùàâ2ctYBQÿâe endstream endobj 527 0 obj 1757 endobj 435 0 obj <> endobj 434 0 obj <>stream xœeoLSW‡ïí-—+"2\ Æyo³ç *›Ž°Q@ƒÑ©0CL Â-t ¥ ”xËßÖ–ÖámqÖYÌV6S³lùP:ËK¶/SL”8³/óÜìøaÝ–};¿÷=çù=9$!—$In*+.RUTì.(9~`&/L\ ™Ãå¦ÊÓZÎ0¡óÔ“™¯ÊÖŽ×O´pöŽžfhMÀ0ØHÓw¬LöŸ¥h J{:íÄÅÐÈV DʼnªèÑèÌL´ª¬¬ªêçÄ…Šˆ„·«‹ª^Û¥ºL]›þç æbäok攨·)®:Ü:ö=ºÓõŸ„ÀÏ]ÇZú@^·.¾³(˜øÿý0y»ùç/¿¹e‡˜æ.í» SW›ÀÊUÒR ÄDsŒDïÇ)4+þø¢ï§­MäœçÐÖgf¼u]¾GûC :8iþÂs1†dÏU&÷_Ìz•g@·‚)I 7|m¹ ¢¯¢4´ñ­?°ü¤¦½±ŽÃ[ässß/,Ízsߑêš_gY©à—zwå $R/SèP –öLCdZ ÝfG{`Z˃¶›ÅæmÒ‘€—CR¢mÀG¤ËÞ5Ôl@Ô $ˆ{(Q-ZçÆ|.0Ÿ›Ç­ý6°u°ø.®évØz¡u´úì®3h×§õ¹œÀLþI¡ËÝ3ÆeÍ¿1Ÿ9Çüøº¨ðº> endobj 431 0 obj <>stream xœcd`ab`ddäsöôu÷pÒvö 14‰Èýfü!ÃôC–yC÷i?ö±®üá(ôÝZð» ÿw}fFF7Ÿhçü‚Ê¢ÌôŒ gMCKKsÇÜÔ¢ÌäÄ<ßÄ’ŒÔÜÄ 'G!8?93µ¤ROÁ1'G!¤£X!(µ8µ¨,5b§s~nAiIj‘‚o~JjQ³¶ƒ,ƒ< ##{èêÿÿ™˜¦2ðÉ ¾[Ÿùn3Ÿñ{ÀæïÛ¾/ý®Ä6cu÷ê59ݵò¿•¾+³Íè^ÕS+÷[ù·2{]vwvÖªî™òß<¶ºîìÕkºWÍ”ƒ˜vdÁ˜ùŒÝ?4˜xý¨:iÚÄî¹ *§×Èuv5wuv74Kþ¾û;¥¾¥¥¡»^²»rZËä¶ïw~§JLjŸÜ:¥›cÖÜé ¦·Nm˜$ÿ{×w?V S}¾/>iÒ´îéÝs&5Oø}ç{ªDKóĦnŽšÊú²Êi­S[ä¿oûíó{Ûo߯–†ÖîJɲ¹õ³äz{&÷ôvO›,ÉW?ýÇ÷é¿C¦°ý®œÄ~”ë ·Ke>çQž3<¼ ™5¿ó endstream endobj 529 0 obj 451 endobj 429 0 obj <> endobj 428 0 obj <>stream xœcd`ab`ddä r Š Õvö ñ´ Èÿfü!ÃôC–ù;{÷æï ¬«¾' }7ünÈÿ]O€™‘ÑÍ;Ê9¿ ²(3=£DAÃYSÁÐÒÒ\Á17µ(391OÁ7±$#57±ÈÉQÎOÎL-©ÔSpÌÉQé(VJ-N-*KMÛ霟[PZ’Z¤à›Ÿ’Z”ÇÀÀÀ¨ÇÀÀÏÀÄÈÈ®õŸ1ßóßF« º¿30vgfþ^vZtQÕ‚üôÜÌÜ’9eËׯ\»RޝtáOû…¿—Mû^ÒÃö;qû*®‹Ür\,æóy8—Läáa`¹Q endstream endobj 530 0 obj 245 endobj 476 0 obj <> endobj 475 0 obj <>stream xœcd`ab`ddä‹òñ s ×vö ñ44‰Èýfü!ÃôC–ù;k÷÷Ÿ_YW}Oún*øÝˆÿ»¾3#£›O´s~AeQfzF‰‚†³¦‚¡¥¥¹‚cnjQfrbž‚obIFjnb “£œŸœ™ZR©§à˜“£ÒQ¬”ZœZT–š±Ó9?· ´$µHÁ7?%µ(QŸ‰‘‘]ó?cê1¾ÿŒF«teìþÎÈü½è”èÂêùÙY¹Y…s«–®]µf¥_éŸö /›ö½¸—íwâ4öU\ç¹å¸XÌçóp.œÂÃÃÀÆøR endstream endobj 531 0 obj 244 endobj 465 0 obj <> endobj 464 0 obj <>stream xœcd`ab`ddðó q óÖvöuŠñ44‰Éÿfü!ÃôC–ù;_÷£ïê¬k¿g }·ünÎÿÝD€™‘ÑÍ/Ö9¿ ²(3=£DAÃYSÁÐÒÒ\Á17µ(391OÁ7±$#57±ÈÉQÎOÎL-©ÔSpÌÉQé(VJ-N-*KMY뜟[PZ’Z¤à›Ÿ’Z”ÇÀÀÀ¨ÇÀÀÏÀÄÈÈ®õŸq^A߯ä>ƒîïêŒÝßµ˜¿/y,º®hqzRtjdÒªÊ;vlÙ%ÇW5ç§ÓœßÓ'Oíaû7™}×7n9.–Ê|ÎõÓxxzxøÑsSñ endstream endobj 532 0 obj 250 endobj 459 0 obj <> endobj 458 0 obj <>stream xœµXiT×¶®¶¥«§8”‚z«4ƒ³ADÅ)àPqFehf¡»{ÓÐÌsŒ *"¢‚¢Æ8Æ1jbÔ¨‰Æ)ÆÜëÍ)rȽït·¨÷®äÏ[ï­^ýVÞ»öþö·¿ïˆ¨ž=(‘HÔÇÅuÍšUKÇ;8»ÚL6þc„0L$ ï!üMœ‡½~ît·¨>tÔt¦?ò? Ä"Ñ¢¥nAÁÑ¡Ûü¶†ã0v„ÍŒv#æú†nóö’Žpö ßêèNþ±2È{›oxô§#æŒp5žáêæéëc êî:Â9ÈÇ7TJQÔd§ùRïuÎö1A>ë]‚}—-X¾0Ô/l«ëâðm+##ý¼Ö, ܼvê4»é3>d3Ùv EM¤>¤–Q ¨Ô§ÔGÔj9µšIYSS+¨EÔ$êʆE­¤>§VQŽ”-5†ZM-¡¦Pk¨qÔZʉr¦ì);jåB9PÓ©ÁÔÊ’²¢†Rý¨þÔj 5ˆb)[R2Ц܍»"OQ[™x¨8[ü¨§Sϳ+-îH–InÒv´Šþñf®¿7ûýß¿Ð˵·UïúÞ¯ú8öéêëÙ·±ßè~?èõAvÿ÷úw Ø9à×û­t›µc[Ïì1øÞ C4–6–ò‹mîûïÞæ¡Ó zz[,\D¹l„D6zˆ€™"ñPdïá…½tƒªàWkH¶°a2„©©–¾–!ÛÂwÕÐ[ä2n‡T ùÉ»=ïy„Z‘0¤Ó‰M+PdÅA(ä©;±o×S˸ÍA!K•Œ”>£RÁ¨#P¥` ´Wz¨Žü•*uá!de‰Ô’ØF [®ƒPNJ—«n‘Gjà”,hˆkf°FгˆÁ÷-p¬1¾s9„áZÑÍ Èû‚XXÒXx 5ụM³¶Á8ðž´ƒQþ]‚‡'XHéK9Én<® Ý` R¥:NBà¸9¯¥ñÐÊ#úÕå“gÏ­sápü_<¹BAYËôý·hÿÄ™î׋à&r¿+Fÿ$lüØVSQ®)2\\xd&~ïÓð<èÙXd,kQïÜÜd'*åñr>bÁêÀÕÀ¸Ìì@ÐÌ{Íí'b}Êùî › ÅÂ0a‹8´©´Âpðiº•öT$À:†¥NºD7Ë Ã ÒRRqo¼ÀCå™iÙ ¶*Ò•4p:L1¤ M}¥o@^ªÎ-õ–x6VÄ„ú{Û(­¤t‹*ŽB5\0×ÞKµ«J!_•‹F#K4 §f%¦+!Í â£c|Œ-®P}KÊSW¡Âxf9„Ax=)X6­yBéu1ŠéœÀ&k” ¶–j%fl¥ÓÁ°q‚©Ð¦¾w˜ =WóBK:Rþx?3!#)¬r n²ŠQZg_Ëô®’× ””«¾#à;SÖ;hyÞ>^¨¡÷eä]ã´l-‰¥2) K»¾²$Õ=à;‚à÷² ¹ÝD÷‰[:粂öÞÄ>|ðì¶ýw¸W!ÿ´ìòy¸ÁÜŸráð"|•E*z*û ‡H~i˜ºÚqít,æÇàYÓX!ZF?k·›3ÓeþXތРVZ=ÄBa4››*Èdò“!†Ã% ØÖB/ÉúU³‰€AŒ7uýÍ"ZzÝ’” '‹I"–ÄlÀ½H û9=É –é…ÉZ#koŠ´EìØ¿c÷ž0Òˆ¼_Æ# zÿùÏh‡·cwv ¸—HÛ‚[•_Âh„3u­5-Kê¡ DWûÔm'ØB8À9dcІMQ¾À˜§M¦¬µhÛ~c ²sbÔa,Ùë± ¡# žõ.$'fôX<|:õ¸y°]SÄ/¢ÑÈ< ½8)»þI/éºÎ’‰–ÇE„mÝ,]L¦òКkûõ{xmÝþºv8 õîy; b)D3ïºrK,ü,Üg÷t*h’• I5ÈTamÐí Û¥Ëvòø3\ƒ]Ðñ”d%È”©É|"¶ÅÌÂqÀ,Ä+ Vt-?xíÕO“ñ8-¯Šy0E¡åÍÀk ÈZ+LÔI·ä¦)ð ÖLötYh³ÏyZúåsÄ¢Æ"ÛNirþ"y#_ÉJöà»¶ÿ)¯ÎòXÐ@z~Imk›¦˜§'ី×â)s¤…š|xy¬jÞÒn°9˜0ŸtV, D±¬^š—«Ÿà>Xbû1þ[þ:‰Q¯VDé²R3S’©© >Äîóp/`¼FÕ ù¼†N×°9Èæ‡²ø ²ðÈômF´uª=#Ë;gë•õ{,î\‹~b‘7ž€&c{2ôcñì…=ÐxlƒÐb4Ù¢M¾…²Ÿ`Ëg()÷É 4l*NÅ…x¸õ8cõžëxœ[ÂàGâÊ7èï4 Eã3ZM8ÜÏäñà?>4Ó‰pÀL6¯$wá+ïfÇÖ0 ¼a¥r¢ëüí^Ë6Û™&µxò$Âm*Ðc,tâ±IaªÏ$è½ßn½|>î<ŒÇßÐï›à’ îkßàÞÄ¢ ¤aQ¥9ð šØÂÓ °Ûño‚3 }uD^ 7½¸s€Ia„áIa ðgd,†›%*D?˘ÊëQI„djBÀxn’KÌìi%A£¡n}1þ˜ÑKBP˜EWó›üªÞñq#ÝÅž¾÷zíŸûí–˜T+Ž}¾ÿÑ79*PfrIi;S ˜‘–'”hµ…ÕµÁ5žÓ¤ÖQ)œ‰%xèŸÈ€Õ òÆÕdw•¿žõüÞ̪ØK‡VŸ¸¯C*hïeäp¹©à 9²‡öC>0/^ú¦:©Ñ7ß´ÿ0¨!ÓøUÈÒReÀÄåŗ䔩õeq5[×úøÇÆqå[ —Ú|¾xŽký–¼D>>6Z >°¢>4'uÓ®M~°–YôÄõC½^tܨLþrY·®j=LH†h,/Q:(Í*Í+b^ÈX[xY^Í¥Õ¼ÆP›§æ ›c‚ù(i ,˜jŒØñöm_䨚«x}Q.\æ.²€)Ëçn´6¾eât5aõie"hEÑ­bt[˜e"‘¤¨ˆÄd. 2 Ë߸füW%ÀÖÆ­üɇO$Ê+w”ÅF@ãºÁÖqCã/\Z¤+Ó™i &R£y<œŽ†Ôö'Ö½YSP.=ð0YõM°/¡:h¯/DÂ"˜ !=‹c„ŸæÛº,ÈMAŠLɧ.“ûÃ&NêPf§´È+“ÛÓvÖ%ä‡T¯*f&°¸'*–@9è2sÓkA Ìm4ðø)—âÁ¤˜bjñ‘´Ë Œ1­Y·ÅJSfIeeh‡J“£kr´‹ÍZþ,”@±7ÚÕÕeêpAz†¹Ãvoo@† vlqIÓ¾’bâ¨ÿVSsKe‚W<¸“Ö.7·V§,K„ˆMNŒˆÄ§ðKt“nˇïMQg¨0Ãõû| 寠ÝÀŽ3Záw%m—mFiLdœqmfJf²*ÕJ•–ž )Lì4ùšœ©"-«7žY 1jÿ#FûlýÛ¼wn8ŒcÜéõ_;o:x-Ûé÷Íj½ÓÿÛ…ÇÿfQ¾kožCeÄ*Ìú/È>ÕÓ™95í™Ùå[Z|ÿÓ7ˆWm õÚÆ«V³Pªü’Іƒ†6`j_ÅãUŸË¼ÂüøÞëa5l­©Þ¥#ÒËØgñ‹ ¯áõ»‡ø÷þ¶äˆAÛn„—'—iðjsÛÎ(Ëü ¼RåIŠd<¡Kj‰§  ÌPä@†UmT˜=Ÿ4ZJÔ—Ézu@‘.Vˆª¡uÄ«;!ÌÆ(Ó”ÈÈÔDÉ’Ük\8Y¼ÕmÃŒò¯¤üîTC40†HmPXHœïäí×?> endobj 71 0 obj <> endobj 36 0 obj <> endobj 33 0 obj <> endobj 30 0 obj <> endobj 27 0 obj <> endobj 477 0 obj <> endobj 24 0 obj <> endobj 16 0 obj <> endobj 466 0 obj <> endobj 13 0 obj <> endobj 460 0 obj <> endobj 436 0 obj <> endobj 10 0 obj <> endobj 433 0 obj <> endobj 430 0 obj <> endobj 363 0 obj <> endobj 360 0 obj <> endobj 321 0 obj <> endobj 2 0 obj <>endobj xref 0 534 0000000000 65535 f 0000274743 00000 n 0000353455 00000 n 0000273802 00000 n 0000274791 00000 n 0000257169 00000 n 0000000015 00000 n 0000000389 00000 n 0000281996 00000 n 0000281757 00000 n 0000350942 00000 n 0000295845 00000 n 0000295294 00000 n 0000349255 00000 n 0000288958 00000 n 0000288551 00000 n 0000348313 00000 n 0000274860 00000 n 0000274890 00000 n 0000257337 00000 n 0000000408 00000 n 0000003725 00000 n 0000283734 00000 n 0000283394 00000 n 0000347513 00000 n 0000316626 00000 n 0000316420 00000 n 0000346903 00000 n 0000312694 00000 n 0000312407 00000 n 0000346467 00000 n 0000304966 00000 n 0000304370 00000 n 0000345956 00000 n 0000321571 00000 n 0000321199 00000 n 0000345501 00000 n 0000274944 00000 n 0000257489 00000 n 0000003746 00000 n 0000007773 00000 n 0000275042 00000 n 0000257633 00000 n 0000007794 00000 n 0000011099 00000 n 0000275107 00000 n 0000257777 00000 n 0000011120 00000 n 0000014790 00000 n 0000275172 00000 n 0000257921 00000 n 0000014811 00000 n 0000018872 00000 n 0000275248 00000 n 0000258065 00000 n 0000018893 00000 n 0000023150 00000 n 0000275313 00000 n 0000258209 00000 n 0000023171 00000 n 0000025867 00000 n 0000275356 00000 n 0000258353 00000 n 0000025888 00000 n 0000026083 00000 n 0000275399 00000 n 0000258497 00000 n 0000026103 00000 n 0000027628 00000 n 0000318028 00000 n 0000317726 00000 n 0000344701 00000 n 0000275431 00000 n 0000258641 00000 n 0000027649 00000 n 0000030071 00000 n 0000275507 00000 n 0000258785 00000 n 0000030092 00000 n 0000032113 00000 n 0000275561 00000 n 0000258929 00000 n 0000032134 00000 n 0000034308 00000 n 0000275626 00000 n 0000259073 00000 n 0000034329 00000 n 0000036682 00000 n 0000275680 00000 n 0000259217 00000 n 0000036703 00000 n 0000038840 00000 n 0000275745 00000 n 0000259361 00000 n 0000038861 00000 n 0000041021 00000 n 0000275810 00000 n 0000259505 00000 n 0000041042 00000 n 0000043354 00000 n 0000275875 00000 n 0000259650 00000 n 0000043375 00000 n 0000045931 00000 n 0000275930 00000 n 0000259797 00000 n 0000045953 00000 n 0000048669 00000 n 0000275996 00000 n 0000259944 00000 n 0000048691 00000 n 0000052062 00000 n 0000276051 00000 n 0000260091 00000 n 0000052084 00000 n 0000055345 00000 n 0000276139 00000 n 0000260238 00000 n 0000055367 00000 n 0000058085 00000 n 0000276205 00000 n 0000260385 00000 n 0000058107 00000 n 0000060715 00000 n 0000276260 00000 n 0000260532 00000 n 0000060737 00000 n 0000063569 00000 n 0000276326 00000 n 0000260679 00000 n 0000063591 00000 n 0000066150 00000 n 0000276381 00000 n 0000260826 00000 n 0000066172 00000 n 0000068626 00000 n 0000276436 00000 n 0000260973 00000 n 0000068648 00000 n 0000070687 00000 n 0000276491 00000 n 0000261120 00000 n 0000070709 00000 n 0000073593 00000 n 0000276557 00000 n 0000261275 00000 n 0000073615 00000 n 0000073814 00000 n 0000276612 00000 n 0000261422 00000 n 0000073835 00000 n 0000075729 00000 n 0000276645 00000 n 0000261569 00000 n 0000075751 00000 n 0000077111 00000 n 0000276722 00000 n 0000261716 00000 n 0000077133 00000 n 0000078367 00000 n 0000276777 00000 n 0000261863 00000 n 0000078389 00000 n 0000079546 00000 n 0000276832 00000 n 0000262010 00000 n 0000079568 00000 n 0000082109 00000 n 0000276898 00000 n 0000262157 00000 n 0000082131 00000 n 0000083298 00000 n 0000276964 00000 n 0000262304 00000 n 0000083320 00000 n 0000085481 00000 n 0000277030 00000 n 0000262451 00000 n 0000085503 00000 n 0000085702 00000 n 0000277096 00000 n 0000262598 00000 n 0000085723 00000 n 0000089133 00000 n 0000277129 00000 n 0000262745 00000 n 0000089155 00000 n 0000090620 00000 n 0000277206 00000 n 0000262892 00000 n 0000090642 00000 n 0000092138 00000 n 0000277261 00000 n 0000263039 00000 n 0000092160 00000 n 0000094069 00000 n 0000277327 00000 n 0000263186 00000 n 0000094091 00000 n 0000096417 00000 n 0000277393 00000 n 0000263333 00000 n 0000096439 00000 n 0000099437 00000 n 0000277448 00000 n 0000263480 00000 n 0000099459 00000 n 0000101647 00000 n 0000277503 00000 n 0000263627 00000 n 0000101669 00000 n 0000103405 00000 n 0000277569 00000 n 0000263774 00000 n 0000103427 00000 n 0000105743 00000 n 0000277624 00000 n 0000263921 00000 n 0000105765 00000 n 0000107945 00000 n 0000277690 00000 n 0000264068 00000 n 0000107967 00000 n 0000110214 00000 n 0000277745 00000 n 0000264215 00000 n 0000110236 00000 n 0000111658 00000 n 0000277811 00000 n 0000264362 00000 n 0000111680 00000 n 0000114737 00000 n 0000277866 00000 n 0000264509 00000 n 0000114759 00000 n 0000118070 00000 n 0000277954 00000 n 0000264656 00000 n 0000118092 00000 n 0000120970 00000 n 0000278020 00000 n 0000264803 00000 n 0000120992 00000 n 0000123471 00000 n 0000278097 00000 n 0000264950 00000 n 0000123493 00000 n 0000125911 00000 n 0000278152 00000 n 0000265097 00000 n 0000125933 00000 n 0000127796 00000 n 0000278229 00000 n 0000265244 00000 n 0000127818 00000 n 0000129479 00000 n 0000278295 00000 n 0000265391 00000 n 0000129501 00000 n 0000132306 00000 n 0000278350 00000 n 0000265538 00000 n 0000132328 00000 n 0000133542 00000 n 0000278416 00000 n 0000265685 00000 n 0000133564 00000 n 0000135136 00000 n 0000278471 00000 n 0000265832 00000 n 0000135158 00000 n 0000136813 00000 n 0000278548 00000 n 0000265979 00000 n 0000136835 00000 n 0000138892 00000 n 0000278603 00000 n 0000266126 00000 n 0000138914 00000 n 0000141170 00000 n 0000278658 00000 n 0000266273 00000 n 0000141192 00000 n 0000143926 00000 n 0000278724 00000 n 0000266420 00000 n 0000143948 00000 n 0000145249 00000 n 0000278790 00000 n 0000266567 00000 n 0000145271 00000 n 0000148282 00000 n 0000278845 00000 n 0000266714 00000 n 0000148304 00000 n 0000151435 00000 n 0000278911 00000 n 0000266861 00000 n 0000151457 00000 n 0000151656 00000 n 0000278966 00000 n 0000267008 00000 n 0000151677 00000 n 0000154049 00000 n 0000278999 00000 n 0000267155 00000 n 0000154071 00000 n 0000156652 00000 n 0000279076 00000 n 0000267302 00000 n 0000156674 00000 n 0000159571 00000 n 0000279131 00000 n 0000267449 00000 n 0000159593 00000 n 0000163400 00000 n 0000317263 00000 n 0000317039 00000 n 0000344555 00000 n 0000333028 00000 n 0000332778 00000 n 0000353030 00000 n 0000279197 00000 n 0000267604 00000 n 0000163422 00000 n 0000165992 00000 n 0000279289 00000 n 0000267751 00000 n 0000166014 00000 n 0000168682 00000 n 0000279344 00000 n 0000267898 00000 n 0000168704 00000 n 0000171527 00000 n 0000279399 00000 n 0000268045 00000 n 0000171549 00000 n 0000174394 00000 n 0000279454 00000 n 0000268192 00000 n 0000174416 00000 n 0000178077 00000 n 0000279509 00000 n 0000268339 00000 n 0000178099 00000 n 0000181278 00000 n 0000279564 00000 n 0000268494 00000 n 0000181300 00000 n 0000184147 00000 n 0000279630 00000 n 0000268641 00000 n 0000184169 00000 n 0000186435 00000 n 0000279685 00000 n 0000268788 00000 n 0000186457 00000 n 0000189831 00000 n 0000332376 00000 n 0000332166 00000 n 0000352891 00000 n 0000326856 00000 n 0000326474 00000 n 0000352095 00000 n 0000279740 00000 n 0000268943 00000 n 0000189853 00000 n 0000193068 00000 n 0000279821 00000 n 0000269090 00000 n 0000193090 00000 n 0000194760 00000 n 0000279876 00000 n 0000269237 00000 n 0000194782 00000 n 0000194981 00000 n 0000279931 00000 n 0000269384 00000 n 0000195002 00000 n 0000197685 00000 n 0000279964 00000 n 0000269531 00000 n 0000197707 00000 n 0000200421 00000 n 0000280030 00000 n 0000269678 00000 n 0000200443 00000 n 0000202429 00000 n 0000280074 00000 n 0000269825 00000 n 0000202451 00000 n 0000202650 00000 n 0000280129 00000 n 0000269972 00000 n 0000202671 00000 n 0000207030 00000 n 0000280162 00000 n 0000270119 00000 n 0000207052 00000 n 0000208918 00000 n 0000280239 00000 n 0000270266 00000 n 0000208940 00000 n 0000211612 00000 n 0000280283 00000 n 0000270413 00000 n 0000211634 00000 n 0000213413 00000 n 0000280360 00000 n 0000270560 00000 n 0000213435 00000 n 0000217709 00000 n 0000280415 00000 n 0000270707 00000 n 0000217731 00000 n 0000220737 00000 n 0000280470 00000 n 0000270854 00000 n 0000220759 00000 n 0000222769 00000 n 0000280514 00000 n 0000271001 00000 n 0000222791 00000 n 0000222990 00000 n 0000280558 00000 n 0000271148 00000 n 0000223011 00000 n 0000225932 00000 n 0000337250 00000 n 0000337036 00000 n 0000351955 00000 n 0000336476 00000 n 0000336251 00000 n 0000351738 00000 n 0000335136 00000 n 0000334895 00000 n 0000350505 00000 n 0000280591 00000 n 0000271295 00000 n 0000225954 00000 n 0000229573 00000 n 0000280698 00000 n 0000271450 00000 n 0000229595 00000 n 0000233039 00000 n 0000280768 00000 n 0000271597 00000 n 0000233061 00000 n 0000236933 00000 n 0000280851 00000 n 0000271744 00000 n 0000236955 00000 n 0000238966 00000 n 0000280921 00000 n 0000271891 00000 n 0000238988 00000 n 0000239187 00000 n 0000281004 00000 n 0000339096 00000 n 0000338748 00000 n 0000350059 00000 n 0000272038 00000 n 0000239208 00000 n 0000240210 00000 n 0000338389 00000 n 0000338172 00000 n 0000349112 00000 n 0000281037 00000 n 0000272185 00000 n 0000240231 00000 n 0000240431 00000 n 0000281096 00000 n 0000272332 00000 n 0000240452 00000 n 0000242446 00000 n 0000337819 00000 n 0000337604 00000 n 0000347372 00000 n 0000281131 00000 n 0000272479 00000 n 0000242468 00000 n 0000244560 00000 n 0000281212 00000 n 0000272626 00000 n 0000244582 00000 n 0000246444 00000 n 0000281282 00000 n 0000272773 00000 n 0000246466 00000 n 0000248513 00000 n 0000281352 00000 n 0000272920 00000 n 0000248535 00000 n 0000250232 00000 n 0000281422 00000 n 0000273067 00000 n 0000250254 00000 n 0000252231 00000 n 0000281468 00000 n 0000273214 00000 n 0000252253 00000 n 0000253780 00000 n 0000281538 00000 n 0000273361 00000 n 0000253802 00000 n 0000255706 00000 n 0000281584 00000 n 0000273508 00000 n 0000255728 00000 n 0000256925 00000 n 0000281654 00000 n 0000273655 00000 n 0000256947 00000 n 0000257148 00000 n 0000281724 00000 n 0000283372 00000 n 0000288529 00000 n 0000295272 00000 n 0000304348 00000 n 0000312385 00000 n 0000316398 00000 n 0000317018 00000 n 0000317705 00000 n 0000321177 00000 n 0000326452 00000 n 0000332144 00000 n 0000332757 00000 n 0000334873 00000 n 0000336229 00000 n 0000337015 00000 n 0000337583 00000 n 0000338151 00000 n 0000338727 00000 n 0000344533 00000 n trailer << /Size 534 /Root 1 0 R /Info 2 0 R >> startxref 353505 %%EOF ucblogo-5.5/docs/html/0040755000161300001330000000000010276035443012633 5ustar bhdoeucblogo-5.5/docs/html/usermanual_10.html0100644000161300001330000002214510276035442016175 0ustar bhdoe BERKELEY LOGO 5.5: ERROR PROCESSING
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10. Error Processing

10.1 Error Codes  

If an error occurs, Logo takes the following steps. First, if there is an available variable named ERRACT, Logo takes its value as an instructionlist and runs the instructions. The operation ERROR may be used within the instructions (once) to examine the error condition. If the instructionlist invokes PAUSE, the error message is printed before the pause happens. Certain errors are "recoverable"; for one of those errors, if the instructionlist outputs a value, that value is used in place of the expression that caused the error. (If ERRACT invokes PAUSE and the user then invokes CONTINUE with an input, that input becomes the output from PAUSE and therefore the output from the ERRACT instructionlist.)

It is possible for an ERRACT instructionlist to produce an inappropriate value or no value where one is needed. As a result, the same error condition could recur forever because of this mechanism. To avoid that danger, if the same error condition occurs twice in a row from an ERRACT instructionlist without user interaction, the message "Erract loop" is printed and control returns to toplevel. "Without user interaction" means that if ERRACT invokes PAUSE and the user provides an incorrect value, this loop prevention mechanism does not take effect and the user gets to try again.

During the running of the ERRACT instructionlist, ERRACT is locally unbound, so an error in the ERRACT instructions themselves will not cause a loop. In particular, an error during a pause will not cause a pause-within-a-pause unless the user reassigns the value [PAUSE] to ERRACT during the pause. But such an error will not return to toplevel; it will remain within the original pause loop.

If there is no available ERRACT value, Logo handles the error by generating an internal THROW "ERROR. (A user program can also generate an error condition deliberately by invoking THROW.) If this throw is not caught by a CATCH "ERROR in the user program, it is eventually caught either by the toplevel instruction loop or by a pause loop, which prints the error message. An invocation of CATCH "ERROR in a user program locally unbinds ERRACT, so the effect is that whichever of ERRACT and CATCH "ERROR is more local will take precedence.

If a floating point overflow occurs during an arithmetic operation, or a two-input mathematical function (like POWER) is invoked with an illegal combination of inputs, the `doesn't like' message refers to the second operand, but should be taken as meaning the combination.

See section erract , throw , error , catch , pause , continue .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.1 Error Codes

Here are the numeric codes that appear as the first member of the list output by ERROR when an error is caught, with the corresponding messages. Some messages may have two different codes depending on whether or not the error is recoverable (that is, a substitute value can be provided through the ERRACT mechanism) in the specific context. Some messages are warnings rather than errors; these will not be caught. Errors 0 and 32 are so bad that Logo exits immediately.

 
  0	Fatal internal error (can't be caught)
  1	Out of memory
  2	Stack overflow
  3	Turtle out of bounds
  4	PROC doesn't like DATUM as input (not recoverable)
  5	PROC didn't output to PROC
  6	Not enough inputs to PROC
  7	PROC doesn't like DATUM as input (recoverable)
  8	Too much inside ()'s
  9 	You don't say what to do with DATUM
 10	')' not found
 11	VAR has no value
 12	Unexpected ')'
 13	I don't know how to PROC (recoverable)
 14	Can't find catch tag for THROWTAG
 15	PROC is already defined
 16	Stopped
 17	Already dribbling
 18	File system error
 19	Assuming you mean IFELSE, not IF (warning only)
 20	VAR shadowed by local in procedure call (warning only)
 21	Throw "Error
 22	PROC is a primitive
 23	Can't use TO inside a procedure
 24	I don't know how to PROC (not recoverable)
 25	IFTRUE/IFFALSE without TEST
 26	Unexpected ']'
 27	Unexpected '}'
 28	Couldn't initialize graphics
 29	Macro returned VALUE instead of a list
 30	You don't say what to do with VALUE
 31	Can only use STOP or OUTPUT inside a procedure
 32	APPLY doesn't like BADTHING as input
 33	END inside multi-line instruction
 34	Really out of memory (can't be caught)


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_11.html0100644000161300001330000005336210276035442016203 0ustar bhdoe BERKELEY LOGO 5.5: SPECIAL VARIABLES
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

11. Special Variables

Logo takes special action if any of the following variable names exists. They follow the normal scoping rules, so a procedure can locally set one of them to limit the scope of its effect. Initially, no variables exist except for ALLOWGETSET, CASEIGNOREDP, and UNBURYONEDIT, which are TRUE and buried.

allowgetset  
caseignoredp  
erract  
fullprintp  
loadnoisily  
printdepthlimit  
printwidthlimit  
redefp  
startup  
unburyonedit  
usealternatenames  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

allowgetset

 
ALLOWGETSET                           (variable)

if TRUE, indicates that an attempt to use a procedure that doesn't exist should be taken as an implicit getter or setter procedure (setter if the first three letters of the name are SET) for a variable of the same name (without the SET if appropriate).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

caseignoredp

 
CASEIGNOREDP                                (variable)

if TRUE, indicates that lower case and upper case letters should be considered equal by EQUALP, BEFOREP, MEMBERP, etc. Logo initially makes this variable TRUE, and buries it.

See section equalp , beforep , memberp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erract

 
ERRACT                                      (variable)

an instructionlist that will be run in the event of an error. Typically has the value [PAUSE] to allow interactive debugging.

See section pause .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fullprintp

 
FULLPRINTP

if TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

loadnoisily

 
LOADNOISILY                                 (variable)

if TRUE, prints the names of procedures defined when loading from a file (including the temporary file made by EDIT).

See section edit .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

printdepthlimit

 
PRINTDEPTHLIMIT                             (variable)

if a nonnegative integer, indicates the maximum depth of sublist structure that will be printed by PRINT, etc.

See section print .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

printwidthlimit

 
PRINTWIDTHLIMIT                             (variable)

if a nonnegative integer, indicates the maximum number of members in any one list that will be printed by PRINT, etc.

See section print .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

redefp

 
REDEFP                                      (variable)

if TRUE, allows primitives to be erased (ERASE) or redefined (COPYDEF).

See section erase , copydef .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

startup

 
STARTUP                                     (variable)

if assigned a list value in a file loaded by LOAD, that value is run as an instructionlist after the loading.

See section load .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

unburyonedit

 
UNBURYONEDIT                            (variable)

if TRUE, causes any procedure defined during EDIT or LOAD to be unburied, so that it will be saved by a later SAVE. Files that want to define and bury procedures must do it in that order.

See section edit , See section load , See section save .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

usealternatenames

 
USEALTERNATENAMES					(variable)

if TRUE, causes Logo to generate non-English words (from the Messages file) instead of TRUE, FALSE, END, etc.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_12.html0100644000161300001330000002355110276035442016201 0ustar bhdoe BERKELEY LOGO 5.5: INTERNATIONALIZATION
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12. Internationalization

Berkeley Logo has limited support for non-English-speaking users. Alas, there is no Unicode support, and high-bit-on ASCII codes work in some contexts but not others.

If you want to translate Berkeley Logo for use with another language, there are three main things you have to do:

 
	1. Primitive names
	2. Error (and other) messages
	3. Documentation

For primitive names, the easiest thing is to provide a startup file that defines aliases for the English primitive names, using COPYDEF:

 
COPYDEF "AVANT "FORWARD

This should take care of it, unless your language's name for one primitive is spelled like the English name of a different primitive. In that case you have to turn REDEFP on and be sure to copy the non-conflicting name before overwriting the conflicting one!

"Primitives" that are actually in the Logo library, of course, can just be replaced or augmented with native-language-named Logo procedures and filenames.

Of course Logo programs will still not look like your native language if the word order is dramatically different, especially if you don't put verbs before their objects.

For error messages, there is a file named Messages in the logolib directory with texts of messages, one per line. You can replace this with a file for your own language. Do not add, delete, or reorder lines; Logo finds messages by line number. The sequences %p, %s, and %t in these messages represent variable parts of the message and should not be translated. (%p PRINTs the variable part, while %s SHOWs it -- that is, the difference is about whether or not brackets are shown surrounding a list. %t means that the variable part is a C text string rather than a Logo object.) If you want to change the order of two variable parts (no reorderable message has more than two), you would for example replace the line

 
%p doesn't like %s as input

with

 
%+s is a lousy input to %p

The plus sign tells the message printer to reverse the order; you must reverse the order of %p and %s, if both are used, to match. The plus sign goes just after the first percent sign in the message, which might not be at the beginning of the line. The sequence \n in a message represents a newline; don't be fooled into thinking that the "n" is part of the following word.

Some messages appear twice in the file; this isn't a mistake. The two spaces before "to" in "I don't know how to" aren't a mistake either. The message containing just "%p" is for user-provided error messages in THROW "ERROR. The message " in %s\n%s" is the part of all error messages that indicates where the error occurred if it was inside a procedure; you might want to change the word "in" to your language. "%s defined\n" is what LOAD prints for each procedure defined if the variable LOADNOISILY is TRUE. "to %p\nend\n\n" is what EDIT puts in the temporary file if you ask to edit a procedure that isn't already defined.

Also in the Messages file are lines containing only one word each; the first of these is the word "true". Some of these words are recognized by Logo in user input; some are generated by Logo; some are both. For example, the words TRUE and FALSE are recognized as Boolean values by IF and IFELSE, and are also generated by Logo as outputs from the primitive predicates such as EQUALP. The word END is recognized as the end of a procedure definition, and may be generated when Logo reconstructs a procedure body for PO or EDIT. I've used capital letters in this paragraph for easier reading, but the words in the Messages file should be in lower case.

If you replace these with non-English words, Logo will *recognize* both the English names and your alternate names. For example, if you replace the word "true" with "vrai" then Logo will understand both of these:

 
IF "TRUE [PRINT "YES]
IF "VRAI [PRINT "YES]

The variable UseAlternateNames determines whether Logo will *generate* other-language names -- for example, whether predicate functions return the other-language alternates for TRUE and FALSE. This variable is FALSE by default, meaning that the English words will be generated.

You might wish to have English-named predicate functions generate English TRUE and FALSE, while other-language-named predicates generate the alternate words. This can be done by leaving UseAlternateNames false, and instead of defining the other-language predicates with COPYDEF, do it this way:

 
to french.boolean :bool
if equalp :bool "true [output "vrai]
if equalp :bool "false [output "faux]
output :bool	; shouldn't happen
end

to make.french.predicate :french :english :arity
define :french `[[[inputs] ,[:arity]]
                 [output french.boolean
			    apply ,[word "" :english] :inputs]]
end

? make.french.predicate "egal? "equal? 2
? pr egal? 3 4
faux
? pr egal? 4 4
vrai
? pr equal? 3 4
false
? pr equal? 4 4
true

The third input to make.french.predicate is the number of inputs that the predicate expects. This solution isn't quite perfect because the infix predicates (=, <, >) will still output in English. If you want them to generate alternate-language words, set UseAlternateNames to TRUE instead.

Some of the words in this section of the Messages file are names of Logo primitives (OUTPUT, STOP, GOTO, TAG, IF, IFELSE, TO, .MACRO). To translate these names, you must use COPYDEF as described earlier, in addition to changing the names in Messages. You should be consistent in these two steps. Don't forget the period in ".macro"!

For documentation, there are two kinds: this manual and the help files. The latter are generated automatically from this manual if you have a Unix system, so in that case you need only translate this manual, maintaining the format. (The automatic helpfile generator notices things like capital letters, tabs, hyphens, and equal signs at the beginnings of lines.) The program makefile.c may require modification because a few of the primitive names are special cases (e.g., LOG10 is the only name with digits included).

If you don't have Unix tools, you can just translate each helpfile individually. A period in a primitive name is represented as a D in the filename; there are no files for question marks because the HELP command looks for the file named after the corresponding primitive that ends in P.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_13.html0100644000161300001330000007112710276035442016204 0ustar bhdoe BERKELEY LOGO 5.5: INDEX
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

INDEX

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  

Index Entry Section

*
*product

+
+sum

-
-difference

.
.defmacro.macro
.eq.eq
.macro.macro
.maybeoutput.maybeoutput
.setbf.setbf
.setfirst.setfirst
.setitem.setitem
.setsegmentsize.setsegmentsize

/
/quotient

<
<lessp
<=lessequalp
<>notequalp

=
=equalp

>
>greaterp
>=greaterequalp

`
``

A
allopenallopen
AllowGetSet1.2 Getter/Setter Variable Syntax
allowgetsetallowgetset
andand
applyapply
arcarc
arctanarctan
arityarity
arrayarray
array?arrayp
arrayparrayp
arraytolistarraytolist
asciiascii
ashiftashift

B
backback
backgroundbackground
backslashed?backslashedp
backslashedpbackslashedp
before?beforep
beforepbeforep
bfbutfirst
bfsbutfirsts
bgbackground
bitandbitand
bitnotbitnot
bitorbitor
bitxorbitxor
bkback
blbutlast
buriedburied
buried?buriedp
buriedpburiedp
burybury
buryallburyall
burynameburyname
butfirstbutfirst
butfirstsbutfirsts
butlastbutlast
buttonbuttonp
button?buttonp
buttonpbuttonp
byebye

C
cascadecascade
cascade.2cascade.2
casecase
case-insensitive1.4 Tokenization
caseignoredpcaseignoredp
catchcatch
charchar
cleanclean
clearscreenclearscreen
cleartextcleartext
closeclose
closeallcloseall
cocontinue
combinecombine
comments1.4 Tokenization
Computer_Science_Logo_Style1.1 Overview
condcond
contentscontents
continuecontinue
copydefcopydef
Copyright1.1 Overview
coscos
countcount
crossmapcrossmap
csclearscreen
cslsloadcslsload
ctcleartext
cursorcursor

D
definedefine
defined?definedp
definedpdefinedp
delimiters1.4 Tokenization
dequeuedequeue
differencedifference
do.untildo.until
do.whiledo.while
dribbledribble

E
ededit
edalledall
editedit
editfileeditfile
editoredit
ednedn
ednsedns
edpledpl
edplsedpls
edpsedps
empty?emptyp
emptypemptyp
eof?eofp
eofpeofp
epspictepspict
equal?equalp
equalpequalp
ererase
erallerall
eraseerase
erasefileerasefile
erferasefile
ernern
ernserns
erplerpl
erplserpls
erpserps
erracterract
errorerror
errors10.1 Error Codes
expexp

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_14.html0100644000161300001330000006167010276035442016207 0ustar bhdoe BERKELEY LOGO 5.5: INDEX: F -- O
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

INDEX: F -- O

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  

Index Entry Section

F
fdforward
fencefence
file?filep
filepfilep
fillfill
filterfilter
findfind
firstfirst
firstsfirsts
forfor
foreachforeach
foreverforever
formform
forwardforward
fputfput
fsfullscreen
fullprintpfullprintp
fullscreenfullscreen
fulltextfulltext

G
gcgc
gensymgensym
getter1.2 Getter/Setter Variable Syntax
globalglobal
gotogoto
gpropgprop
greater?greaterp
greaterequal?greaterequalp
greaterequalpgreaterequalp
greaterpgreaterp

H
headingheading
helphelp
hideturtlehideturtle
homehome
hthideturtle

I
ifif
ifelseifelse
iffiffalse
iffalseiffalse
iftiftrue
iftrueiftrue
ignoreignore
intint
invokeinvoke
iseqiseq
itemitem

K
key?keyp
keypkeyp

L
labellabel
lastlast
leaving ucblogo1.3 Entering and Leaving Logo
leftleft
less?lessp
lessequal?lessequalp
lessequalplessequalp
lessplessp
line-continuation1.4 Tokenization
listlist
list?listp
listplistp
listtoarraylisttoarray
lnln
loadload
loadnoisilyloadnoisily
loadpictloadpict
locallocal
localmakelocalmake
log10log10
logohelphelp
lowercaselowercase
lputlput
lshiftlshift
ltleft

M
macro?macrop
macroexpandmacroexpand
macropmacrop
makemake
mapmap
map.semap.se
mdarraymdarray
mditemmditem
mdsetitemmdsetitem
membermember
member?memberp
memberpmemberp
minusminus
modulomodulo
mouseposmousepos

N
namename
name?namep
namelistnamelist
namepnamep
namesnames
nodesnodes
nodribblenodribble
norefreshnorefresh
notnot
notequal?notequalp
notequalpnotequalp
number?numberp
numberpnumberp

O
opoutput
openappendopenappend
openreadopenread
openupdateopenupdate
openwriteopenwrite
oror
outputoutput

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_15.html0100644000161300001330000007640410276035442016211 0ustar bhdoe BERKELEY LOGO 5.5: INDEX: P -- S
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

INDEX: P -- S

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  

Index Entry Section

P
palettepalette
parseparse
pausepause
pcpencolor
pdpendown
pepenerase
penpen
pencolorpencolor
pendownpendown
pendown?pendownp
pendownppendownp
penerasepenerase
penmodepenmode
penpaintpenpaint
penpatternpensize
penreversepenreverse
pensizepensize
penuppenup
pickpick
plistplist
plist?plistp
plistpplistp
plistsplists
pllistpllist
popo
poallpoall
ponpon
ponspons
poppop
poplpopl
poplspopls
popspops
pospos
potpot
potspots
powerpower
pproppprop
pptpenpaint
prprint
prefixprefix
primitive?primitivep
primitivepprimitivep
primitivesprimitives
printprint
printdepthlimitprintdepthlimit
printoutpo
printwidthlimitprintwidthlimit
procedure?procedurep
procedurepprocedurep
proceduresprocedures
productproduct
pupenup
pushpush
pxpenreverse

Q
queuequeue
quotedquoted
quotientquotient

R
radarctanradarctan
radcosradcos
radsinradsin
randomrandom
rawasciirawascii
rcreadchar
rcsreadchars
readcharreadchar
readcharsreadchars
readerreader
readlistreadlist
readposreadpos
readrawlinereadrawline
readwordreadword
redefpredefp
reducereduce
refreshrefresh
remainderremainder
remdupremdup
removeremove
rempropremprop
repcountrepcount
repeatrepeat
rerandomrerandom
reversereverse
rightright
rlreadlist
roundround
rseqrseq
rtright
runrun
runparserunparse
runparsing1.4 Tokenization
runresultrunresult
rwreadword

S
savesave
savelsavel
savepictsavepict
screenmodescreenmode
scrunchscrunch
scrunch.datsetscrunch
sesentence
sentencesentence
setbackgroundsetbackground
setbgsetbackground
setcslslocsetcslsloc
setcursorsetcursor
seteditorseteditor
sethsetheading
setheadingsetheading
sethelplocsethelploc
setitemsetitem
setliblocsetlibloc
setmarginssetmargins
setpalettesetpalette
setpcsetpencolor
setpensetpen
setpencolorsetpencolor
setpenpatternsetpenpattern
setpensizesetpensize
setpossetpos
setprefixsetprefix
setreadsetread
setreadpossetreadpos
setscrunchsetscrunch
settcsettextcolor
settemplocsettemploc
setter1.2 Getter/Setter Variable Syntax
settextcolorsettextcolor
setwritesetwrite
setwritepossetwritepos
setxsetx
setxysetxy
setysety
shellshell
showshow
shown?shownp
shownpshownp
showturtleshowturtle
sinsin
splitscreensplitscreen
sqrtsqrt
sssplitscreen
stshowturtle
standoutstandout
starting ucblogo1.3 Entering and Leaving Logo
startupstartup
stepstep
steppedstepped
stepped?steppedp
steppedpsteppedp
stopstop
substring?substringp
substringpsubstringp
sumsum

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_16.html0100644000161300001330000003453610276035442016212 0ustar bhdoe BERKELEY LOGO 5.5: INDEX: T -- Y
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

INDEX: T -- Y

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  

Index Entry Section

T
tagtag
tempedit
template8.2 Template-based Iteration
testtest
texttext
textscreentextscreen
thingthing
throwthrow
toto
towardstowards
tracetrace
tracedtraced
traced?tracedp
tracedptracedp
transfertransfer
tstextscreen
turtlemodeturtlemode
typetype

U
unburyunbury
unburyallunburyall
unburynameunburyname
unburyoneditunburyonedit
unstepunstep
untiluntil
untraceuntrace
uppercaseuppercase
usealternatenamesusealternatenames

W
waitwait
whilewhile
windowwindow
wordword
wordpwordp
wrapwrap
writeposwritepos
writerwriter

X
xcorxcor

Y
ycorycor

Jump to:   *   +   -   .   /   <   =   >   `  
A   B   C   D   E   F   G   H   I   K   L   M   N   O   P   Q   R   S   T   U   W   X   Y  


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_1.html0100644000161300001330000007057210276035441016123 0ustar bhdoe BERKELEY LOGO 5.5: INTRODUCTION
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1. Introduction

1.1 Overview  
1.2 Getter/Setter Variable Syntax  
1.3 Entering and Leaving Logo  
1.4 Tokenization  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 Overview

Copyright (C) 1993 by the Regents of the University of California

This program 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 of the License, or (at your option) any later version.

This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

This is a program that is still being written. Many things are missing, including adequate documentation. This manual assumes that you already know how to program in Logo, and merely presents the details of this new implementation.

Read Computer_Science_Logo_Style, Volume_1:_ _Symbolic_Computing_ by Brian Harvey (MIT Press, 1997) for a tutorial on Logo programming with emphasis on symbolic computation.

Here are the special features of this dialect of Logo:

 
Source file compatible among Unix, DOS, Windows, and Mac platforms.

Random-access arrays.

Variable number of inputs to user-defined procedures.

Mutators for list structure (dangerous).

Pause on error, and other improvements to error handling.

Comments and continuation lines; formatting is preserved when
procedure definitions are saved or edited.

Terrapin-style tokenization (e.g., [2+3] is a list with one member)
but LCSI-style syntax (no special forms except TO).  The best of
both worlds.

First-class instruction and expression templates (see APPLY).

Macros.

Features not found in Berkeley Logo include robotics, music, GUIs, animation, parallelism, and multimedia. For those, buy a commercial version.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Getter/Setter Variable Syntax

Logo distinguishes PROCEDURES from VARIABLES. A procedure is a set of instructions to carry out some computation; a variable is a named container that holds a data value such as a number, word, list, or array.

In traditional Logo syntax, a non-numeric word typed without punctuation represents a request to invoke the procedure named by that word. A word typed with a preceding quotation mark represents the word itself. For example, in the instruction
 
	PRINT FIRST "WORD
the procedures named FIRST and PRINT are invoked, but the procedure named WORD is not invoked; the word W-O-R-D is the input to FIRST.

What about variables? There are two things one can do with a variable: give it a value, and find out its value. To give a variable a value, Logo provides the primitive procedure MAKE, which requires two inputs: the name of the variable and the new value to be assigned. The first input, the name of the variable, is just a word, and if (as is almost always the case) the programmer wants to assign a value to a specific variable whose name is known in advance, that input is quoted, just as any known specific word would be:
 
	MAKE "MY.VAR FIRST "WORD
gives the variable named MY.VAR the value W (the first letter of WORD).

To find the value of a variable, Logo provides the primitive procedure THING, which takes a variable name as its input, and outputs the value of the accessible variable with that name. Thus
 
	PRINT THING "MY.VAR
will print W (supposing the MAKE above has been done). Since finding the value of a specific, known variable name is such a common operation, Logo also provides an abbreviated notation that combines THING with quote:
 
	PRINT :MY.VAR
The colon (which Logo old-timers pronounce "dots") replaces THING and " in the earlier version of the instruction.

Newcomers to Logo often complain about the need for all this punctuation. In particular, Logo programmers who learned about dots and quotes without also learning about THING wonder why an instruction such as
 
	MAKE "NEW.VAR :OLD.VAR
uses two different punctuation marks to identify the two variables. (Having read the paragraphs above, you will understand that actually both variable names are quoted, but the procedure THING is invoked to find the value of OLD.VAR, since it's that value, not OLD.VAR's name, that MAKE needs to know. It wouldn't make sense to ask for THING of NEW.VAR, since we haven't given NEW.VAR a value yet.)

Although Logo's punctuation rules make sense once understood, they do form a barrier to entry for the Logo beginner. Why, then, couldn't Logo be designed so that an unpunctuated word would represent a procedure if there is a procedure by that name, or a variable if there is a variable by that name? Then we could say
 
	PRINT MY.VAR
and Logo would realize that MY.VAR is the name of a variable, not of a procedure. The traditional reason not to use this convention is that Logo allows the same word to name a procedure and a variable at the same time. This is most often important for words that name data types, as in the following procedure:
 
	TO PLURAL :WORD
	OUTPUT WORD :WORD "S
	END
Here the name WORD is a natural choice for the input to PLURAL, since it describes the kind of input that PLURAL expects. Within the procedure, we use WORD to represent Logo's primitive procedure that combines two input words to form a new, longer word; we use :WORD to represent the variable containing the input, whatever actual word is given when PLURAL is invoked.
 
	? PRINT PLURAL "COMPUTER
	COMPUTERS

However, if a Logo instruction includes an unquoted word that is not the name of a procedure, Logo could look for a variable of that name instead. This would allow a "punctuationless" Logo, * PROVIDED THAT USERS WHO WANT TO WORK WITHOUT COLONS FOR VARIABLES CHOOSE VARIABLE NAMES THAT ARE NOT ALSO PROCEDURE NAMES. *

What about assigning a value to a variable? Could we do without the quotation mark on MAKE's first input? Alas, no. Although the first input to MAKE is usually a constant, known variable name, sometimes it isn't, as in this example:
 
	TO INCREMENT :VAR
	MAKE :VAR (THING :VAR)+1	; Note: it's not "VAR here!
	END

	? MAKE "X 5
	? INCREMENT "X
	? PRINT :X
	6
The procedure INCREMENT takes a variable name as its input and changes the value of that variable. In this example there are two variables; the variable whose name is VAR, and whose value is the word X; and the variable whose name is X and whose value changes from 5 to 6. Suppose we changed the behavior of MAKE so that it took the word after MAKE as the name of the variable to change; we would be unable to write INCREMENT:
 
	TO INCREMENT :VAR		; nonworking!
	MAKE VAR (THING VAR)+1
	END
This would assign a new value to VAR, not to X.

What we can do is to allow an alternative to MAKE, a "setter" procedure for a particular variable. The notation will be
 
	? SETFOO 7
	? PRINT FOO
	7
SETFOO is a "setter procedure" that takes one input (in this case the input 7) and assigns its value to the variable named FOO.

Berkeley Logo allows users to choose either the traditional notation, in which case the same name can be used both for a procedure and for a variable, or the getter/setter notation, in which variable FOO is set with SETFOO and examined with FOO, but the same name can't be used for procedure and variable.

Here is how this choice is allowed: Berkeley Logo uses traditional notation, with procedures distinct from variables. However, if there is a variable named AllowGetSet whose value is TRUE (which there is, by default, when Logo starts up), then if a Logo instruction refers to a nonexistent procedure (so that the error message "I don't know how to ..." would result), Logo tries the following two steps:

 
	1.  If the name is at least four characters long, and the first three
	characters are the letters SET (upper or lower case), and if the name
	is followed in the instruction by another value, and if the name
	without the SET is the name of a variable that already exists, then
	Logo will invoke MAKE with its first input being the name without the
	SET, and its second input being the following value.

	2.  If step 1's conditions are not met, but the name is
	the name of an accessible variable, then Logo will invoke
	THING with that name as input, to find the variable's value.

Step 1 requires that the variable already exist so that misspellings of names of SETxxx primitives (e.g., SETHEADING) will still be caught, instead of silently creating a new variable. The command GLOBAL can be used to create a variable without giving it a value.

One final point: The TO command in Logo has always been a special case; the rest of the line starting with TO is not evaluated as ordinary Logo expressions are. In particular, the colons used to mark the names of inputs to the procedure do not cause THING to be invoked. They are merely mnemonic aids, reminding the Logo user that these words are names of variables. (Arguably, this nonstantard behavior of TO adds to Logo beginners' confusion about colons.) To a programmer using colonless variable references, the colons in the TO line are unnecessary and meaningless. Berkeley Logo therefore makes the colons optional:
 
	TO FOO :IN1 :IN2
and
 
	TO FOO IN1 IN2
are both allowed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3 Entering and Leaving Logo

The process to start Logo depends on your operating system:

`Unix:'
Type the word logo to the shell. (The directory in which you've installed Logo must be in your path.)

`DOS:'
Change directories to the one containing Logo (probably C:\UCBLOGO). Then type UCBLOGO for the large memory version, or BL for the 640K version.

`Mac:'
Double-click on the LOGO icon within the "UCB Logo" folder.

`Windows:'
Double-click on the UCBWLOGO icon in the UCBLOGO folder.

To leave Logo, enter the command bye.

After initialization, Logo looks for a file in the current working directory named startup.lg and, if one is found, executes the Logo instructions in it. Then, under Unix, DOS, or Windows, if you include one or more filenames on the command line when starting Logo, those files will be loaded before the interpreter starts reading commands from your terminal. If you load a file that executes some program that includes a BYE command, Logo will run that program and exit. You can therefore write standalone programs in Logo and run them with shell/batch scripts. To support this technique, Logo does not print its usual welcoming and parting messages if you give file arguments to the logo command.

If you type your interrupt character (see table below) Logo will stop what it's doing and return to top-level, as if you did THROW "TOPLEVEL. If you type your quit character Logo will pause as if you did PAUSE.

 
                Unix           DOS/Windows          Mac

toplevel    usually ctrl-C       ctrl-Q      command-. (period)

pause       usually ctrl-\       ctrl-W      command-, (comma)

If you have an environment variable called LOGOLIB whose value is the name of a directory, then Logo will use that directory instead of the default library. If you invoke a procedure that has not been defined, Logo first looks for a file in the current directory named proc.lg where proc is the procedure name in lower case letters. If such a file exists, Logo loads that file. If the missing procedure is still undefined, or if there is no such file, Logo then looks in the library directory for a file named proc (no .lg) and, if it exists, loads it. If neither file contains a definition for the procedure, then Logo signals an error. Several procedures that are primitive in most versions of Logo are included in the default library, so if you use a different library you may want to include some or all of the default library in it.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4 Tokenization

Names of procedures, variables, and property lists are case-insensitive. So are the special words END, TRUE, and FALSE. Case of letters is preserved in everything you type, however.

Within square brackets, words are delimited only by spaces and square brackets. [2+3] is a list containing one word. Note, however, that the Logo primitives that interpret such a list as a Logo instruction or expression (RUN, IF, etc.) reparse the list as if it had not been typed inside brackets.

After a quotation mark outside square brackets, a word is delimited by a space, a square bracket, or a parenthesis.

A word not after a quotation mark or inside square brackets is delimited by a space, a bracket, a parenthesis, or an infix operator +-*/=<>. Note that words following colons are in this category. Note that quote and colon are not delimiters. Each infix operator character is a word in itself, except that the two-character sequences <= >= and <> (the latter meaning not-equal) with no intervening space are recognized as a single word.

A word consisting of a question mark followed by a number (e.g., ?37), when runparsed (i.e., where a procedure name is expected), is treated as if it were the sequence

 
( ? 37 )

making the number an input to the ? procedure. (See the discussion of templates, below.) This special treatment does not apply to words read as data, to words with a non-number following the question mark, or if the question mark is backslashed.

A line (an instruction line or one read by READLIST or READWORD) can be continued onto the following line if its last character is a tilde (~). READWORD preserves the tilde and the newline; READLIST does not.

Lines read with READRAWLINE are never continued.

An instruction line or a line read by READLIST (but not by READWORD) is automatically continued to the next line, as if ended with a tilde, if there are unmatched brackets, parentheses, braces, or vertical bars pending. However, it's an error if the continuation line contains only the word END; this is to prevent runaway procedure definitions. Lines explicitly continued with a tilde avoid this restriction.

If a line being typed interactively on the keyboard is continued, either with a tilde or automatically, Logo will display a tilde as a prompt character for the continuation line.

A semicolon begins a comment in an instruction line. Logo ignores characters from the semicolon to the end of the line. A tilde as the last character still indicates a continuation line, but not a continuation of the comment. For example, typing the instruction

 
print "abc;comment ~
def

will print the word abcdef. Semicolon has no special meaning in data lines read by READWORD or READLIST, but such a line can later be reparsed using RUNPARSE and then comments will be recognized.

The two-character sequence #! at the beginning of a line also starts a comment. Unix users can therefore write a file containing Logo commands, starting with the line
 
#! /usr/local/bin/logo
(or wherever your Logo executable lives) and the file will be executable directly from the shell.

To include an otherwise delimiting character (including semicolon or tilde) in a word, precede it with backslash (\). If the last character of a line is a backslash, then the newline character following the backslash will be part of the last word on the line, and the line continues onto the following line. To include a backslash in a word, use \\. If the combination backslash-newline is entered at the terminal, Logo will issue a backslash as a prompt character for the continuation line. All of this applies to data lines read with READWORD or READLIST as well as to instruction lines. A character entered with backslash is EQUALP to the same character without the backslash, but can be distinguished by the BACKSLASHEDP predicate. (However, BACKSLASHEDP recognizes backslashedness only on characters for which it is necessary: whitespace, parentheses, brackets, infix operators, backslash, vertical bar, tilde, quote, question mark, colon, and semicolon.)

A line read with READRAWLINE has no special quoting mechanism; both backslash and vertical bar (described below) are just ordinary characters.

An alternative notation to include otherwise delimiting characters in words is to enclose a group of characters in vertical bars. All characters between vertical bars are treated as if they were letters. In data read with READWORD the vertical bars are preserved in the resulting word. In data read with READLIST (or resulting from a PARSE or RUNPARSE of a word) the vertical bars do not appear explicitly; all potentially delimiting characters (including spaces, brackets, parentheses, and infix operators) appear as though entered with a backslash. Within vertical bars, backslash may still be used; the only characters that must be backslashed in this context are backslash and vertical bar themselves.

Characters entered between vertical bars are forever special, even if the word or list containing them is later reparsed with PARSE or RUNPARSE. Characters typed after a backslash are treated somewhat differently: When a quoted word containing a backslashed character is runparsed, the backslashed character loses its special quality and acts thereafter as if typed normally. This distinction is important only if you are building a Logo expression out of parts, to be RUN later, and want to use parentheses. For example,

 
PRINT RUN (SE "\( 2 "+ 3 "\))

will print 5, but

 
RUN (SE "MAKE ""|(| 2)

will create a variable whose name is open-parenthesis. (Each example would fail if vertical bars and backslashes were interchanged.)


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_2.html0100644000161300001330000031134710276035441016122 0ustar bhdoe BERKELEY LOGO 5.5: DATA STRUCTURE PRIMITIVES
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. Data Structure Primitives

2.1 Constructors  
2.2 Data Selectors  
2.3 Data Mutators  
2.4 Predicates  
2.5 Queries  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.1 Constructors

word  
list  
sentence  
fput  
lput  
array  
mdarray  
listtoarray  
arraytolist  
combine  
reverse  
gensym  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

word

 
WORD word1 word2
(WORD word1 word2 word3 ...)

outputs a word formed by concatenating its inputs.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

list

 
LIST thing1 thing2
(LIST thing1 thing2 thing3 ...)

outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

sentence

 
SENTENCE thing1 thing2
SE thing1 thing2
(SENTENCE thing1 thing2 thing3 ...)
(SE thing1 thing2 thing3 ...)

outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fput

 
FPUT thing list

outputs a list equal to its second input with one extra member, the first input, at the beginning. If the second input is a word, then the first input must be a one-letter word, and FPUT is equivalent to WORD.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

lput

 
LPUT thing list

outputs a list equal to its second input with one extra member, the first input, at the end. If the second input is a word, then the first input must be a one-letter word, and LPUT is equivalent to WORD with its inputs in the other order.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

array

 
ARRAY size
(ARRAY size origin)

outputs an array of size members (must be a positive integer), each of which initially is an empty list. Array members can be selected with ITEM and changed with SETITEM. The first member of the array is member number 1 unless an origin input (must be an integer) is given, in which case the first member of the array has that number as its index. (Typically 0 is used as the origin if anything.) Arrays are printed by PRINT and friends, and can be typed in, inside curly braces; indicate an origin with {a b c}@0.

See section item , setitem , print .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

mdarray

 
MDARRAY sizelist				(library procedure)
(MDARRAY sizelist origin)

outputs a multi-dimensional array. The first input must be a list of one or more positive integers. The second input, if present, must be a single integer that applies to every dimension of the array.

Ex: (MDARRAY [3 5] 0) outputs a two-dimensional array whose members range from [0 0] to [2 4].


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

listtoarray

 
LISTTOARRAY list
(LISTTOARRAY list origin)

outputs an array of the same size as the input list, whose members are the members of the input list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

arraytolist

 
ARRAYTOLIST array

outputs a list whose members are the members of the input array. The first member of the output is the first member of the array, regardless of the array's origin.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

combine

 
COMBINE thing1 thing2				(library procedure)

if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2.

See section word , fput


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

reverse

 
REVERSE list					(library procedure)

outputs a list whose members are the members of the input list, in reverse order.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

gensym

 
GENSYM						(library procedure)

outputs a unique word each time it's invoked. The words are of the form G1, G2, etc.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2 Data Selectors

first  
firsts  
last  
butfirst  
butfirsts  
butlast  
item  
mditem  
pick  
remove  
remdup  
quoted  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

first

 
FIRST thing

if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

firsts

 
FIRSTS list

outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as

 
to firsts :list
output map "first :list
end

but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH.

 
to transpose :matrix
if emptyp first :matrix [op []]
op fput firsts :matrix transpose bfs :matrix
end

See section map , map.se , foreach


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

last

 
LAST wordorlist

if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

butfirst

 
BUTFIRST wordorlist
BF wordorlist

if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

butfirsts

 
BUTFIRSTS list
BFS list

outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as

 
to butfirsts :list
output map "butfirst :list
end

but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH.

See section map , map.se , foreach


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

butlast

 
BUTLAST wordorlist
BL wordorlist

if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

item

 
ITEM index thing

if the thing is a word, outputs the indexth character of the word. If the thing is a list, outputs the indexth member of the list. If the thing is an array, outputs the indexth member of the array. Index starts at 1 for words and lists; the starting index of an array is specified when the array is created.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

mditem

 
MDITEM indexlist array				(library procedure)

outputs the member of the multidimensional array selected by the list of numbers indexlist.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pick

 
PICK list					(library procedure)

outputs a randomly chosen member of the input list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

remove

 
REMOVE thing list				(library procedure)

outputs a copy of list with every member equal to thing removed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

remdup

 
REMDUP list					(library procedure)

outputs a copy of list with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

quoted

 
QUOTED thing					(library procedure)

outputs its input, if a list; outputs its input with a quotation mark prepended, if a word.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.3 Data Mutators

setitem  
mdsetitem  
.setfirst  SETFIRST
.setbf  SETBF
.setitem  SETITEM
push  
pop  
queue  
dequeue  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setitem

 
SETITEM index array value

command. Replaces the indexth member of array with the new value. Ensures that the resulting array is not circular, i.e., value may not be a list or array that contains array.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

mdsetitem

 
MDSETITEM indexlist array value			(library procedure)

command. Replaces the member of array chosen by indexlist with the new value.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.setfirst

 
.SETFIRST list value

command. Changes the first member of list to be value.

WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; and the loss of memory if a circular structure is released.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.setbf

 
.SETBF list value

command. Changes the butfirst of list to be value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; Logo crashes and coredumps if the butfirst of a list is not itself a list; and the loss of memory if a circular structure is released.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.setitem

 
.SETITEM index array value

command. Changes the indexth member of array to be value, like SETITEM, but without checking for circularity.

WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETITEM can lead to circular arrays, which will get some Logo primitives into infinite loops; and the loss of memory if a circular structure is released.

See section setitem.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

push

 
PUSH stackname thing				(library procedure)

command. Adds the thing to the stack that is the value of the variable whose name is stackname. This variable must have a list as its value; the initial value should be the empty list. New members are added at the front of the list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pop

 
POP stackname					(library procedure)

outputs the most recently PUSHed member of the stack that is the value of the variable whose name is stackname and removes that member from the stack.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

queue

 
QUEUE queuename thing				(library procedure)

command. Adds the thing to the queue that is the value of the variable whose name is queuename. This variable must have a list as its value; the initial value should be the empty list. New members are added at the back of the list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

dequeue

 
DEQUEUE queuename				(library procedure)

outputs the least recently QUEUEd member of the queue that is the value of the variable whose name is queuename and removes that member from the queue.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.4 Predicates

wordp  
listp  
arrayp  
emptyp  
equalp  
notequalp  
beforep  
.eq  EQ
memberp  
substringp  
numberp  
backslashedp  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

wordp

 
WORDP thing
WORD? thing

outputs TRUE if the input is a word, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

listp

 
LISTP thing
LIST? thing

outputs TRUE if the input is a list, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

arrayp

 
ARRAYP thing
ARRAY? thing

outputs TRUE if the input is an array, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

emptyp

 
EMPTYP thing
EMPTY? thing

outputs TRUE if the input is the empty word or the empty list, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

equalp

 
EQUALP thing1 thing2
EQUAL? thing1 thing2
thing1 = thing2

outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named CASEIGNOREDP whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.)

See section caseignoredp , setitem


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

notequalp

 
NOTEQUALP thing1 thing2
NOTEQUAL? thing1 thing2
thing1 <> thing2

outputs FALSE if the inputs are equal, TRUE otherwise. See EQUALP for the meaning of equality for different data types.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

beforep

 
BEFOREP word1 word2
BEFORE? word1 word2

outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, BEFOREP 3 12 is false because 3 collates after 1.

See section caseignoredp , lessp


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.eq

 
.EQ thing1 thing2

outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value.

WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of mutators can lead to circular data structures, infinite loops, or Logo crashes.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

memberp

 
MEMBERP thing1 thing2
MEMBER? thing1 thing2

if thing2 is a list or an array, outputs TRUE if thing1 is EQUALP to a member of thing2, FALSE otherwise. If thing2 is a word, outputs TRUE if thing1 is a one-character word EQUALP to a character of thing2, FALSE otherwise.

See section equalp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

substringp

 
SUBSTRINGP thing1 thing2
SUBSTRING? thing1 thing2

if thing1 or thing2 is a list or an array, outputs FALSE. If thing2 is a word, outputs TRUE if thing1 is EQUALP to a substring of thing2, FALSE otherwise.

See section equalp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

numberp

 
NUMBERP thing
NUMBER? thing

outputs TRUE if the input is a number, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

backslashedp

 
BACKSLASHEDP char
BACKSLASHED? char

outputs TRUE if the input character was originally entered into Logo with a backslash (\) before it or within vertical bars (|) to prevent its usual special syntactic meaning, FALSE otherwise. (Outputs TRUE only if the character is a backslashed space, tab, newline, or one of ()[]+-*/=<>":;\~?| )


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.5 Queries

count  
ascii  
rawascii  
char  
member  
lowercase  
uppercase  
standout  
parse  
runparse  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

count

 
COUNT thing

outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ascii

 
ASCII char

outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing backslashed punctuation, and returns the character code for the corresponding punctuation character without backslash. (Compare RAWASCII.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

rawascii

 
RAWASCII char

outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing themselves. To find out the ASCII code of an arbitrary keystroke, use RAWASCII RC.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

char

 
CHAR int

outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255.

See section ascii .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

member

 
MEMBER thing1 thing2

if thing2 is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of thing2 from the first instance of thing1 to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of thing2. It is an error for thing2 to be an array.

See section memberp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

lowercase

 
LOWERCASE word

outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

uppercase

 
UPPERCASE word

outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

standout

 
STANDOUT thing

outputs a word that, when printed, will appear like the input but displayed in standout mode (boldface, reverse video, or whatever your terminal does for standout). The word contains terminal-specific magic characters at the beginning and end; in between is the printed form (as if displayed using TYPE) of the input. The output is always a word, even if the input is of some other type, but it may include spaces and other formatting characters. Note: a word output by STANDOUT while Logo is running on one terminal will probably not have the desired effect if printed on another type of terminal.

On the Macintosh, the way that standout works is incompatible with the use of characters whose ASCII code is greater than 127. Therefore, you have a choice to make: The instruction
 
CANINVERSE 0 
disables standout, but enables the display of ASCII codes above 127, and the instruction
 
CANINVERSE 1 
restores the default situation in which standout is enabled and the extra graphic characters cannot be printed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

parse

 
PARSE word

outputs the list that would result if the input word were entered in response to a READLIST operation. That is, PARSE READWORD has the same value as READLIST for the same characters read.

See section readlist , readword


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

runparse

 
RUNPARSE wordorlist

outputs the list that would result if the input word or list were entered as an instruction line; characters such as infix operators and parentheses are separate members of the output. Note that sublists of a runparsed list are not themselves runparsed.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_3.html0100644000161300001330000023225710276035442016126 0ustar bhdoe BERKELEY LOGO 5.5: COMMUNICATION
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. Communication

3.1 Transmitters  
3.2 Receivers  
3.3 File Access  
3.4 Terminal Access  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1 Transmitters

print  
type  
show  

Note: If there is a variable named PRINTDEPTHLIMIT with a nonnegative integer value, then complex list and array structures will be printed only to the allowed depth. That is, members of members of... of members will be allowed only so far. The members omitted because they are just past the depth limit are indicated by an ellipsis for each one, so a too-deep list of two members will print as [... ...].

If there is a variable named PRINTWIDTHLIMIT with a nonnegative integer value, then only the first so many members of any array or list will be printed. A single ellipsis replaces all missing data within the structure. The width limit also applies to the number of characters printed in a word, except that a PRINTWIDTHLIMIT between 0 and 9 will be treated as if it were 10 when applied to words. This limit applies not only to the top-level printed datum but to any substructures within it.

See section printdepthlimit , printwidthlimit

If there is a variable named FULLPRINTP whose value is TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.)

See section fullprintp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

print

 
PRINT thing
PR thing
(PRINT thing1 thing2 ...)
(PR thing1 thing2 ...)

command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

type

 
TYPE thing
(TYPE thing1 thing2 ...)

command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces. Note: printing to the terminal is ordinarily "line buffered"; that is, the characters you print using TYPE will not actually appear on the screen until either a newline character is printed (for example, by PRINT or SHOW) or Logo tries to read from the keyboard (either at the request of your program or after an instruction prompt). This buffering makes the program much faster than it would be if each character appeared immediately, and in most cases the effect is not disconcerting. To accommodate programs that do a lot of positioned text display using TYPE, Logo will force printing whenever SETCURSOR is invoked. This solves most buffering problems. Still, on occasion you may find it necessary to force the buffered characters to be printed explicitly; this can be done using the WAIT command. WAIT 0 will force printing without actually waiting.

See section setcursor , wait


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

show

 
SHOW thing
(SHOW thing1 thing2 ...)

command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets.

See section print .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2 Receivers

readlist  
readword  
readrawline  
readchar  
readchars  
shell  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

readlist

 
READLIST
RL

reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

readword

 
READWORD
RW

reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READWORD outputs the empty list (not the empty word). READWORD processes backslash, vertical bar, and tilde characters in the read stream. In the case of a tilde used for line continuation, the output word DOES include the tilde and the newline characters, so that the user program can tell exactly what the user entered. Vertical bars in the line are also preserved in the output. Backslash characters are not preserved in the output, but the character following the backslash has 128 added to its representation. Programs can use BACKSLASHEDP to check for this code. (Backslashedness is preserved only for certain characters.)

See section backslashedp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

readrawline

 
READRAWLINE

reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters.

See section readword .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

readchar

 
READCHAR
RC

reads a single character from the read stream and outputs that character as a word. If the read stream is a file, and the end of file is reached, READCHAR outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHAR is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context.

See section readlist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

readchars

 
READCHARS num
RCS num

reads num characters from the read stream and outputs those characters as a word. If the read stream is a file, and the end of file is reached, READCHARS outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHARS is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context.

See section readlist , readword


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

shell

 
SHELL command
(SHELL command wordflag)

Under Unix, outputs the result of running command as a shell command. (The command is sent to `/bin/sh', not `csh' or other alternatives.) If the command is a literal list in the instruction line, and if you want a backslash character sent to the shell, you must use \\ to get the backslash through Logo's reader intact. The output is a list containing one member for each line generated by the shell command. Ordinarily each such line is represented by a list in the output, as though the line were read using READLIST. If a second input is given, regardless of the value of the input, each line is represented by a word in the output as though it were read with READWORD. Example:

 
to dayofweek
output first first shell [date]
end

This is "first first" to extract the first word of the first (and only) line of the shell output.

Under DOS, SHELL is a command, not an operation; it sends its input to a DOS command processor but does not collect the result of the command.

The Macintosh, of course, is not programmable (unless you are running the Unix version of UCBLogo under OS X).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3 File Access

setprefix  
prefix  
openread  
openwrite  
openappend  
openupdate  
close  
allopen  
closeall  
erasefile  
dribble  
nodribble  
setread  
setwrite  
reader  
writer  
setreadpos  
setwritepos  
readpos  
writepos  
eofp  
filep  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setprefix

 
SETPREFIX string

command. Sets a prefix that will be used as the implicit beginning of filenames in OPENREAD, OPENWRITE, OPENAPPEND, OPENUPDATE, LOAD, and SAVE commands. Logo will put the appropriate separator character (slash for Unix, backslash for DOS/Windows, colon for MacOS) between the prefix and the filename entered by the user. The input to SETPREFIX must be a word, unless it is the empty list, to indicate that there should be no prefix.

See section openread , See section openwrite , See section openappend , See section openupdate , See section load , See section save .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

prefix

 
PREFIX

outputs the current file prefix, or [] if there is no prefix.

See section setprefix .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

openread

 
OPENREAD filename

command. Opens the named file for reading. The read position is initially at the beginning of the file.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

openwrite

 
OPENWRITE filename

command. Opens the named file for writing. If the file already existed, the old version is deleted and a new, empty file created.

OPENWRITE, but not the other OPEN variants, will accept as input a two-element list, in which the first element must be a variable name, and the second must be a positive integer. A character buffer of the specified size will be created. When a SETWRITE is done with this same list (in the sense of .EQ, not a copy, so you must do something like

 
? make "buf [foo 100]
? openwrite :buf
? setwrite :buf
    [...]
? close :buf

and not just

 
? openwrite [foo 100]
? setwrite [foo 100]

and so on), the printed characters are stored in the buffer; when a CLOSE is done with the same list as input, the characters from the buffer (treated as one long word, even if spaces and newlines are included) become the value of the specified variable.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

openappend

 
OPENAPPEND filename

command. Opens the named file for writing. If the file already exists, the write position is initially set to the end of the old file, so that newly written data will be appended to it.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

openupdate

 
OPENUPDATE filename

command. Opens the named file for reading and writing. The read and write position is initially set to the end of the old file, if any. Note: each open file has only one position, for both reading and writing. If a file opened for update is both READER and WRITER at the same time, then SETREADPOS will also affect WRITEPOS and vice versa. Also, if you alternate reading and writing the same file, you must SETREADPOS between a write and a read, and SETWRITEPOS between a read and a write.

See section reader , writer , setreadpos , setwritepos


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

close

 
CLOSE filename

command. Closes the named file. If the file was currently the reader or writer, then the reader or writer is changed to the keyboard or screen, as if SETREAD [] or SETWRITE [] had been done.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

allopen

 
ALLOPEN

outputs a list whose members are the names of all files currently open. This list does not include the dribble file, if any.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

closeall

 
CLOSEALL					(library procedure)

command. Closes all open files. Abbreviates FOREACH ALLOPEN [CLOSE ?]

See section foreach , close


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erasefile

 
ERASEFILE filename
ERF filename

command. Erases (deletes, removes) the named file, which should not currently be open.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

dribble

 
DRIBBLE filename

command. Creates a new file whose name is the input, like OPENWRITE, and begins recording in that file everything that is read from the keyboard or written to the terminal. That is, this writing is in addition to the writing to WRITER. The intent is to create a transcript of a Logo session, including things like prompt characters and interactions.

See section openwrite , writer


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

nodribble

 
NODRIBBLE

command. Stops copying information into the dribble file, and closes the file.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setread

 
SETREAD filename

command. Makes the named file the read stream, used for READLIST, etc. The file must already be open with OPENREAD or OPENUPDATE. If the input is the empty list, then the read stream becomes the terminal, as usual. Changing the read stream does not close the file that was previously the read stream, so it is possible to alternate between files.

See section readlist , openread , openupdate


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setwrite

 
SETWRITE filename

command. Makes the named file the write stream, used for PRINT, etc. The file must already be open with OPENWRITE, OPENAPPEND, or OPENUPDATE. If the input is the empty list, then the write stream becomes the terminal, as usual. Changing the write stream does not close the file that was previously the write stream, so it is possible to alternate between files.

If the input is a list, then its first element must be a variable name, and its second and last element must be a positive integer; a buffer of that many characters will be allocated, and will become the writestream. If the same list (same in the .EQ sense, not a copy) has been used as input to OPENWRITE, then the already-allocated buffer will be used, and the writer can be changed to and from this buffer, with all the characters accumulated as in a file. When the same list is used as input to CLOSE, the contents of the buffer (as an unparsed word, which may contain newline characters) will become the value of the named variable. For compatibility with earlier versions, if the list has not been opened when the SETWRITE is done, it will be opened implicitly, but the first SETWRITE after this one will implicitly close it, setting the variable and freeing the allocated buffer.

See section print , openwrite ; openappend ; openupdate


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

reader

 
READER

outputs the name of the current read stream file, or the empty list if the read stream is the terminal.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

writer

 
WRITER

outputs the name of the current write stream file, or the empty list if the write stream is the terminal.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setreadpos

 
SETREADPOS charpos

command. Sets the file pointer of the read stream file so that the next READLIST, etc., will begin reading at the charposth character in the file, counting from 0. (That is, SETREADPOS 0 will start reading from the beginning of the file.) Meaningless if the read stream is the terminal.

See section readlist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setwritepos

 
SETWRITEPOS charpos

command. Sets the file pointer of the write stream file so that the next PRINT, etc., will begin writing at the charposth character in the file, counting from 0. (That is, SETWRITEPOS 0 will start writing from the beginning of the file.) Meaningless if the write stream is the terminal.

See section print .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

readpos

 
READPOS

outputs the file position of the current read stream file.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

writepos

 
WRITEPOS

outputs the file position of the current write stream file.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

eofp

 
EOFP
EOF?

predicate, outputs TRUE if there are no more characters to be read in the read stream file, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

filep

 
FILEP filename
FILE? filename					(library procedure)

predicate, outputs TRUE if a file of the specified name exists and can be read, FALSE otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4 Terminal Access

keyp  
cleartext  
setcursor  
cursor  
setmargins  
settextcolor  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

keyp

 
KEYP
KEY?

predicate, outputs TRUE if there are characters waiting to be read from the read stream. If the read stream is a file, this is equivalent to NOT EOFP. If the read stream is the terminal, then echoing is turned off and the terminal is set to CBREAK (character at a time instead of line at a time) mode. It remains in this mode until some line-mode reading is requested (e.g., READLIST). The Unix operating system forgets about any pending characters when it switches modes, so the first KEYP invocation will always output FALSE.

See section eofp , readlist


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cleartext

 
CLEARTEXT
CT

command. Clears the text screen of the terminal.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setcursor

 
SETCURSOR vector

command. The input is a list of two numbers, the x and y coordinates of a screen position (origin in the upper left corner, positive direction is southeast). The screen cursor is moved to the requested position. This command also forces the immediate printing of any buffered characters.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cursor

 
CURSOR

outputs a list containing the current x and y coordinates of the screen cursor. Logo may get confused about the current cursor position if, e.g., you type in a long line that wraps around or your program prints escape codes that affect the terminal strangely.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setmargins

 
SETMARGINS vector

command. The input must be a list of two numbers, as for SETCURSOR. The effect is to clear the screen and then arrange for all further printing to be shifted down and to the right according to the indicated margins. Specifically, every time a newline character is printed (explicitly or implicitly) Logo will type x_margin spaces, and on every invocation of SETCURSOR the margins will be added to the input x and y coordinates. (CURSOR will report the cursor position relative to the margins, so that this shift will be invisible to Logo programs.) The purpose of this command is to accommodate the display of terminal screens in lecture halls with inadequate TV monitors that miss the top and left edges of the screen.

See section setcursor .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

settextcolor

 
SETTEXTCOLOR foreground background
SETTC foreground background

Command (Windows and DOS extended only). The inputs are color numbers, as for turtle graphics. Future printing to the text window will use the specified colors for foreground (the characters printed) and background (the space under those characters). Using STANDOUT will revert to the default text window colors. In the DOS extended (ucblogo.exe) version, colors in textscreen mode are limited to numbers 0-7, and the coloring applies only to text printed by the program, not to the echoing of text typed by the user. Neither limitation applies to the text portion of splitscreen mode, which is actually drawn as graphics internally.

See section standout .


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_4.html0100644000161300001330000020060210276035442016114 0ustar bhdoe BERKELEY LOGO 5.5: ARITHMETIC
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. Arithmetic

4.1 Numeric Operations  
4.2 Numeric Predicates  
4.3 Random Numbers  
4.4 Print Formatting  
4.5 Bitwise Operations  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.1 Numeric Operations

sum  
difference  
minus  
product  
quotient  
remainder  
modulo  
int  
round  
sqrt  
power  
exp  
log10  
ln  
sin  
radsin  
cos  
radcos  
arctan  
radarctan  
iseq  
rseq  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

sum

 
SUM num1 num2
(SUM num1 num2 num3 ...)
num1 + num2

outputs the sum of its inputs.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

difference

 
DIFFERENCE num1 num2
num1 - num2

outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

minus

 
MINUS num
- num

outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms:

 
MINUS 3 + 4     means   -(3+4)
- 3 + 4         means   (-3)+4


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

product

 
PRODUCT num1 num2
(PRODUCT num1 num2 num3 ...)
num1 * num2

outputs the product of its inputs.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

quotient

 
QUOTIENT num1 num2
(QUOTIENT num)
num1 / num2

outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is 2, not 2.0 -- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

remainder

 
REMAINDER num1 num2

outputs the remainder on dividing num1 by num2; both must be integers and the result is an integer with the same sign as num1.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

modulo

 
MODULO num1 num2

outputs the remainder on dividing num1 by num2; both must be integers and the result is an integer with the same sign as num2.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

int

 
INT num

outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

round

 
ROUND num

outputs the nearest integer to the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

sqrt

 
SQRT num

outputs the square root of the input, which must be nonnegative.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

power

 
POWER num1 num2

outputs num1 to the num2 power. If num1 is negative, then num2 must be an integer.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

exp

 
EXP num

outputs e (2.718281828+) to the input power.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

log10

 
LOG10 num

outputs the common logarithm of the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ln

 
LN num

outputs the natural logarithm of the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

sin

 
SIN degrees

outputs the sine of its input, which is taken in degrees.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

radsin

 
RADSIN radians

outputs the sine of its input, which is taken in radians.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cos

 
COS degrees

outputs the cosine of its input, which is taken in degrees.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

radcos

 
RADCOS radians

outputs the cosine of its input, which is taken in radians.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

arctan

 
ARCTAN num
(ARCTAN x y)

outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or --90 depending on the sign of y, if x is zero.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

radarctan

 
RADARCTAN num
(RADARCTAN x y)

outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or --pi/2 depending on the sign of y, if x is zero.

The expression 2*(RADARCTAN 0 1) can be used to get the value of pi.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

iseq

 
ISEQ from to					(library procedure)

outputs a list of the integers from FROM to TO, inclusive.

 
? show iseq 3 7
[3 4 5 6 7]
? show iseq 7 3
[7 6 5 4 3]


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

rseq

 
RSEQ from to count				(library procedure)

outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive.

 
? show rseq 3 5 9 
[3 3.25 3.5 3.75 4 4.25 4.5 4.75 5] 
? show rseq 3 5 5
[3 3.5 4 4.5 5]


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2 Numeric Predicates

lessp  
greaterp  
lessequalp  
greaterequalp  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

lessp

 
LESSP num1 num2
LESS? num1 num2
num1 < num2

outputs TRUE if its first input is strictly less than its second.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

greaterp

 
GREATERP num1 num2
GREATER? num1 num2
num1 > num2

outputs TRUE if its first input is strictly greater than its second.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

lessequalp

 
LESSEQUALP num1 num2
LESSEQUAL? num1 num2
num1 <= num2

outputs TRUE if its first input is less than or equal to its second.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

greaterequalp

 
GREATEREQUALP num1 num2
GREATEREQUAL? num1 num2
num1 >= num2

outputs TRUE if its first input is greater than or equal to its second.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.3 Random Numbers

random  
rerandom  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

random

 
RANDOM num
(RANDOM start end)

with one input, outputs a random nonnegative integer less than its input, which must be a positive integer.

With two inputs, RANDOM outputs a random integer greater than or equal to the first input, and less than or equal to the second input. Both inputs must be integers, and the first must be less than the second. (RANDOM 0 9) is equivalent to RANDOM 10; (RANDOM 3 8) is equivalent to (RANDOM 6)+3.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

rerandom

 
RERANDOM
(RERANDOM seed)

command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.4 Print Formatting

form  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

form

 
FORM num width precision

outputs a word containing a printable representation of num, possibly preceded by spaces (and therefore not a number for purposes of performing arithmetic operations), with at least width characters, including exactly precision digits after the decimal point. (If precision is 0 then there will be no decimal point in the output.)

As a debugging feature, (FORM num -1 format) will print the floating point num according to the C printf format, to allow

 
to hex :num
op form :num -1 "|%08X %08X|
end

to allow finding out the exact result of floating point operations. The precise format needed may be machine-dependent.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5 Bitwise Operations

bitand  
bitor  
bitxor  
bitnot  
ashift  
lshift  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

bitand

 
BITAND num1 num2
(BITAND num1 num2 num3 ...)

outputs the bitwise AND of its inputs, which must be integers.

See section and .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

bitor

 
BITOR num1 num2
(BITOR num1 num2 num3 ...)

outputs the bitwise OR of its inputs, which must be integers.

See section or .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

bitxor

 
BITXOR num1 num2
(BITXOR num1 num2 num3 ...)

outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers.

See section or .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

bitnot

 
BITNOT num

outputs the bitwise NOT of its input, which must be an integer.

See section not .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ashift

 
ASHIFT num1 num2

outputs num1 arithmetic-shifted to the left by num2 bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

lshift

 
LSHIFT num1 num2

outputs num1 logical-shifted to the left by num2 bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_5.html0100644000161300001330000002170310276035442016120 0ustar bhdoe BERKELEY LOGO 5.5: LOGICAL OPERATIONS
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5. Logical Operations

and  
or  
not  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

and

 
AND tf1 tf2
(AND tf1 tf2 tf3 ...)

outputs TRUE if all inputs are TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, true or True or TRUE are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example:

 
MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5]

to avoid the division by zero if the first part is false.

See section caseignoredp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

or

 
OR tf1 tf2
(OR tf1 tf2 tf3 ...)

outputs TRUE if any input is TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, true or True or TRUE are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example:

 
IF OR :X=0 [some.long.computation] [...]

to avoid the long computation if the first condition is met.

See section caseignoredp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

not

 
NOT tf

outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_6.html0100644000161300001330000033737410276035442016137 0ustar bhdoe BERKELEY LOGO 5.5: GRAPHICS
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6. Graphics

Berkeley Logo provides traditional Logo turtle graphics with one turtle. Multiple turtles, dynamic turtles, and collision detection are not supported. This is the most hardware-dependent part of Logo; some features may exist on some machines but not others. Nevertheless, the goal has been to make Logo programs as portable as possible, rather than to take fullest advantage of the capabilities of each machine. In particular, Logo attempts to scale the screen so that turtle coordinates [--100 --100] and [100 100] fit on the graphics window, and so that the aspect ratio is 1:1.

The center of the graphics window (which may or may not be the entire screen, depending on the machine used) is turtle location [0 0]. Positive X is to the right; positive Y is up. Headings (angles) are measured in degrees clockwise from the positive Y axis. (This differs from the common mathematical convention of measuring angles counterclockwise from the positive X axis.) The turtle is represented as an isoceles triangle; the actual turtle position is at the midpoint of the base (the short side). However, the turtle is drawn one step behind its actual position, so that the display of the base of the turtle's triangle does not obscure a line drawn perpendicular to it (as would happen after drawing a square).

Colors are, of course, hardware-dependent. However, Logo provides partial hardware independence by interpreting color numbers 0 through 7 uniformly on all computers:

 
	0  black        1  blue         2  green        3  cyan
	4  red          5  magenta      6  yellow       7 white

Where possible, Logo provides additional user-settable colors; how many are available depends on the hardware and operating system environment. If at least 16 colors are available, Logo tries to provide uniform initial settings for the colors 8-15:

 
	 8  brown        9  tan         10  forest      11  aqua
	12  salmon      13  purple      14  orange      15  grey

Logo begins with a black background and white pen.

6.1 Turtle Motion  
6.2 Turtle Motion Queries  
6.3 Turtle and Window Control  
6.4 Turtle and Window Queries  
6.5 Pen and Background Control  
6.6 Pen Queries  
6.7 saving and loading pictures  
6.8 Mouse Queries  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1 Turtle Motion

forward  
back  
left  
right  
setpos  
setxy  
setx  
sety  
setheading  
home  
arc  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

forward

 
FORWARD dist
FD dist

moves the turtle forward, in the direction that it's facing, by the specified distance (measured in turtle steps).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

back

 
BACK dist
BK dist

moves the turtle backward, i.e., exactly opposite to the direction that it's facing, by the specified distance. (The heading of the turtle does not change.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

left

 
LEFT degrees
LT degrees

turns the turtle counterclockwise by the specified angle, measured in degrees (1/360 of a circle).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

right

 
RIGHT degrees
RT degrees

turns the turtle clockwise by the specified angle, measured in degrees (1/360 of a circle).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setpos

 
SETPOS pos

moves the turtle to an absolute screen position. The input is a list of two numbers, the X and Y coordinates.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setxy

 
SETXY xcor ycor

moves the turtle to an absolute screen position. The two inputs are numbers, the X and Y coordinates.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setx

 
SETX xcor

moves the turtle horizontally from its old position to a new absolute horizontal coordinate. The input is the new X coordinate.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

sety

 
SETY ycor

moves the turtle vertically from its old position to a new absolute vertical coordinate. The input is the new Y coordinate.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setheading

 
SETHEADING degrees
SETH degrees

turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive Y axis.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

home

 
HOME

moves the turtle to the center of the screen. Equivalent to SETPOS [0 0] SETHEADING 0.

See section setpos , See section setheading .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

arc

 
ARC angle radius

draws an arc of a circle, with the turtle at the center, with the specified radius, starting at the turtle's heading and extending clockwise through the specified angle. The turtle does not move.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2 Turtle Motion Queries

pos  
xcor  
ycor  
heading  
towards  
scrunch  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pos

 
POS

outputs the turtle's current position, as a list of two numbers, the X and Y coordinates.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

xcor

 
XCOR						(library procedure)

outputs a number, the turtle's X coordinate.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ycor

 
YCOR						(library procedure)

outputs a number, the turtle's Y coordinate.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

heading

 
HEADING

outputs a number, the turtle's heading in degrees.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

towards

 
TOWARDS pos

outputs a number, the heading at which the turtle should be facing so that it would point from its current position to the position given as the input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

scrunch

 
SCRUNCH

outputs a list containing two numbers, the X and Y scrunch factors, as used by SETSCRUNCH. (But note that SETSCRUNCH takes two numbers as inputs, not one list of numbers.)

See section setscrunch .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.3 Turtle and Window Control

showturtle  
hideturtle  
clean  
clearscreen  
wrap  
window  
fence  
fill  
label  
textscreen  
fullscreen  
splitscreen  
setscrunch  
refresh  
norefresh  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

showturtle

 
SHOWTURTLE
ST

makes the turtle visible.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

hideturtle

 
HIDETURTLE
HT

makes the turtle invisible. It's a good idea to do this while you're in the middle of a complicated drawing, because hiding the turtle speeds up the drawing substantially.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

clean

 
CLEAN

erases all lines that the turtle has drawn on the graphics window. The turtle's state (position, heading, pen mode, etc.) is not changed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

clearscreen

 
CLEARSCREEN
CS

erases the graphics window and sends the turtle to its initial position and heading. Like HOME and CLEAN together.

See section home .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

wrap

 
WRAP

tells the turtle to enter wrap mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will "wrap around" and reappear at the opposite edge of the window. The top edge wraps to the bottom edge, while the left edge wraps to the right edge. (So the window is topologically equivalent to a torus.) This is the turtle's initial mode. Compare WINDOW and FENCE.

See section fence .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

window

 
WINDOW

tells the turtle to enter window mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move offscreen. The visible graphics window is considered as just part of an infinite graphics plane; the turtle can be anywhere on the plane. (If you lose the turtle, HOME will bring it back to the center of the window.) Compare WRAP and FENCE.

See section home .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fence

 
FENCE

tells the turtle to enter fence mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move as far as it can and then stop at the edge with an "out of bounds" error message. Compare WRAP and WINDOW.

See section wrap .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fill

 
FILL

fills in a region of the graphics window containing the turtle and bounded by lines that have been drawn earlier. This is not portable; it doesn't work for all machines, and may not work exactly the same way on different machines.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

label

 
LABEL text

takes a word or list as input, and prints the input on the graphics window, starting at the turtle's position.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

textscreen

 
TEXTSCREEN
TS

rearranges the size and position of windows to maximize the space available in the text window (the window used for interaction with Logo). The details differ among machines. Compare SPLITSCREEN and FULLSCREEN.

See section splitscreen .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fullscreen

 
FULLSCREEN
FS

rearranges the size and position of windows to maximize the space available in the graphics window. The details differ among machines. Compare SPLITSCREEN and TEXTSCREEN.

In the DOS version, switching from fullscreen to splitscreen loses the part of the picture that's hidden by the text window. Also, since there must be a text window to allow printing (including the printing of the Logo prompt), Logo automatically switches from fullscreen to splitscreen whenever anything is printed. [This design decision follows from the scarcity of memory, so that the extra memory to remember an invisible part of a drawing seems too expensive.]


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

splitscreen

 
SPLITSCREEN
SS

rearranges the size and position of windows to allow some room for text interaction while also keeping most of the graphics window visible. The details differ among machines. Compare TEXTSCREEN and FULLSCREEN.

See section textscreen .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setscrunch

 
SETSCRUNCH xscale yscale

adjusts the aspect ratio and scaling of the graphics display. After this command is used, all further turtle motion will be adjusted by multiplying the horizontal and vertical extent of the motion by the two numbers given as inputs. For example, after the instruction SETSCRUNCH 2 1 motion at a heading of 45 degrees will move twice as far horizontally as vertically. If your squares don't come out square, try this. (Alternatively, you can deliberately misadjust the aspect ratio to draw an ellipse.)

For Unix machines and Macintoshes, both scale factors are initially 1. For DOS machines, the scale factors are initially set according to what the hardware claims the aspect ratio is, but the hardware sometimes lies. The values set by SETSCRUNCH are remembered in a file (called SCRUNCH.DAT) and are automatically put into effect when a Logo session begins.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

refresh

 
REFRESH

tells Logo to remember the turtle's motions so that they can be reconstructed in case the graphics window is overlayed. The effectiveness of this command may depend on the machine used.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

norefresh

 
NOREFRESH

tells Logo not to remember the turtle's motions. This will make drawing faster, but prevents recovery if the window is overlayed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.4 Turtle and Window Queries

shownp  
screenmode  
turtlemode  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

shownp

 
SHOWNP
SHOWN?

outputs TRUE if the turtle is shown (visible), FALSE if the turtle is hidden. See SHOWTURTLE and HIDETURTLE.

See section showturtle , hideturtle .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

screenmode

 
SCREENMODE

outputs the word TEXTSCREEN, SPLITSCREEN, or FULLSCREEN depending on the current screen mode.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

turtlemode

 
TURTLEMODE

outputs the word WRAP, FENCE, or WINDOW depending on the current turtle mode.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.5 Pen and Background Control

The turtle carries a pen that can draw pictures. At any time the pen can be UP (in which case moving the turtle does not change what's on the graphics screen) or DOWN (in which case the turtle leaves a trace). If the pen is down, it can operate in one of three modes: PAINT (so that it draws lines when the turtle moves), ERASE (so that it erases any lines that might have been drawn on or through that path earlier), or REVERSE (so that it inverts the status of each point along the turtle's path).

pendown  
penup  
penpaint  
penerase  
penreverse  
setpencolor  
setpalette  
setpensize  
setpenpattern  
setpen  
setbackground  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pendown

 
PENDOWN
PD

sets the pen's position to DOWN, without changing its mode.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

penup

 
PENUP
PU

sets the pen's position to UP, without changing its mode.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

penpaint

 
PENPAINT
PPT

sets the pen's position to DOWN and mode to PAINT.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

penerase

 
PENERASE
PE

sets the pen's position to DOWN and mode to ERASE.

See section erase .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

penreverse

 
PENREVERSE
PX

sets the pen's position to DOWN and mode to REVERSE. (This may interact in hardware-dependent ways with use of color.)

See section reverse .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setpencolor

 
SETPENCOLOR colornumber.or.rgblist
SETPC colornumber.or.rgblist

sets the pen color to the given number, which must be a nonnegative integer. There are initial assignments for the first 16 colors:

 
 0  black	 1  blue	 2  green	 3  cyan
 4  red		 5  magenta	 6  yellow	 7 white
 8  brown	 9  tan		10  forest	11  aqua
12  salmon	13  purple	14  orange	15  grey

but other colors can be assigned to numbers by the PALETTE command. Alternatively, sets the pen color to the given RGB values (a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setpalette

 
SETPALETTE colornumber rgblist

sets the actual color corresponding to a given number, if allowed by the hardware and operating system. Colornumber must be an integer greater than or equal to 8. (Logo tries to keep the first 8 colors constant.) The second input is a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color. The actual color resolution on any screen is probably less than 64K, but Logo scales as needed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setpensize

 
SETPENSIZE size

sets the thickness of the pen. The input is either a single positive integer or a list of two positive integers (for horizontal and vertical thickness). Some versions pay no attention to the second number, but always have a square pen.

 
SETPENPATTERN pattern

sets hardware-dependent pen characteristics. This command is not guaranteed compatible between implementations on different machines.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setpenpattern

 
SETPENSIZE size
SETPENPATTERN pattern

set hardware-dependent pen characteristics. These commands are not guaranteed compatible between implementations on different machines.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setpen

 
SETPEN list					(library procedure)

sets the pen's position, mode, thickness, and hardware-dependent characteristics according to the information in the input list, which should be taken from an earlier invocation of PEN.

See section pen .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setbackground

 
SETBACKGROUND colornumber.or.rgblist
SETBG colornumber.or.rgblist

set the screen background color by slot number or RGB values. See SETPENCOLOR for details.

See section setpencolor .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.6 Pen Queries

pendownp  
penmode  
pencolor  
palette  
pensize  
pen  
background  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pendownp

 
PENDOWNP
PENDOWN?

outputs TRUE if the pen is down, FALSE if it's up.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

penmode

 
PENMODE

outputs one of the words PAINT, ERASE, or REVERSE according to the current pen mode.

See section erase , reverse .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pencolor

 
PENCOLOR
PC

outputs a color number, a nonnegative integer that is associated with a particular color, or a list of RGB values if such a list was used as the most recent input to SETPENCOLOR. There are initial assignments for the first 16 colors:

 
	 0  black        1  blue         2  green        3  cyan
	 4  red          5  magenta      6  yellow       7 white
	 8  brown        9  tan         10  forest      11  aqua
	12  salmon      13  purple      14  orange      15  grey

but other colors can be assigned to numbers by the PALETTE command.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

palette

 
PALETTE colornumber

outputs a list of three integers, each in the range 0-65535, representing the amount of red, green, and blue in the color associated with the given number.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pensize

 
PENSIZE

outputs a list of two positive integers, specifying the horizontal and vertical thickness of the turtle pen. (In some implementations the two numbers may always be equal.)

 
PENPATTERN

outputs hardware-specific pen information.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pen

 
PEN						(library procedure)

outputs a list containing the pen's position, mode, thickness, and hardware-specific characteristics, for use by SETPEN.

See section setpen .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

background

 
BACKGROUND
BG

outputs the graphics background color, either as a slot number or as an RGB list, whichever way it was set. (See PENCOLOR.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.7 saving and loading pictures

savepict  
loadpict  
epspict  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

savepict

 
SAVEPICT filename

command. Writes a file with the specified name containing the state of the graphics window, including any nonstandard color palette settings, in Logo's internal format. This picture can be restored to the screen using LOADPICT. The format is not portable between platforms, nor is it readable by other programs. epspict to export Logo graphics for other programs.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

loadpict

 
LOADPICT filename

command. Reads the specified file, which must have been written by a SAVEPICT command, and restores the graphics window and color palette settings to the values stored in the file. Any drawing previously on the screen is cleared.

See section savepict .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

epspict

 
EPSPICT filename

command. Writes a file with the specified name, containing an Encapsulated Postscript (EPS) representation of the state of the graphics window. This file can be imported into other programs that understand EPS format. Restrictions: the drawing cannot use ARC, FILL, PENERASE, or PENREVERSE; any such instructions will be ignored in the translation to Postscript form.

See section arc , See section fill , See section penerase , See section penreverse .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.8 Mouse Queries

mousepos  
buttonp  
buttonp   


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

mousepos

 
MOUSEPOS

outputs the coordinates of the mouse, provided that it's within the graphics window, in turtle coordinates. If the mouse is outside the graphics window, then the last position within the window is returned. Exception: If a mouse button is pressed within the graphics window and held while the mouse is dragged outside the window, the mouse's position is returned as if the window were big enough to include it.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

buttonp

 
BUTTONP
BUTTON?

outputs TRUE if a mouse button is down and the mouse is over the graphics window. Once the button is down, BUTTONP remains true until the button is released, even if the mouse is dragged out of the graphics window.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

buttonp

 
BUTTON

outputs 0 if BUTTONP would output FALSE; otherwise, it outputs an integer between 1 and 3 indicating which button was pressed. Ordinarily 1 means left, 2 means right, and 3 means center, but operating systems may reconfigure these.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_7.html0100644000161300001330000046507010276035442016133 0ustar bhdoe BERKELEY LOGO 5.5: WORKSPACE MANAGEMENT
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7. Workspace Management

7.1 Procedure Definition  
7.2 Variable Definition  
7.3 Property Lists  
7.4 Workspace Predicates  
7.5 Workspace Queries  
7.6 Workspace Inspection  
7.7 Workspace Control  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1 Procedure Definition

to  
define  
text  
fulltext  
copydef  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

to

 
TO procname :input1 :input2 ...			(special form)

command. Prepares Logo to accept a procedure definition. The procedure will be named procname and there must not already be a procedure by that name. The inputs will be called input1 etc. Any number of inputs are allowed, including none. Names of procedures and inputs are case-insensitive.

Unlike every other Logo procedure, TO takes as its inputs the actual words typed in the instruction line, as if they were all quoted, rather than the results of evaluating expressions to provide the inputs. (That's what "special form" means.)

This version of Logo allows variable numbers of inputs to a procedure. After the procedure name come four kinds of things, *in this order*:

 
	    1.   0 or more REQUIRED inputs    :FOO :FROBOZZ
	    2.   0 or more OPTIONAL inputs    [:BAZ 87] [:THINGO 5+9]
	    3.   0 or 1 REST input            [:GARPLY]
	    4.   0 or 1 DEFAULT number        5

Every procedure has a MINIMUM, DEFAULT, and MAXIMUM number of inputs. (The latter can be infinite.)

The MINIMUM number of inputs is the number of required inputs, which must come first. A required input is indicated by the

 
:inputname

notation.

After all the required inputs can be zero or more optional inputs, each of which is represented by the following notation:

 
[:inputname default.value.expression]

When the procedure is invoked, if actual inputs are not supplied for these optional inputs, the default value expressions are evaluated to set values for the corresponding input names. The inputs are processed from left to right, so a default value expression can be based on earlier inputs. Example:

 
to proc :inlist [:startvalue first :inlist]

If the procedure is invoked by saying

 
proc [a b c]

then the variable inlist will have the value [A B C] and the variable startvalue will have the value A. If the procedure is invoked by saying

 
(proc [a b c] "x)

then inlist will have the value [A B C] and startvalue will have the value X.

After all the required and optional input can come a single rest input, represented by the following notation:

 
[:inputname]

This is a rest input rather than an optional input because there is no default value expression. There can be at most one rest input. When the procedure is invoked, the value of this input will be a list containing all of the actual inputs provided that were not used for required or optional inputs. Example:

 
to proc :in1 [:in2 "foo] [:in3 "baz] [:in4]

If this procedure is invoked by saying

 
proc "x

then in1 has the value X, in2 has the value FOO, in3 has the value BAZ,and in4 has the value [] (the empty list). If it's invoked by saying

 
(proc "a "b "c "d "e)

then in1 has the value A, in2 has the value B, in3 has the value C, and in4 has the value [D E].

The MAXIMUM number of inputs for a procedure is infinite if a rest input is given; otherwise, it is the number of required inputs plus the number of optional inputs.

The DEFAULT number of inputs for a procedure, which is the number of inputs that it will accept if its invocation is not enclosed in parentheses, is ordinarily equal to the minimum number. If you want a different default number you can indicate that by putting the desired default number as the last thing on the TO line. example:

 
to proc :in1 [:in2 "foo] [:in3] 3

This procedure has a minimum of one input, a default of three inputs, and an infinite maximum.

Logo responds to the TO command by entering procedure definition mode. The prompt character changes from ? to > and whatever instructions you type become part of the definition until you type a line containing only the word END.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

define

 
DEFINE procname text

command. Defines a procedure with name procname and text text. If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.) It is an error to redefine a primitive procedure unless the variable REDEFP has the value TRUE.

See section redefp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

text

 
TEXT procname

outputs the text of the procedure named procname in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fulltext

 
FULLTEXT procname

outputs a representation of the procedure procname in which formatting information is preserved. If the procedure was defined with TO, EDIT, or LOAD, then the output is a list of words. Each word represents one entire line of the definition in the form output by READWORD, including extra spaces and continuation lines. The last member of the output represents the END line. If the procedure was defined with DEFINE, then the output is a list of lists. If these lists are printed, one per line, the result will look like a definition using TO. Note: the output from FULLTEXT is not suitable for use as input to DEFINE!

See section to , edit , load , define .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

copydef

 
COPYDEF newname oldname

command. Makes newname a procedure identical to oldname. The latter may be a primitive. If newname was already defined, its previous definition is lost. If newname was already a primitive, the redefinition is not permitted unless the variable REDEFP has the value TRUE.

Note: dialects of Logo differ as to the order of inputs to COPYDEF. This dialect uses "MAKE order," not "NAME order."

See section redefp , save , po , pot .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.2 Variable Definition

make  
name  
local  
localmake  
thing  
global  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

make

 
MAKE varname value

command. Assigns the value value to the variable named varname, which must be a word. Variable names are case-insensitive. If a variable with the same name already exists, the value of that variable is changed. If not, a new global variable is created.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

name

 
NAME value varname				(library procedure)

command. Same as MAKE but with the inputs in reverse order.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

local

 
LOCAL varname
LOCAL varnamelist
(LOCAL varname1 varname2 ...)

command. Accepts as inputs one or more words, or a list of words. A variable is created for each of these words, with that word as its name. The variables are local to the currently running procedure. Logo variables follow dynamic scope rules; a variable that is local to a procedure is available to any subprocedure invoked by that procedure. The variables created by LOCAL have no initial value; they must be assigned a value (e.g., with MAKE) before the procedure attempts to read their value.

See section make .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

localmake

 
LOCALMAKE varname value				(library procedure)

command. Makes the named variable local, like LOCAL, and assigns it the given value, like MAKE.

See section local , See section make .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

thing

 
THING varname
:quoted.varname

outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination

 
thing "

so that :FOO means THING "FOO.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

global

 
GLOBAL varname
GLOBAL varnamelist
(GLOBAL varname1 varname2 ...)

command. Accepts as inputs one or more words, or a list of words. A global variable is created for each of these words, with that word as its name. The only reason this is necessary is that you might want to use the "setter" notation SETXYZ for a variable XYZ that does not already have a value; GLOBAL "XYZ makes that legal. Note: If there is currently a local variable of the same name, this command does *not* make Logo use the global value instead of the local one.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3 Property Lists

Note: Names of property lists are always case-insensitive. Names of individual properties are case-sensitive or case-insensitive depending on the value of CASEIGNOREDP, which is TRUE by default.

See section caseignoredp .

In principle, every possible name is the name of a property list, which is initially empty. So Logo never gives a "no such property list" error, as it would for undefined procedure or variable names. But the primitive procedures that deal with "all" property lists (CONTENTS, PLISTS, etc.) list only nonempty ones. To "erase" a property list erase means to make it empty, removing all properties from it.

pprop  
gprop  
remprop  
plist  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pprop

 
PPROP plistname propname value

command. Adds a property to the plistname property list with name propname and value value.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

gprop

 
GPROP plistname propname

outputs the value of the propname property in the plistname property list, or the empty list if there is no such property.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

remprop

 
REMPROP plistname propname

command. Removes the property named propname from the property list named plistname.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

plist

 
PLIST plistname

outputs a list whose odd-numbered members are the names, and whose even-numbered members are the values, of the properties in the property list named plistname. The output is a copy of the actual property list; changing properties later will not magically change a list output earlier by PLIST.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.4 Workspace Predicates

procedurep  
primitivep  
definedp  
namep  
plistp  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

procedurep

 
PROCEDUREP name
PROCEDURE? name

outputs TRUE if the input is the name of a procedure.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

primitivep

 
PRIMITIVEP name
PRIMITIVE? name

outputs TRUE if the input is the name of a primitive procedure (one built into Logo). Note that some of the procedures described in this document are library procedures, not primitives.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

definedp

 
DEFINEDP name
DEFINED? name

outputs TRUE if the input is the name of a user-defined procedure, including a library procedure. (However, Logo does not know about a library procedure until that procedure has been invoked.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

namep

 
NAMEP name
NAME? name

outputs TRUE if the input is the name of a variable.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

plistp

 
PLISTP name
PLIST? name

outputs TRUE if the input is the name of a *nonempty* property list. (In principle every word is the name of a property list; if you haven't put any properties in it, PLIST of that name outputs an empty list, rather than giving an error message.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.5 Workspace Queries

contents  
buried  
traced  
stepped  
procedures  
primitives  
names  
plists  
namelist  
pllist  
arity  
nodes  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

contents

 
CONTENTS

outputs a "contents list," i.e., a list of three lists containing names of defined procedures, variables, and property lists respectively. This list includes all unburied named items in the workspace.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

buried

 
BURIED

outputs a contents list including all buried named items in the workspace.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

traced

 
TRACED

outputs a contents list including all traced named items in the workspace.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

stepped

 
STEPPED

outputs a contents list including all stepped named items in the workspace.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

procedures

 
PROCEDURES

outputs a list of the names of all unburied user-defined procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

primitives

 
PRIMITIVES

outputs a list of the names of all primitive procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

names

 
NAMES

outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

plists

 
PLISTS

outputs a contents list consisting of two empty lists (indicating no procedures or variables) followed by a list of all unburied nonempty property lists in the workspace.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

namelist

 
NAMELIST varname				(library procedure)
NAMELIST varnamelist

outputs a contents list consisting of an empty list followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pllist

 
PLLIST plname					(library procedure)
PLLIST plnamelist

outputs a contents list consisting of two empty lists followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input.

Note: All procedures whose input is indicated as contentslist will accept a single word (taken as a procedure name), a list of words (taken as names of procedures), or a list of three lists as described under the CONTENTS command above.

See section contents .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

arity

 
ARITY procedurename

outputs a list of three numbers: the minimum, default, and maximum number of inputs for the procedure whose name is the input. It is an error if there is no such procedure. A maximum of -1 means that the number of inputs is unlimited.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

nodes

 
NODES

outputs a list of two numbers. The first represents the number of nodes of memory currently in use. The second shows the maximum number of nodes that have been in use at any time since the last invocation of NODES. (A node is a small block of computer memory as used by Logo. Each number uses one node. Each non-numeric word uses one node, plus some non-node memory for the characters in the word. Each array takes one node, plus some non-node memory, as well as the memory required by its elements. Each list requires one node per element, as well as the memory within the elements.) If you want to track the memory use of an algorithm, it is best if you invoke GC at the beginning of each iteration, since otherwise the maximum will include storage that is unused but not yet collected.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6 Workspace Inspection

po  
poall  
pops  
pons  
popls  
pon  
popl  
pot  
pots  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

po

 
PRINTOUT contentslist
PO contentslist

command. Prints to the write stream the definitions of all procedures, variables, and property lists named in the input contents list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

poall

 
POALL						(library procedure)

command. Prints all unburied definitions in the workspace. Abbreviates PO CONTENTS.

See section contents .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pops

 
POPS						(library procedure)

command. Prints the definitions of all unburied procedures in the workspace. Abbreviates PO PROCEDURES.

See section po , procedures .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pons

 
PONS						(library procedure)

command. Prints the definitions of all unburied variables in the workspace. Abbreviates PO NAMES.

See section po , names .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

popls

 
POPLS						(library procedure)

command. Prints the contents of all unburied nonempty property lists in the workspace. Abbreviates PO PLISTS.

See section po , plists .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pon

 
PON varname					(library procedure)
PON varnamelist

command. Prints the definitions of the named variable(s).
Abbreviates PO NAMELIST varname(list).

See section po , namelist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

popl

 
POPL plname					(library procedure)
POPL plnamelist

command. Prints the definitions of the named property list(s).
Abbreviates PO PLLIST plname(list).

See section po , pllist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pot

 
POT contentslist

command. Prints the title lines of the named procedures and the definitions of the named variables and property lists. For property lists, the entire list is shown on one line instead of as a series of PPROP instructions as in PO.

See section pprop , po .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pots

 
POTS						(library procedure)

command. Prints the title lines of all unburied procedures in the workspace. Abbreviates POT PROCEDURES.

See section procedures .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.7 Workspace Control

erase  
erall  
erps  
erns  
erpls  
ern  
erpl  
bury  
buryall  
buryname  
unbury  
unburyall  
unburyname  
buriedp  
trace  
untrace  
tracedp  
step  
unstep  
steppedp  
edit  
editfile  
edall  
edps  
edns  
edpls  
edn  
edpl  
save  
savel  
load  
cslsload  
help  
seteditor  
setlibloc  
sethelploc  
setcslsloc  
settemploc  
gc  
.setsegmentsize  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erase

 
ERASE contentslist
ER contentslist

command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE.

See section redefp .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erall

 
ERALL

command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates ERASE CONTENTS.

See section contents .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erps

 
ERPS

command. Erases all unburied procedures from the workspace.
Abbreviates ERASE PROCEDURES.

See section erase , procedures .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erns

 
ERNS

command. Erases all unburied variables from the workspace. Abbreviates ERASE NAMES.

See section erase , names .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erpls

 
ERPLS

command. Erases all unburied property lists from the workspace.
Abbreviates ERASE PLISTS.

See section erase , plists .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ern

 
ERN varname					(library procedure)
ERN varnamelist

command. Erases from the workspace the variable(s) named in the input. Abbreviates ERASE NAMELIST varname(list).

See section erase , namelist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

erpl

 
ERPL plname					(library procedure)
ERPL plnamelist

command. Erases from the workspace the property list(s) named in the input. Abbreviates ERASE PLLIST plname(list).

See section erase , pllist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

bury

 
BURY contentslist

command. Buries the procedures, variables, and property lists named in the input. A buried item is not included in the lists output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is included in the list output by BURIED. By implication, buried things are not printed by POALL or saved by SAVE.

See section contents , procedures , pons , plists , poall , save .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

buryall

 
BURYALL                                         (library procedure)

command. Abbreviates BURY CONTENTS.

See section contents .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

buryname

 
BURYNAME varname				(library procedure)
BURYNAME varnamelist

command. Abbreviates BURY NAMELIST varname(list).

See section bury , namelist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

unbury

 
UNBURY contentslist

command. Unburies the procedures, variables, and property lists named in the input. That is, the named items will be returned to view in CONTENTS, etc.

See section contents .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

unburyall

 
UNBURYALL					(library procedure)

command. Abbreviates UNBURY BURIED.

See section buried .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

unburyname

 
UNBURYNAME varname				(library procedure)
UNBURYNAME varnamelist

command. Abbreviates UNBURY NAMELIST varname(list).

See section unbury , namelist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

buriedp

 
BURIEDP contentslist
BURIED? contentslist

outputs TRUE if the first procedure, variable, or property list named in the contents list is buried, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can BURIEDP [[] [VARIABLE]] or BURIEDP [[] [] [PROPLIST]].


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

trace

 
TRACE contentslist

command. Marks the named items for tracing. A message is printed whenever a traced procedure is invoked, giving the actual input values, and whenever a traced procedure STOPs or OUTPUTs. A message is printed whenever a new value is assigned to a traced variable using MAKE. A message is printed whenever a new property is given to a traced property list using PPROP.

See section stop , output , make , pprop .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

untrace

 
UNTRACE contentslist

command. Turns off tracing for the named items.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

tracedp

 
TRACEDP contentslist
TRACED? contentslist

outputs TRUE if the first procedure, variable, or property list named in the contents list is traced, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can TRACEDP [[] [VARIABLE]] or TRACEDP [[] [] [PROPLIST]].


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

step

 
STEP contentslist

command. Marks the named items for stepping. Whenever a stepped procedure is invoked, each instruction line in the procedure body is printed before being executed, and Logo waits for the user to type a newline at the terminal. A message is printed whenever a stepped variable name is `shadowed' because a local variable of the same name is created either as a procedure input or by the LOCAL command.

See section local .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

unstep

 
UNSTEP contentslist

command. Turns off stepping for the named items.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

steppedp

 
STEPPEDP contentslist
STEPPED? contentslist

outputs TRUE if the first procedure, variable, or property list named in the contents list is stepped, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can STEPPEDP [[] [VARIABLE]] or STEPPEDP [[] [] [PROPLIST]].


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edit

 
EDIT contentslist
ED contentslist
(EDIT)
(ED)

command. If invoked with an input, EDIT writes the definitions of the named items into a temporary file and edits that file, using your favorite editor as determined by the EDITOR environment variable. If you don't have an EDITOR variable, edits the definitions using jove. If invoked without an input, EDIT edits the same file left over from a previous EDIT or EDITFILE instruction. When you leave the editor, Logo reads the revised definitions and modifies the workspace accordingly. It is not an error if the input includes names for which there is no previous definition.

If there is a variable LOADNOISILY whose value is TRUE, then, after leaving the editor, TO commands in the temporary file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently.

If there is an environment variable called TEMP, then Logo uses its value as the directory in which to write the temporary file used for editing.

Exceptionally, the EDIT command can be used without its default input and without parentheses provided that nothing follows it on the instruction line.

See section loadnoisily , See section editfile .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

editfile

 
EDITFILE filename

command. Starts the Logo editor, like EDIT, but instead of editing a temporary file it edits the file specified by the input. When you leave the editor, Logo reads the revised file, as for EDIT. EDITFILE also remembers the filename, so that a subsequent EDIT command with no input will re-edit the same file.

EDITFILE is intended as an alternative to LOAD and SAVE. You can maintain a workspace file yourself, controlling the order in which definitions appear, maintaining comments in the file, and so on.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edall

 
EDALL						(library procedure)

command. Abbreviates EDIT CONTENTS.

See section contents .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edps

 
EDPS						(library procedure)

command. Abbreviates EDIT PROCEDURES.

See section edit , procedures .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edns

 
EDNS						(library procedure)

command. Abbreviates EDIT NAMES.

See section edit , names .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edpls

 
EDPLS						(library procedure)

command. Abbreviates EDIT PLISTS.

See section edit , plists .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edn

 
EDN varname					(library procedure)
EDN varnamelist

command. Abbreviates EDIT NAMELIST varname(list).

See section edit , namelist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

edpl

 
EDPL plname					(library procedure)
EDPL plnamelist

command. Abbreviates EDIT PLLIST plname(list).

See section edit , pllist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

save

 
SAVE filename

command. Saves the definitions of all unburied procedures, variables, and nonempty property lists in the named file. Equivalent to

 
to save :filename
local "oldwriter
make "oldwriter writer
openwrite :filename
setwrite :filename
poall
setwrite :oldwriter
close :filename
end


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

savel

 
SAVEL contentslist filename			(library procedure)

command. Saves the definitions of the procedures, variables, and property lists specified by contentslist to the file named filename.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

load

 
LOAD filename

command. Reads instructions from the named file and executes them. The file can include procedure definitions with TO, and these are accepted even if a procedure by the same name already exists. If the file assigns a list value to a variable named STARTUP, then that list is run as an instructionlist after the file is loaded. If there is a variable LOADNOISILY whose value is TRUE, then TO commands in the file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently.

See section startup , See section loadnoisily .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cslsload

 
CSLSLOAD name

command. Loads the named file, like LOAD, but from the directory containing the Computer Science Logo Style programs instead of the current user's directory.

See section load .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

help

 
HELP name
(HELP)

command. Prints information from the reference manual about the primitive procedure named by the input. With no input, lists all the primitives about which help is available. If there is an environment variable LOGOHELP, then its value is taken as the directory in which to look for help files, instead of the default help directory.

If HELP is called with the name of a defined procedure for which there is no help file, it will print the title line of the procedure followed by lines from the procedure body that start with semicolon, stopping when a non-semicolon line is seen.

Exceptionally, the HELP command can be used without its default input and without parentheses provided that nothing follows it on the instruction line.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

seteditor

 
SETEDITOR path

command. Tells Logo to use the specified program as its editor instead of the default editor. The format of a path depends on your operating system.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setlibloc

 
SETLIBLOC path

command. Tells Logo to use the specified directory as its library instead of the default. (Note that many Logo "primitive" procedures are actually found in the library, so they may become unavailable if your new library does not include them!) The format of a path depends on your operating system.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

setcslsloc

 
SETCSLSLOC path

command. Tells Logo to use the specified directory for the CSLSLOAD command, instead of the default directory. The format of a path depends on your operating system.

See section cslsload .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

sethelploc

 
SETHELPLOC path

command. Tells Logo to look in the specified directory for the information provided by the HELP command, instead of the default directory. The format of a path depends on your operating system.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

settemploc

 
SETTEMPLOC path

command. Tells Logo to write editor temporary files in the specified directory rather than in the default directory. You must have write permission for this directory. The format of a path depends on your operating system.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

gc

 
GC
(GC anything)

command. Runs the garbage collector, reclaiming unused nodes. Logo does this when necessary anyway, but you may want to use this command to control exactly when Logo does it. In particular, the numbers output by the NODES operation will not be very meaningful unless garbage has been collected. Another reason to use GC is that a garbage collection takes a noticeable fraction of a second, and you may want to schedule collections for times before or after some time-critical animation. If invoked with an argument (of any value), GC runs a full garbage collection, including GCTWA (Garbage Collect Truly Worthless Atoms, which means that it removes from Logo's memory words that used to be procedure or variable names but aren't any more); without an argument, GC does a generational garbage collection, which means that only recently created nodes are examined. (The latter is usually good enough.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.setsegmentsize

 
.SETSEGMENTSIZE num

command. Sets the number of nodes that Logo allocates from the operating system at once to num, which mush be a positive integer. The name is dotted because bad things will happen if you use a number that's too small or too large for your computer. The initial value is 16,000 for most systems, but is smaller for 68000-based Macs. Making it larger will speed up computations (by reducing the number of garbage collections) at the cost of allocating more memory than necessary.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_8.html0100644000161300001330000030522410276035442016126 0ustar bhdoe BERKELEY LOGO 5.5: CONTROL STRUCTURES
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8. Control Structures

8.1 Control  
8.2 Template-based Iteration  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.1 Control

Note: in the following descriptions, an instructionlist can be a list or a word. In the latter case, the word is parsed into list form before it is run. Thus, RUN READWORD or RUN READLIST will work. The former is slightly preferable because it allows for a continued line (with ~) that includes a comment (with ;) on the first line.

A tf input must be the word TRUE, the word FALSE, or a list. If it's a list, then it must be a Logo expression, which will be evaluated to produce a value that must be TRUE or FALSE. The comparisons with TRUE and FALSE are always case-insensitive.

run  
runresult  
repeat  
forever  
repcount  
if  
ifelse  
test  
iftrue  
iffalse  
stop  
output  
catch  
throw  
error  
pause  
continue  
wait  
bye  
.maybeoutput  MAYBEOUTPUT
goto  
tag  
ignore  
`  
for  
do.while  DO.WHILE
while  
do.until  DO.UNTIL
until  
case  
cond  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

run

 
RUN instructionlist

command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs.

See section readword , readlist .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

runresult

 
RUNRESULT instructionlist

runs the instructions in the input; outputs an empty list if those instructions produce no output, or a list whose only member is the output from running the input instructionlist. Useful for inventing command-or-operation control structures:

 
local "result
make "result runresult [something]
if emptyp :result [stop]
output first :result


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

repeat

 
REPEAT num instructionlist

command. Runs the instructionlist repeatedly, num times.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

forever

 
FOREVER instructionlist

command. Runs the "instructionlist" repeatedly, until something inside the instructionlist (such as STOP or THROW) makes it stop.

See section stop , See section throw .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

repcount

 
REPCOUNT

outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs --1.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

if

 
IF tf instructionlist
(IF tf instructionlist1 instructionlist2)

command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE.

For compatibility with earlier versions of Logo, if an IF instruction is not enclosed in parentheses, but the first thing on the instruction line after the second input expression is a literal list (i.e., a list in square brackets), the IF is treated as if it were IFELSE, but a warning message is given. If this aberrant IF appears in a procedure body, the warning is given only the first time the procedure is invoked in each Logo session.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ifelse

 
IFELSE tf instructionlist1 instructionlist2

command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

test

 
TEST tf

command. Remembers its input, which must be TRUE or FALSE, for use by later IFTRUE or IFFALSE instructions. The effect of TEST is local to the procedure in which it is used; any corresponding IFTRUE or IFFALSE must be in the same procedure or a subprocedure.

See section iffalse .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

iftrue

 
IFTRUE instructionlist
IFT instructionlist

command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

iffalse

 
IFFALSE instructionlist
IFF instructionlist

command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure.

See section test .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

stop

 
STOP

command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

output

 
OUTPUT value
OP value

command. Ends the running of the procedure in which it appears. That procedure outputs the value value to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

catch

 
CATCH tag instructionlist

command or operation. Runs its second input. Outputs if that instructionlist outputs. If, while running the instructionlist, a THROW instruction is executed with a tag equal to the first input (case-insensitive comparison), then the running of the instructionlist is terminated immediately. In this case the CATCH outputs if a value input is given to THROW. The tag must be a word.

If the tag is the word ERROR, then any error condition that arises during the running of the instructionlist has the effect of THROW "ERROR instead of printing an error message and returning to toplevel. The CATCH does not output if an error is caught. Also, during the running of the instructionlist, the variable ERRACT is temporarily unbound. (If there is an error while ERRACT has a value, that value is taken as an instructionlist to be run after printing the error message. Typically the value of ERRACT, if any, is the list [PAUSE].)

See section error , erract , pause .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

throw

 
THROW tag
(THROW tag value)

command. Must be used within the scope of a CATCH with an equal tag. Ends the running of the instructionlist of the CATCH. If THROW is used with only one input, the corresponding CATCH does not output a value. If THROW is used with two inputs, the second provides an output for the CATCH.

THROW "TOPLEVEL can be used to terminate all running procedures and interactive pauses, and return to the toplevel instruction prompt. Typing the system interrupt character (normally control-C for Unix, control-Q for DOS, or command-period for Mac) has the same effect.

THROW "ERROR can be used to generate an error condition. If the error is not caught, it prints a message (THROW "ERROR) with the usual indication of where the error (in this case the THROW) occurred. If a second input is used along with a tag of ERROR, that second input is used as the text of the error message instead of the standard message. Also, in this case, the location indicated for the error will be, not the location of the THROW, but the location where the procedure containing the THROW was invoked. This allows user-defined procedures to generate error messages as if they were primitives. Note: in this case the corresponding CATCH "ERROR, if any, does not output, since the second input to THROW is not considered a return value.

THROW "SYSTEM immediately leaves Logo, returning to the operating system, without printing the usual parting message and without deleting any editor temporary file written by EDIT.

See section edit .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

error

 
ERROR

outputs a list describing the error just caught, if any. If there was not an error caught since the last use of ERROR, the empty list will be output. The error list contains four members: an integer code corresponding to the type of error, the text of the error message, the name of the procedure in which the error occurred, and the instruction line on which the error occurred.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

pause

 
PAUSE

command or operation. Enters an interactive pause. The user is prompted for instructions, as at toplevel, but with a prompt that includes the name of the procedure in which PAUSE was invoked. Local variables of that procedure are available during the pause. PAUSE outputs if the pause is ended by a CONTINUE with an input.

If the variable ERRACT exists, and an error condition occurs, the contents of that variable are run as an instructionlist. Typically ERRACT is given the value [PAUSE] so that an interactive pause will be entered on the event of an error. This allows the user to check values of local variables at the time of the error.

Typing the system quit character (normally control-\ for Unix, control-W for DOS, or command-comma for Mac) will also enter a pause.

See section erract .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

continue

 
CONTINUE value
CO value
(CONTINUE)
(CO)

command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output.

Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

wait

 
WAIT time

command. Delays further execution for time 60ths of a second. Also causes any buffered characters destined for the terminal to be printed immediately. WAIT 0 can be used to achieve this buffer flushing without actually waiting.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

bye

 
BYE

command. Exits from Logo; returns to the operating system.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.maybeoutput

 
.MAYBEOUTPUT value				(special form)

works like OUTPUT except that the expression that provides the input value might not, in fact, output a value, in which case the effect is like STOP. This is intended for use in control structure definitions, for cases in which you don't know whether or not some expression produces a value. Example:

 
to invoke :function [:inputs] 2
.maybeoutput apply :function :inputs
end

? (invoke "print "a "b "c)
a b c
? print (invoke "word "a "b "c)
abc

This is an alternative to RUNRESULT. It's fast and easy to use, at the cost of being an exception to Logo's evaluation rules. (Ordinarily, it should be an error if the expression that's supposed to provide an input to something doesn't have a value.)

See section output , stop , runresult .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

goto

 
GOTO word

command. Looks for a TAG command with the same input in the same procedure, and continues running the procedure from the location of that TAG. It is meaningless to use GOTO outside of a procedure.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

tag

 
TAG quoted.word

command. Does nothing. The input must be a literal word following a quotation mark ("), not the result of a computation. Tags are used by the GOTO command.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

ignore

 
IGNORE value					(library procedure)

command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

`

 
` list						(library procedure)

outputs a list equal to its input but with certain substitutions. If a member of the input list is the word `,' (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word `,@' (comma atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the `,@' and the instructionlist. Example:

 
show `[foo baz ,[bf [a b c]] garply ,@[bf [a b c]]]

will print

 
[foo baz [b c] garply b c]

A word starting with `,' or `,@' is treated as if the rest of the word were a one-word list, e.g., `,:foo' is equivalent to `,[:Foo]'.

A word starting with `",' (quote comma) or `:,' (colon comma) becomes a word starting with `"' or `:' but with the result of running the substitution (or its first word, if the result is a list) replacing what comes after the comma.

Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found:

 
? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f]
[a ` [b , [1+2] , [foo 4 d] e] f]

?make "name1 "x
?make "name2 "y
? show `[a `[b ,:,:name1 ,",:name2 d] e]
[a ` [b , [:x] , ["y] d] e]


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

for

 
FOR forcontrol instructionlist			(library procedure)

command. The first input must be a list containing three or four members: (1) a word, which will be used as the name of a local variable; (2) a word or list that will be evaluated as by RUN to determine a number, the starting value of the variable; (3) a word or list that will be evaluated to determine a number, the limit value of the variable; (4) an optional word or list that will be evaluated to determine the step size. If the fourth member is missing, the step size will be 1 or --1 depending on whether the limit value is greater than or less than the starting value, respectively.

The second input is an instructionlist. The effect of FOR is to run that instructionlist repeatedly, assigning a new value to the control variable (the one named by the first member of the forcontrol list) each time. First the starting value is assigned to the control variable. Then the value is compared to the limit value. FOR is complete when the sign of (current-limit) is the same as the sign of the step size. (If no explicit step size is provided, the instructionlist is always run at least once. An explicit step size can lead to a zero-trip FOR, e.g., FOR [I 1 0 1] ...). Otherwise, the instructionlist is run, then the step is added to the current value of the control variable and FOR returns to the comparison step.

 
? for [i 2 7 1.5] [print :i]
2
3.5
5
6.5
?

See section run .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

do.while

 
DO.WHILE instructionlist tfexpression		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated remains TRUE. Evaluates the first input first, so the instructionlist is always run at least once. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

while

 
WHILE tfexpression instructionlist		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated remains TRUE. Evaluates the first input first, so the instructionlist may never be run at all. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

do.until

 
DO.UNTIL instructionlist tfexpression		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated remains FALSE. Evaluates the first input first, so the instructionlist is always run at least once. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

until

 
UNTIL tfexpression instructionlist		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated remains FALSE. Evaluates the first input first, so the instructionlist may never be run at all. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

case

 
CASE value clauses					(library procedure)

command or operation. The second input is a list of lists (clauses); each clause is a list whose first element is either a list of values or the word ELSE and whose butfirst is a Logo expression or instruction. CASE examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. If the first input to CASE is a member of the first element of a clause, then the butfirst of that clause is evaluated and CASE outputs its value, if any. If neither of these conditions is met, then CASE goes on to the next clause. If no clause is satisfied, CASE does nothing. Example:

 
to vowelp :letter
output case :letter [ [[a e i o u] "true] [else "false] ]
end


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cond

 
COND clauses						(library procedure)

command or operation. The input is a list of lists (clauses); each clause is a list whose first element is either an expression whose value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo expression or instruction. COND examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. Otherwise, the first element of the clause is evaluated; the resulting value must be TRUE or FALSE. If it's TRUE, then the butfirst of that clause is evaluated and COND outputs its value, if any. If the value is FALSE, then COND goes on to the next clause. If no clause is satisfied, COND does nothing. Example:

 
to evens :numbers	; select even numbers from a list
op cond [ [[emptyp :numbers] []]
          [[evenp first :numbers]	; assuming EVENP is defined
           fput first :numbers evens butfirst :numbers]
          [else evens butfirst :numbers] ]
end


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2 Template-based Iteration

The procedures in this section are iteration tools based on the idea of a template. This is a generalization of an instruction list or an expression list in which slots are provided for the tool to insert varying data. Four different forms of template can be used.

The most commonly used form for a template is `explicit-slot' form, or `question mark' form. Example:

 
? show map [? * ?] [2 3 4 5]
[4 9 16 25]
?

In this example, the MAP tool evaluated the template [? * ?] repeatedly, with each of the members of the data list [2 3 4 5] substituted in turn for the question marks. The same value was used for every question mark in a given evaluation. Some tools allow for more than one datum to be substituted in parallel; in these cases the slots are indicated by ?1 for the first datum, ?2 for the second, and so on:

 
? show (map [(word ?1 ?2 ?1)] [a b c] [d e f])
[ada beb cfc]
?

If the template wishes to compute the datum number, the form (? 1) is equivalent to ?1, so (? ?1) means the datum whose number is given in datum number 1. Some tools allow additional slot designations, as shown in the individual descriptions.

The second form of template is the `named-procedure' form. If the template is a word rather than a list, it is taken as the name of a procedure. That procedure must accept a number of inputs equal to the number of parallel data slots provided by the tool; the procedure is applied to all of the available data in order. That is, if data ?1 through ?3 are available, the template "PROC is equivalent to [PROC ?1 ?2 ?3].

 
? show (map "word [a b c] [d e f])
[ad be cf]
?

to dotprod :a :b	; vector dot product
op apply "sum (map "product :a :b)
end

The third form of template is `named-slot' or `lambda' form. This form is indicated by a template list containing more than one member, whose first member is itself a list. The first member is taken as a list of names; local variables are created with those names and given the available data in order as their values. The number of names must equal the number of available data. This form is needed primarily when one iteration tool must be used within the template list of another, and the ? notation would be ambiguous in the inner template. Example:

 
to matmul :m1 :m2 [:tm2 transpose :m2]	; multiply two matrices
output map [[row] map [[col] dotprod :row :col] :tm2] :m1
end

The fourth form is `procedure text' form, a variant of lambda form. In this form, the template list contains at least two members, all of which are lists. This is the form used by the DEFINE and TEXT primitives, and APPLY accepts it so that the text of a defined procedure can be used as a template.

Note: The fourth form of template is interpreted differently from the others, in that Logo considers it to be an independent defined procedure for the purposes of OUTPUT and STOP. For example, the following two instructions are identical:

 
? print apply [[x] :x+3] [5]
8
? print apply [[x] [output :x+3]] [5]
8

although the first instruction is in named-slot form and the second is in procedure-text form. The named-slot form can be understood as telling Logo to evaluate the expression :x+3 in place of the entire invocation of apply, with the variable x temporarily given the value 5. The procedure-text form can be understood as invoking the procedure

 
to foo :x
output :x+3
end

with input 5, but without actually giving the procedure a name. If the use of OUTPUT were interchanged in these two examples, we'd get errors:

 
? print apply [[x] output :x+3] [5]
Can only use output inside a procedure
? print apply [[x] [:x+3]] [5]
You don't say what to do with 8

The named-slot form can be used with STOP or OUTPUT inside a procedure, to stop the enclosing procedure.

The following iteration tools are extended versions of the ones in Appendix B of the book _Computer_Science_Logo_Style,_Volume_3: _Advanced_Topics_ by Brian Harvey [MIT Press, 1987]. The extensions are primarily to allow for variable numbers of inputs.

apply  
invoke  
foreach  
map  
map.se  MAP.SE
filter  
find  
reduce  
crossmap  
cascade  
cascade.2  CASCADE.2
transfer  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

apply

 
APPLY template inputlist

command or operation. Runs the "template," filling its slots with the members of inputlist. The number of members in inputlist must be an acceptable number of slots for template. It is illegal to apply the primitive TO as a template, but anything else is okay. APPLY outputs what template outputs, if anything.

See section to .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

invoke

 
INVOKE template input				(library procedure)
(INVOKE template input1 input2 ...)

command or operation. Exactly like APPLY except that the inputs are provided as separate expressions rather than in a list.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

foreach

 
FOREACH data template				(library procedure)
(FOREACH data1 data2 ... template)

command. Evaluates the template list repeatedly, once for each member of the data list. If more than one data list are given, each of them must be the same length. (The data inputs can be words, in which case the template is evaluated once for each character.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc.

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

map

 
MAP template data				(library procedure)
(MAP template data1 data2 ...)

outputs a word or list, depending on the type of the data input, of the same length as that data input. (If more than one data input are given, the output is of the same type as data1.) Each member of the output is the result of evaluating the template list, filling the slots with the corresponding member(s) of the data input(s). (All data inputs must be the same length.) In the case of a word output, the results of the template evaluation must be words, and they are concatenated with WORD.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc.

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.

See section word .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

map.se

 
MAP.SE template data				(library procedure)
(MAP.SE template data1 data2 ...)

outputs a list formed by evaluating the template list repeatedly and concatenating the results using SENTENCE. That is, the members of the output are the members of the results of the evaluations. The output list might, therefore, be of a different length from that of the data input(s). (If the result of an evaluation is the empty list, it contributes nothing to the final output.) The data inputs may be words or lists.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc.

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.

See section sentence .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

filter

 
FILTER tftemplate data				(library procedure)

outputs a word or list, depending on the type of the data input, containing a subset of the members (for a list) or characters (for a word) of the input. The template is evaluated once for each member or character of the data, and it must produce a TRUE or FALSE value. If the value is TRUE, then the corresponding input constituent is included in the output.

 
? print filter "vowelp "elephant 
eea 
?

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E].

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

find

 
FIND tftemplate data				(library procedure)

outputs the first constituent of the data input (the first member of a list, or the first character of a word) for which the value produced by evaluating the template with that consituent in its slot is TRUE. If there is no such constituent, the empty list is output.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E].

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

reduce

 
REDUCE template data				(library procedure)

outputs the result of applying the template to accumulate the members of the data input. The template must be a two-slot function. Typically it is an associative function name like "SUM. If the data input has only one constituent (member in a list or character in a word), the output is that consituent. Otherwise, the template is first applied with ?1 filled with the next-to-last consitient and ?2 with the last constituent. Then, if there are more constituents, the template is applied with ?1 filled with the next constituent to the left and ?2 with the result from the previous evaluation. This process continues until all constituents have been used. The data input may not be empty.

Note: If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs:

 
to max :a :b
output ifelse :a > :b [:a] [:b]
end

 
print reduce "max [...]

Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does:

 
to max [:inputs] 2
if emptyp :inputs ~
   [(throw "error [not enough inputs to max])]
output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs
end

See section sum , apply .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

crossmap

 
CROSSMAP template listlist			(library procedure)
(CROSSMAP template data1 data2 ...)

outputs a list containing the results of template evaluations. Each data list contributes to a slot in the template; the number of slots is equal to the number of data list inputs. As a special case, if only one data list input is given, that list is taken as a list of data lists, and each of its members contributes values to a slot. CROSSMAP differs from MAP in that instead of taking members from the data inputs in parallel, it takes all possible combinations of members of data inputs, which need not be the same length.

 
? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4])
[a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4]
?

For compatibility with the version in the first edition of CSLS (1), CROSSMAP templates may use the notation :1 instead of ?1 to indicate slots.

See section map .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cascade

 
CASCADE endtest template startvalue		(library procedure)
(CASCADE endtest tmp1 sv1 tmp2 sv2 ...)
(CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate)

outputs the result of applying a template (or several templates, as explained below) repeatedly, with a given value filling the slot the first time, and the result of each application filling the slot for the following application.

In the simplest case, CASCADE has three inputs. The second input is a one-slot expression template. That template is evaluated some number of times (perhaps zero). On the first evaluation, the slot is filled with the third input; on subsequent evaluations, the slot is filled with the result of the previous evaluation. The number of evaluations is determined by the first input. This can be either a nonnegative integer, in which case the template is evaluated that many times, or a predicate expression template, in which case it is evaluated (with the same slot filler that will be used for the evaluation of the second input) repeatedly, and the CASCADE evaluation continues as long as the predicate value is FALSE. (In other words, the predicate template indicates the condition for stopping.)

If the template is evaluated zero times, the output from CASCADE is the third (startvalue) input. Otherwise, the output is the value produced by the last template evaluation.

CASCADE templates may include the symbol # to represent the number of times the template has been evaluated. This slot is filled with 1 for the first evaluation, 2 for the second, and so on.

 
? show cascade 5 [lput # ?] []
[1 2 3 4 5]
? show cascade [vowelp first ?] [bf ?] "spring
ing
? show cascade 5 [# * ?] 1
120
?

Several cascaded results can be computed in parallel by providing additional template-startvalue pairs as inputs to CASCADE. In this case, all templates (including the endtest template, if used) are multi-slot, with the number of slots equal to the number of pairs of inputs. In each round of evaluations, ?2 represents the result of evaluating the second template in the previous round. If the total number of inputs (including the first endtest input) is odd, then the output from CASCADE is the final value of the first template. If the total number of inputs is even, then the last input is a template that is evaluated once, after the end test is satisfied, to determine the output from CASCADE.

 
to fibonacci :n
output (cascade :n [?1 + ?2] 1 [?1] 0)
end

to piglatin :word
output (cascade [vowelp first ?] ~
   [word bf ? first ?] ~
   :word ~
   [word ? "ay])
end


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

cascade.2

 
CASCADE.2 endtest temp1 startval1 temp2 startval2  (library procedure)

outputs the result of invoking CASCADE with the same inputs. The only difference is that the default number of inputs is five instead of three.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

transfer

 
TRANSFER endtest template inbasket		(library procedure)

outputs the result of repeated evaluation of the template. The template is evaluated once for each member of the list inbasket. TRANSFER maintains an outbasket that is initially the empty list. After each evaluation of the template, the resulting value becomes the new outbasket.

In the template, the symbol ?IN represents the current member from the inbasket; the symbol ?OUT represents the entire current outbasket. Other slot symbols should not be used.

If the first (endtest) input is an empty list, evaluation continues until all inbasket members have been used. If not, the first input must be a predicate expression template, and evaluation continues until either that template's value is TRUE or the inbasket is used up.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_9.html0100644000161300001330000003550210276035442016126 0ustar bhdoe BERKELEY LOGO 5.5: MACROS
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9. Macros

.macro  MACRO
.defmacro  DEFMACRO
macrop  
macroexpand  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.macro

 
.MACRO procname :input1 :input2 ...			(special form)
.DEFMACRO procname text

A macro is a special kind of procedure whose output is evaluated as Logo instructions in the context of the macro's caller. .MACRO is exactly like TO except that the new procedure becomes a macro; .DEFMACRO is exactly like DEFINE with the same exception.

Macros are useful for inventing new control structures comparable to REPEAT, IF, and so on. Such control structures can almost, but not quite, be duplicated by ordinary Logo procedures. For example, here is an ordinary procedure version of REPEAT:

 
to my.repeat :num :instructions
if :num=0 [stop]
run :instructions
my.repeat :num-1 :instructions
end

This version works fine for most purposes, e.g.,

 
my.repeat 5 [print "hello]

But it doesn't work if the instructions to be carried out include OUTPUT, STOP, or LOCAL. For example, consider this procedure:

 
to example
print [Guess my secret word.  You get three guesses.]
repeat 3 [type "|?? | ~
   if readword = "secret [pr "Right! stop]]
print [Sorry, the word was "secret"!]
end

This procedure works as written, but if MY.REPEAT is used instead of REPEAT, it won't work because the STOP will stop MY.REPEAT instead of stopping EXAMPLE as desired.

The solution is to make MY.REPEAT a macro. Instead of actually carrying out the computation, a macro must return a list containing Logo instructions. The contents of that list are evaluated as if they appeared in place of the call to the macro. Here's a macro version of REPEAT:

 
.macro my.repeat :num :instructions
if :num=0 [output []]
output sentence :instructions ~
   (list "my.repeat :num-1 :instructions)
end

Every macro is an operation -- it must always output something. Even in the base case, MY.REPEAT outputs an empty instruction list. To show how MY.REPEAT works, let's take the example

 
my.repeat 5 [print "hello]

For this example, MY.REPEAT will output the instruction list

 
		[print "hello my.repeat 4 [print "hello]]

Logo then executes these instructions in place of the original invocation of MY.REPEAT; this prints hello once and invokes another repetition.

The technique just shown, although fairly easy to understand, has the defect of slowness because each repetition has to construct an instruction list for evaluation. Another approach is to make my.repeat a macro that works just like the non-macro version unless the instructions to be repeated include OUTPUT or STOP:

 
.macro my.repeat :num :instructions
catch "repeat.catchtag ~
   [op repeat.done runresult [repeat1 :num :instructions]]
op []
end

to repeat1 :num :instructions
if :num=0 [throw "repeat.catchtag]
run :instructions
.maybeoutput repeat1 :num-1 :instructions
end

to repeat.done :repeat.result
if emptyp :repeat.result [op [stop]]
op list "output quoted first :repeat.result
end

If the instructions do not include STOP or OUTPUT, then REPEAT1 will reach its base case and invoke THROW. As a result, my.repeat's last instruction line will output an empty list, so the second evaluation of the macro result will do nothing. But if a STOP or OUTPUT happens, then REPEAT.DONE will output a STOP or OUTPUT instruction that will be re-executed in the caller's context.

The macro-defining commands have names starting with a dot because macros are an advanced feature of Logo; it's easy to get in trouble by defining a macro that doesn't terminate, or by failing to construct the instruction list properly.

Lisp users should note that Logo macros are NOT special forms. That is, the inputs to the macro are evaluated normally, as they would be for any other Logo procedure. It's only the output from the macro that's handled unusually.

Here's another example:

 
.macro localmake :name :value
output (list "local~
   word "" :name   ~
   "apply          ~
   ""make          ~
   (list :name :value))
end

It's used this way:

 
to try
localmake "garply "hello
print :garply
end

LOCALMAKE outputs the list

 
		[local "garply apply "make [garply hello]]

The reason for the use of APPLY is to avoid having to decide whether or not the second input to MAKE requires a quotation mark before it. (In this case it would -- MAKE "GARPLY "HELLO -- but the quotation mark would be wrong if the value were a list.)

It's often convenient to use the ` function to construct the instruction list:

 
.macro localmake :name :value
op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]]
end

On the other hand, ` is pretty slow, since it's tree recursive and written in Logo.

See section to , define , apply , stop , output .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

.defmacro

See section .macro .


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

macrop

 
MACROP name
MACRO? name

outputs TRUE if its input is the name of a macro.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

macroexpand

 
MACROEXPAND expr				(library procedure)

takes as its input a Logo expression that invokes a macro (that is, one that begins with the name of a macro) and outputs the the Logo expression into which the macro would translate the input expression.

 
.macro localmake :name :value
op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]]
end

? show macroexpand [localmake "pi 3.14159]
[local "pi apply "make [pi 3.14159]]


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_abt.html0100644000161300001330000000732710276035443016531 0ustar bhdoe BERKELEY LOGO 5.5: About this document
[Top] [Contents] [Index] [ ? ]

About this document

This document was generated by Brian Harvey on August, 8 2005 using texi2html

The buttons in the navigation panels have the following meaning:

Button Name Go to From 1.2.3 go to
[ < ] Back previous section in reading order 1.2.2
[ > ] Forward next section in reading order 1.2.4
[ << ] FastBack previous or up-and-previous section 1.1
[ Up ] Up up section 1.2
[ >> ] FastForward next or up-and-next section 1.3
[Top] Top cover (top) of document  
[Contents] Contents table of contents  
[Index] Index concept index  
[ ? ] About this page  

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
  • 1. Section One
    • 1.1 Subsection One-One
      • ...
    • 1.2 Subsection One-Two
      • 1.2.1 Subsubsection One-Two-One
      • 1.2.2 Subsubsection One-Two-Two
      • 1.2.3 Subsubsection One-Two-Three     <== Current Position
      • 1.2.4 Subsubsection One-Two-Four
    • 1.3 Subsection One-Three
      • ...
    • 1.4 Subsection One-Four


This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_fot.html0100644000161300001330000000320310276035442016537 0ustar bhdoe BERKELEY LOGO 5.5: Footnotes
[Top] [Contents] [Index] [ ? ]

Footnotes

(1)

Computer Science Logo Style



This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual.html0100644000161300001330000000720510276035441015674 0ustar bhdoe BERKELEY LOGO 5.5: BERKELEY LOGO 5.5
[Top] [Contents] [Index] [ ? ]

BERKELEY LOGO 5.5

1. Introduction  
2. Data Structure Primitives  
3. Communication  
4. Arithmetic  
5. Logical Operations  
6. Graphics  
7. Workspace Management  
8. Control Structures  
9. Macros  
10. Error Processing  
11. Special Variables  
12. Internationalization  
INDEX  



This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_ovr.html0100644000161300001330000000511510276035443016562 0ustar bhdoe BERKELEY LOGO 5.5: Short Table of Contents
[Top] [Contents] [Index] [ ? ]

Short Table of Contents

1. Introduction
2. Data Structure Primitives
3. Communication
4. Arithmetic
5. Logical Operations
6. Graphics
7. Workspace Management
8. Control Structures
9. Macros
10. Error Processing
11. Special Variables
12. Internationalization
INDEX


This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/html/usermanual_toc.html0100644000161300001330000006520110276035443016543 0ustar bhdoe BERKELEY LOGO 5.5: Table of Contents
[Top] [Contents] [Index] [ ? ]

Table of Contents



This document was generated by Brian Harvey on August, 8 2005 using texi2html ucblogo-5.5/docs/makefile0100644000161300001330000000217210153114172013355 0ustar bhdoeBUILDIR = `pwd` INFODIR = $(prefix)/info DOCSDIR = $(LIBLOC)/docs HTMLDIR = $(DOCSDIR)/html all: usermanual.ps usermanual.pdf html/usermanual_1.html ucblogo.info ucblogo.info: usermanual.texi makeinfo usermanual.texi usermanual.dvi: usermanual.texi tex --interaction batchmode usermanual.texi tex --interaction batchmode usermanual.texi texindex usermanual.cp tex --interaction batchmode usermanual.texi usermanual.ps: usermanual.dvi dvips -t letter -o usermanual.ps usermanual.dvi usermanual.pdf: usermanual.ps usermanual.dvi ps2pdf usermanual.ps dvipdf usermanual.dvi html/usermanual_1.html: usermanual.texi for d in html; do [ -d $$d ] || mkdir -p $$d || exit 1; done texi2html -expand tex -split chapter usermanual.texi mv *.html html ship: -rm -f *.{aux,cp,cps,dvi,fn,ky,log,pg,toc,tp,vr} install: all for d in $(INFODIR) $(DOCSDIR) $(HTMLDIR); do [ -d $$d ] || mkdir -p $$d || exit 1; done -cp -f *.info* $(INFODIR)/. -cp -f html/*.html $(HTMLDIR)/. -cp -f usermanual.ps $(DOCSDIR)/. -cp -f usermanual.pdf $(DOCSDIR)/. -cp -f usermanual.texi $(DOCSDIR)/. -cp -f ../usermanual $(DOCSDIR)/. ucblogo-5.5/docs/ucblogo.info-10100644000161300001330000013743410276035443014345 0ustar bhdoeThis is ucblogo.info, produced by makeinfo version 4.5 from usermanual.texi.  File: ucblogo.info, Node: Top, Next: INTRODUCTION, Prev: (dir), Up: (dir) This is a TeXinfo version of Berkeley Logo User Manual Original written by: Brian Harvey * Menu: * INTRODUCTION:: * DATA STRUCTURE PRIMITIVES:: * COMMUNICATION:: * ARITHMETIC:: * LOGICAL OPERATIONS:: * GRAPHICS:: * WORKSPACE MANAGEMENT:: * CONTROL STRUCTURES:: * MACROS:: * ERROR PROCESSING:: * SPECIAL VARIABLES:: * INTERNATIONALIZATION:: * INDEX::  File: ucblogo.info, Node: INTRODUCTION, Next: DATA STRUCTURE PRIMITIVES, Prev: Top, Up: Top Introduction ************ * Menu: * OVERVIEW:: * GETTER/SETTER VARIBLE SYNTAX:: * ENTERING AND LEAVING LOGO:: * TOKENIZATION::  File: ucblogo.info, Node: OVERVIEW, Next: GETTER/SETTER VARIBLE SYNTAX, Prev: INTRODUCTION, Up: INTRODUCTION Overview ======== Copyright (C) 1993 by the Regents of the University of California This program 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 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. This is a program that is still being written. Many things are missing, including adequate documentation. This manual assumes that you already know how to program in Logo, and merely presents the details of this new implementation. Read Computer_Science_Logo_Style, Volume_1:_ _Symbolic_Computing_ by Brian Harvey (MIT Press, 1997) for a tutorial on Logo programming with emphasis on symbolic computation. Here are the special features of this dialect of Logo: Source file compatible among Unix, DOS, Windows, and Mac platforms. Random-access arrays. Variable number of inputs to user-defined procedures. Mutators for list structure (dangerous). Pause on error, and other improvements to error handling. Comments and continuation lines; formatting is preserved when procedure definitions are saved or edited. Terrapin-style tokenization (e.g., [2+3] is a list with one member) but LCSI-style syntax (no special forms except TO). The best of both worlds. First-class instruction and expression templates (see APPLY). Macros. Features *not* found in Berkeley Logo include robotics, music, GUIs, animation, parallelism, and multimedia. For those, buy a commercial version.  File: ucblogo.info, Node: GETTER/SETTER VARIBLE SYNTAX, Next: ENTERING AND LEAVING LOGO, Prev: OVERVIEW, Up: INTRODUCTION Getter/Setter Variable Syntax ============================= Logo distinguishes PROCEDURES from VARIABLES. A procedure is a set of instructions to carry out some computation; a variable is a named container that holds a data value such as a number, word, list, or array. In traditional Logo syntax, a non-numeric word typed without punctuation represents a request to invoke the procedure named by that word. A word typed with a preceding quotation mark represents the word itself. For example, in the instruction PRINT FIRST "WORD the procedures named `FIRST' and `PRINT' are invoked, but the procedure named WORD is not invoked; the word W-O-R-D is the input to FIRST. What about variables? There are two things one can do with a variable: give it a value, and find out its value. To give a variable a value, Logo provides the primitive procedure `MAKE', which requires two inputs: the name of the variable and the new value to be assigned. The first input, the name of the variable, is just a word, and if (as is almost always the case) the programmer wants to assign a value to a specific variable whose name is known in advance, that input is quoted, just as any known specific word would be: MAKE "MY.VAR FIRST "WORD gives the variable named MY.VAR the value W (the first letter of WORD). To find the value of a variable, Logo provides the primitive procedure `THING', which takes a variable name as its input, and outputs the value of the accessible variable with that name. Thus PRINT THING "MY.VAR will print W (supposing the `MAKE' above has been done). Since finding the value of a specific, known variable name is such a common operation, Logo also provides an abbreviated notation that combines `THING' with quote: PRINT :MY.VAR The colon (which Logo old-timers pronounce "dots") replaces `THING' and `"' in the earlier version of the instruction. Newcomers to Logo often complain about the need for all this punctuation. In particular, Logo programmers who learned about dots and quotes without also learning about `THING' wonder why an instruction such as MAKE "NEW.VAR :OLD.VAR uses two different punctuation marks to identify the two variables. (Having read the paragraphs above, you will understand that actually both variable names are quoted, but the procedure `THING' is invoked to find the value of OLD.VAR, since it's that value, not OLD.VAR's name, that `MAKE' needs to know. It wouldn't make sense to ask for `THING' of NEW.VAR, since we haven't given NEW.VAR a value yet.) Although Logo's punctuation rules make sense once understood, they do form a barrier to entry for the Logo beginner. Why, then, couldn't Logo be designed so that an unpunctuated word would represent a procedure if there is a procedure by that name, or a variable if there is a variable by that name? Then we could say PRINT MY.VAR and Logo would realize that MY.VAR is the name of a variable, not of a procedure. The traditional reason not to use this convention is that Logo allows the same word to name a procedure and a variable at the same time. This is most often important for words that name data types, as in the following procedure: TO PLURAL :WORD OUTPUT WORD :WORD "S END Here the name WORD is a natural choice for the input to `PLURAL', since it describes the kind of input that `PLURAL' expects. Within the procedure, we use `WORD' to represent Logo's primitive procedure that combines two input words to form a new, longer word; we use `:WORD' to represent the variable containing the input, whatever actual word is given when PLURAL is invoked. ? PRINT PLURAL "COMPUTER COMPUTERS However, if a Logo instruction includes an unquoted word that is *not* the name of a procedure, Logo could look for a variable of that name instead. This would allow a "punctuationless" Logo, ** PROVIDED THAT USERS WHO WANT TO WORK WITHOUT COLONS FOR VARIABLES CHOOSE VARIABLE NAMES THAT ARE NOT ALSO PROCEDURE NAMES. ** What about assigning a value to a variable? Could we do without the quotation mark on `MAKE''s first input? Alas, no. Although the first input to `MAKE' is *usually* a constant, known variable name, sometimes it isn't, as in this example: TO INCREMENT :VAR MAKE :VAR (THING :VAR)+1 ; Note: it's not "VAR here! END ? MAKE "X 5 ? INCREMENT "X ? PRINT :X 6 The procedure `INCREMENT' takes a variable name as its input and changes the value of that variable. In this example there are two variables; the variable whose name is VAR, and whose value is the word X; and the variable whose name is X and whose value changes from 5 to 6. Suppose we changed the behavior of `MAKE' so that it took the word after `MAKE' as the name of the variable to change; we would be unable to write `INCREMENT': TO INCREMENT :VAR ; nonworking! MAKE VAR (THING VAR)+1 END This would assign a new value to VAR, not to X. What we can do is to allow an *alternative* to `MAKE', a "setter" procedure for a particular variable. The notation will be ? SETFOO 7 ? PRINT FOO 7 `SETFOO' is a "setter procedure" that takes one input (in this case the input 7) and assigns its value to the variable named FOO. Berkeley Logo allows users to choose either the traditional notation, in which case the same name can be used both for a procedure and for a variable, or the getter/setter notation, in which variable FOO is set with `SETFOO' and examined with FOO, but the same name can't be used for procedure and variable. Here is how this choice is allowed: Berkeley Logo uses traditional notation, with procedures distinct from variables. However, if there is a variable named ALLOWGETSET whose value is TRUE (which there is, by default, when Logo starts up), then if a Logo instruction refers to a *nonexistent* procedure (so that the error message "I don't know how to ..." would result), Logo tries the following two steps: 1. If the name is at least four characters long, and the first three characters are the letters SET (upper or lower case), and if the name is followed in the instruction by another value, and if the name without the SET is the name of a variable that already exists, then Logo will invoke `MAKE' with its first input being the name without the SET, and its second input being the following value. 2. If step 1's conditions are not met, but the name is the name of an accessible variable, then Logo will invoke `THING' with that name as input, to find the variable's value. Step 1 requires that the variable already exist so that misspellings of names of SETxxx primitives (e.g., `SETHEADING') will still be caught, instead of silently creating a new variable. The command `GLOBAL' can be used to create a variable without giving it a value. One final point: The `TO' command in Logo has always been a special case; the rest of the line starting with TO is not evaluated as ordinary Logo expressions are. In particular, the colons used to mark the names of inputs to the procedure do not cause `THING' to be invoked. They are merely mnemonic aids, reminding the Logo user that these words are names of variables. (Arguably, this nonstantard behavior of TO adds to Logo beginners' confusion about colons.) To a programmer using colonless variable references, the colons in the TO line are unnecessary and meaningless. Berkeley Logo therefore makes the colons optional: TO FOO :IN1 :IN2 and TO FOO IN1 IN2 are both allowed.  File: ucblogo.info, Node: ENTERING AND LEAVING LOGO, Next: TOKENIZATION, Prev: GETTER/SETTER VARIBLE SYNTAX, Up: INTRODUCTION Entering and Leaving Logo ========================= The process to start Logo depends on your operating system: `Unix:' Type the word logo to the shell. (The directory in which you've installed Logo must be in your path.) `DOS:' Change directories to the one containing Logo (probably C:\UCBLOGO). Then type UCBLOGO for the large memory version, or BL for the 640K version. `Mac:' Double-click on the LOGO icon within the "UCB Logo" folder. `Windows:' Double-click on the UCBWLOGO icon in the UCBLOGO folder. To leave Logo, enter the command bye. After initialization, Logo looks for a file in the current working directory named startup.lg and, if one is found, executes the Logo instructions in it. Then, under Unix, DOS, or Windows, if you include one or more filenames on the command line when starting Logo, those files will be loaded before the interpreter starts reading commands from your terminal. If you load a file that executes some program that includes a `BYE' command, Logo will run that program and exit. You can therefore write standalone programs in Logo and run them with shell/batch scripts. To support this technique, Logo does not print its usual welcoming and parting messages if you give file arguments to the logo command. If you type your interrupt character (see table below) Logo will stop what it's doing and return to top-level, as if you did THROW "TOPLEVEL. If you type your quit character Logo will pause as if you did PAUSE. Unix DOS/Windows Mac toplevel usually ctrl-C ctrl-Q command-. (period) pause usually ctrl-\ ctrl-W command-, (comma) If you have an environment variable called LOGOLIB whose value is the name of a directory, then Logo will use that directory instead of the default library. If you invoke a procedure that has not been defined, Logo first looks for a file in the current directory named proc.lg where `proc' is the procedure name in lower case letters. If such a file exists, Logo loads that file. If the missing procedure is still undefined, or if there is no such file, Logo then looks in the library directory for a file named proc (no `.lg') and, if it exists, loads it. If neither file contains a definition for the procedure, then Logo signals an error. Several procedures that are primitive in most versions of Logo are included in the default library, so if you use a different library you may want to include some or all of the default library in it.  File: ucblogo.info, Node: TOKENIZATION, Prev: ENTERING AND LEAVING LOGO, Up: INTRODUCTION Tokenization ============ Names of procedures, variables, and property lists are case-insensitive. So are the special words END, TRUE, and FALSE. Case of letters is preserved in everything you type, however. Within square brackets, words are delimited only by spaces and square brackets. [2+3] is a list containing one word. Note, however, that the Logo primitives that interpret such a list as a Logo instruction or expression (RUN, IF, etc.) reparse the list as if it had not been typed inside brackets. After a quotation mark outside square brackets, a word is delimited by a space, a square bracket, or a parenthesis. A word not after a quotation mark or inside square brackets is delimited by a space, a bracket, a parenthesis, or an infix operator +-*/=<>. Note that words following colons are in this category. Note that quote and colon are not delimiters. Each infix operator character is a word in itself, except that the two-character sequences <= >= and <> (the latter meaning not-equal) with no intervening space are recognized as a single word. A word consisting of a question mark followed by a number (e.g., ?37), when runparsed (i.e., where a procedure name is expected), is treated as if it were the sequence ( ? 37 ) making the number an input to the ? procedure. (See the discussion of templates, below.) This special treatment does not apply to words read as data, to words with a non-number following the question mark, or if the question mark is backslashed. A line (an instruction line or one read by READLIST or READWORD) can be continued onto the following line if its last character is a tilde (~). READWORD preserves the tilde and the newline; READLIST does not. Lines read with READRAWLINE are never continued. An instruction line or a line read by READLIST (but not by READWORD) is automatically continued to the next line, as if ended with a tilde, if there are unmatched brackets, parentheses, braces, or vertical bars pending. However, it's an error if the continuation line contains only the word END; this is to prevent runaway procedure definitions. Lines explicitly continued with a tilde avoid this restriction. If a line being typed interactively on the keyboard is continued, either with a tilde or automatically, Logo will display a tilde as a prompt character for the continuation line. A semicolon begins a comment in an instruction line. Logo ignores characters from the semicolon to the end of the line. A tilde as the last character still indicates a continuation line, but not a continuation of the comment. For example, typing the instruction print "abc;comment ~ def will print the word abcdef. Semicolon has no special meaning in data lines read by READWORD or READLIST, but such a line can later be reparsed using RUNPARSE and then comments will be recognized. The two-character sequence #! at the beginning of a line also starts a comment. Unix users can therefore write a file containing Logo commands, starting with the line #! /usr/local/bin/logo (or wherever your Logo executable lives) and the file will be executable directly from the shell. To include an otherwise delimiting character (including semicolon or tilde) in a word, precede it with backslash (\). If the last character of a line is a backslash, then the newline character following the backslash will be part of the last word on the line, and the line continues onto the following line. To include a backslash in a word, use \\. If the combination backslash-newline is entered at the terminal, Logo will issue a backslash as a prompt character for the continuation line. All of this applies to data lines read with READWORD or READLIST as well as to instruction lines. A character entered with backslash is EQUALP to the same character without the backslash, but can be distinguished by the BACKSLASHEDP predicate. (However, BACKSLASHEDP recognizes backslashedness only on characters for which it is necessary: whitespace, parentheses, brackets, infix operators, backslash, vertical bar, tilde, quote, question mark, colon, and semicolon.) A line read with READRAWLINE has no special quoting mechanism; both backslash and vertical bar (described below) are just ordinary characters. An alternative notation to include otherwise delimiting characters in words is to enclose a group of characters in vertical bars. All characters between vertical bars are treated as if they were letters. In data read with READWORD the vertical bars are preserved in the resulting word. In data read with READLIST (or resulting from a PARSE or RUNPARSE of a word) the vertical bars do not appear explicitly; all potentially delimiting characters (including spaces, brackets, parentheses, and infix operators) appear as though entered with a backslash. Within vertical bars, backslash may still be used; the only characters that must be backslashed in this context are backslash and vertical bar themselves. Characters entered between vertical bars are forever special, even if the word or list containing them is later reparsed with PARSE or RUNPARSE. Characters typed after a backslash are treated somewhat differently: When a quoted word containing a backslashed character is runparsed, the backslashed character loses its special quality and acts thereafter as if typed normally. This distinction is important only if you are building a Logo expression out of parts, to be RUN later, and want to use parentheses. For example, PRINT RUN (SE "\( 2 "+ 3 "\)) will print 5, but RUN (SE "MAKE ""|(| 2) will create a variable whose name is open-parenthesis. (Each example would fail if vertical bars and backslashes were interchanged.)  File: ucblogo.info, Node: DATA STRUCTURE PRIMITIVES, Next: COMMUNICATION, Prev: INTRODUCTION, Up: Top Data Structure Primitives ************************* * Menu: * CONSTRUCTORS:: * SELECTORS:: * MUTATORS:: * PREDICATES:: * QUERIES::  File: ucblogo.info, Node: CONSTRUCTORS, Next: SELECTORS, Prev: DATA STRUCTURE PRIMITIVES, Up: DATA STRUCTURE PRIMITIVES Constructors ============ * Menu: * WORD:: * LIST:: * SENTENCE:: * FPUT:: * LPUT:: * ARRAY:: * MDARRAY:: * LISTTOARRAY:: * ARRAYTOLIST:: * COMBINE:: * REVERSE:: * GENSYM::  File: ucblogo.info, Node: WORD, Next: LIST, Prev: CONSTRUCTORS, Up: CONSTRUCTORS word ---- WORD word1 word2 (WORD word1 word2 word3 ...) outputs a word formed by concatenating its inputs.  File: ucblogo.info, Node: LIST, Next: SENTENCE, Prev: WORD, Up: CONSTRUCTORS list ---- LIST thing1 thing2 (LIST thing1 thing2 thing3 ...) outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array).  File: ucblogo.info, Node: SENTENCE, Next: FPUT, Prev: LIST, Up: CONSTRUCTORS sentence -------- SENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...) outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists.  File: ucblogo.info, Node: FPUT, Next: LPUT, Prev: SENTENCE, Up: CONSTRUCTORS fput ---- FPUT thing list outputs a list equal to its second input with one extra member, the first input, at the beginning. If the second input is a word, then the first input must be a one-letter word, and FPUT is equivalent to WORD.  File: ucblogo.info, Node: LPUT, Next: ARRAY, Prev: FPUT, Up: CONSTRUCTORS lput ---- LPUT thing list outputs a list equal to its second input with one extra member, the first input, at the end. If the second input is a word, then the first input must be a one-letter word, and LPUT is equivalent to WORD with its inputs in the other order.  File: ucblogo.info, Node: ARRAY, Next: MDARRAY, Prev: LPUT, Up: CONSTRUCTORS array ----- ARRAY size (ARRAY size origin) outputs an array of `size' members (must be a positive integer), each of which initially is an empty list. Array members can be selected with ITEM and changed with SETITEM. The first member of the array is member number 1 unless an `origin' input (must be an integer) is given, in which case the first member of the array has that number as its index. (Typically 0 is used as the origin if anything.) Arrays are printed by PRINT and friends, and can be typed in, inside curly braces; indicate an origin with {a b c}@0. *Note ITEM:: , *Note SETITEM:: , *Note PRINT:: .  File: ucblogo.info, Node: MDARRAY, Next: LISTTOARRAY, Prev: ARRAY, Up: CONSTRUCTORS mdarray ------- MDARRAY sizelist (library procedure) (MDARRAY sizelist origin) outputs a multi-dimensional array. The first input must be a list of one or more positive integers. The second input, if present, must be a single integer that applies to every dimension of the array. Ex: (MDARRAY [3 5] 0) outputs a two-dimensional array whose members range from [0 0] to [2 4].  File: ucblogo.info, Node: LISTTOARRAY, Next: ARRAYTOLIST, Prev: MDARRAY, Up: CONSTRUCTORS listtoarray ----------- LISTTOARRAY list (LISTTOARRAY list origin) outputs an array of the same size as the input list, whose members are the members of the input list.  File: ucblogo.info, Node: ARRAYTOLIST, Next: COMBINE, Prev: LISTTOARRAY, Up: CONSTRUCTORS arraytolist ----------- ARRAYTOLIST array outputs a list whose members are the members of the input array. The first member of the output is the first member of the array, regardless of the array's origin.  File: ucblogo.info, Node: COMBINE, Next: REVERSE, Prev: ARRAYTOLIST, Up: CONSTRUCTORS combine ------- COMBINE thing1 thing2 (library procedure) if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2. *Note WORD:: , *Note FPUT::  File: ucblogo.info, Node: REVERSE, Next: GENSYM, Prev: COMBINE, Up: CONSTRUCTORS reverse ------- REVERSE list (library procedure) outputs a list whose members are the members of the input list, in reverse order.  File: ucblogo.info, Node: GENSYM, Prev: REVERSE, Up: CONSTRUCTORS gensym ------ GENSYM (library procedure) outputs a unique word each time it's invoked. The words are of the form G1, G2, etc.  File: ucblogo.info, Node: SELECTORS, Next: MUTATORS, Prev: CONSTRUCTORS, Up: DATA STRUCTURE PRIMITIVES Data Selectors ============== * Menu: * FIRST:: * FIRSTS:: * LAST:: * BUTFIRST:: * BUTFIRSTS:: * BUTLAST:: * ITEM:: * MDITEM:: * PICK:: * REMOVE:: * REMDUP:: * QUOTED::  File: ucblogo.info, Node: FIRST, Next: FIRSTS, Prev: SELECTORS, Up: SELECTORS first ----- FIRST thing if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array).  File: ucblogo.info, Node: FIRSTS, Next: LAST, Prev: FIRST, Up: SELECTORS firsts ------ FIRSTS list outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as to firsts :list output map "first :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. to transpose :matrix if emptyp first :matrix [op []] op fput firsts :matrix transpose bfs :matrix end *Note MAP:: , *Note MAPdSE:: , *Note FOREACH::  File: ucblogo.info, Node: LAST, Next: BUTFIRST, Prev: FIRSTS, Up: SELECTORS last ---- LAST wordorlist if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list.  File: ucblogo.info, Node: BUTFIRST, Next: BUTFIRSTS, Prev: LAST, Up: SELECTORS butfirst -------- BUTFIRST wordorlist BF wordorlist if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input.  File: ucblogo.info, Node: BUTFIRSTS, Next: BUTLAST, Prev: BUTFIRST, Up: SELECTORS butfirsts --------- BUTFIRSTS list BFS list outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as to butfirsts :list output map "butfirst :list end but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH. *Note MAP:: , *Note MAPdSE:: , *Note FOREACH::  File: ucblogo.info, Node: BUTLAST, Next: ITEM, Prev: BUTFIRSTS, Up: SELECTORS butlast ------- BUTLAST wordorlist BL wordorlist if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input.  File: ucblogo.info, Node: ITEM, Next: MDITEM, Prev: BUTLAST, Up: SELECTORS item ---- ITEM index thing if the `thing' is a word, outputs the `index'th character of the word. If the `thing' is a list, outputs the `index'th member of the list. If the `thing' is an array, outputs the `index'th member of the array. `Index' starts at 1 for words and lists; the starting index of an array is specified when the array is created.  File: ucblogo.info, Node: MDITEM, Next: PICK, Prev: ITEM, Up: SELECTORS mditem ------ MDITEM indexlist array (library procedure) outputs the member of the multidimensional `array' selected by the list of numbers `indexlist'.  File: ucblogo.info, Node: PICK, Next: REMOVE, Prev: MDITEM, Up: SELECTORS pick ---- PICK list (library procedure) outputs a randomly chosen member of the input list.  File: ucblogo.info, Node: REMOVE, Next: REMDUP, Prev: PICK, Up: SELECTORS remove ------ REMOVE thing list (library procedure) outputs a copy of `list' with every member equal to `thing' removed.  File: ucblogo.info, Node: REMDUP, Next: QUOTED, Prev: REMOVE, Up: SELECTORS remdup ------ REMDUP list (library procedure) outputs a copy of `list' with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output.  File: ucblogo.info, Node: QUOTED, Prev: REMDUP, Up: SELECTORS quoted ------ QUOTED thing (library procedure) outputs its input, if a list; outputs its input with a quotation mark prepended, if a word.  File: ucblogo.info, Node: MUTATORS, Next: PREDICATES, Prev: SELECTORS, Up: DATA STRUCTURE PRIMITIVES Data Mutators ============= * Menu: * SETITEM:: * MDSETITEM:: * dSETFIRST:: SETFIRST * dSETBF:: SETBF * dSETITEM:: SETITEM * PUSH:: * POP:: * QUEUE:: * DEQUEUE::  File: ucblogo.info, Node: SETITEM, Next: MDSETITEM, Prev: MUTATORS, Up: MUTATORS setitem ------- SETITEM index array value command. Replaces the `index'th member of `array' with the new `value'. Ensures that the resulting array is not circular, i.e., `value' may not be a list or array that contains `array'.  File: ucblogo.info, Node: MDSETITEM, Next: dSETFIRST, Prev: SETITEM, Up: MUTATORS mdsetitem --------- MDSETITEM indexlist array value (library procedure) command. Replaces the member of `array' chosen by `indexlist' with the new `value'.  File: ucblogo.info, Node: dSETFIRST, Next: dSETBF, Prev: MDSETITEM, Up: MUTATORS .setfirst --------- .SETFIRST list value command. Changes the first member of `list' to be `value'. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; and the loss of memory if a circular structure is released.  File: ucblogo.info, Node: dSETBF, Next: dSETITEM, Prev: dSETFIRST, Up: MUTATORS .setbf ------ .SETBF list value command. Changes the butfirst of `list' to be `value'. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; Logo crashes and coredumps if the butfirst of a list is not itself a list; and the loss of memory if a circular structure is released.  File: ucblogo.info, Node: dSETITEM, Next: PUSH, Prev: dSETBF, Up: MUTATORS .setitem -------- .SETITEM index array value command. Changes the `index'th member of `array' to be `value', like SETITEM, but without checking for circularity. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETITEM can lead to circular arrays, which will get some Logo primitives into infinite loops; and the loss of memory if a circular structure is released. *Note SETITEM::.  File: ucblogo.info, Node: PUSH, Next: POP, Prev: dSETITEM, Up: MUTATORS push ---- PUSH stackname thing (library procedure) command. Adds the `thing' to the stack that is the value of the variable whose name is `stackname'. This variable must have a list as its value; the initial value should be the empty list. New members are added at the front of the list.  File: ucblogo.info, Node: POP, Next: QUEUE, Prev: PUSH, Up: MUTATORS pop --- POP stackname (library procedure) outputs the most recently PUSHed member of the stack that is the value of the variable whose name is `stackname' and removes that member from the stack.  File: ucblogo.info, Node: QUEUE, Next: DEQUEUE, Prev: POP, Up: MUTATORS queue ----- QUEUE queuename thing (library procedure) command. Adds the `thing' to the queue that is the value of the variable whose name is `queuename'. This variable must have a list as its value; the initial value should be the empty list. New members are added at the back of the list.  File: ucblogo.info, Node: DEQUEUE, Prev: QUEUE, Up: MUTATORS dequeue ------- DEQUEUE queuename (library procedure) outputs the least recently QUEUEd member of the queue that is the value of the variable whose name is `queuename' and removes that member from the queue.  File: ucblogo.info, Node: PREDICATES, Next: QUERIES, Prev: MUTATORS, Up: DATA STRUCTURE PRIMITIVES Predicates ========== * Menu: * WORDP:: * LISTP:: * ARRAYP:: * EMPTYP:: * EQUALP:: * NOTEQUALP:: * BEFOREP:: * dEQ:: EQ * MEMBERP:: * SUBSTRINGP:: * NUMBERP:: * BACKSLASHEDP::  File: ucblogo.info, Node: WORDP, Next: LISTP, Prev: PREDICATES, Up: PREDICATES wordp ----- WORDP thing WORD? thing outputs TRUE if the input is a word, FALSE otherwise.  File: ucblogo.info, Node: LISTP, Next: ARRAYP, Prev: WORDP, Up: PREDICATES listp ----- LISTP thing LIST? thing outputs TRUE if the input is a list, FALSE otherwise.  File: ucblogo.info, Node: ARRAYP, Next: EMPTYP, Prev: LISTP, Up: PREDICATES arrayp ------ ARRAYP thing ARRAY? thing outputs TRUE if the input is an array, FALSE otherwise.  File: ucblogo.info, Node: EMPTYP, Next: EQUALP, Prev: ARRAYP, Up: PREDICATES emptyp ------ EMPTYP thing EMPTY? thing outputs TRUE if the input is the empty word or the empty list, FALSE otherwise.  File: ucblogo.info, Node: EQUALP, Next: NOTEQUALP, Prev: EMPTYP, Up: PREDICATES equalp ------ EQUALP thing1 thing2 EQUAL? thing1 thing2 thing1 = thing2 outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named CASEIGNOREDP whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.) *Note CASEIGNOREDP:: , *Note SETITEM::  File: ucblogo.info, Node: NOTEQUALP, Next: BEFOREP, Prev: EQUALP, Up: PREDICATES notequalp --------- NOTEQUALP thing1 thing2 NOTEQUAL? thing1 thing2 thing1 <> thing2 outputs FALSE if the inputs are equal, TRUE otherwise. See EQUALP for the meaning of equality for different data types.  File: ucblogo.info, Node: BEFOREP, Next: dEQ, Prev: NOTEQUALP, Up: PREDICATES beforep ------- BEFOREP word1 word2 BEFORE? word1 word2 outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, BEFOREP 3 12 is false because 3 collates after 1. *Note CASEIGNOREDP:: , *Note LESSP::  File: ucblogo.info, Node: dEQ, Next: MEMBERP, Prev: BEFOREP, Up: PREDICATES .eq --- .EQ thing1 thing2 outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of mutators can lead to circular data structures, infinite loops, or Logo crashes.  File: ucblogo.info, Node: MEMBERP, Next: SUBSTRINGP, Prev: dEQ, Up: PREDICATES memberp ------- MEMBERP thing1 thing2 MEMBER? thing1 thing2 if `thing2' is a list or an array, outputs TRUE if `thing1' is EQUALP to a member of `thing2', FALSE otherwise. If `thing2' is a word, outputs TRUE if `thing1' is a one-character word EQUALP to a character of `thing2', FALSE otherwise. *Note EQUALP:: .  File: ucblogo.info, Node: SUBSTRINGP, Next: NUMBERP, Prev: MEMBERP, Up: PREDICATES substringp ---------- SUBSTRINGP thing1 thing2 SUBSTRING? thing1 thing2 if `thing1' or `thing2' is a list or an array, outputs FALSE. If `thing2' is a word, outputs TRUE if `thing1' is EQUALP to a substring of `thing2', FALSE otherwise. *Note EQUALP:: .  File: ucblogo.info, Node: NUMBERP, Next: BACKSLASHEDP, Prev: SUBSTRINGP, Up: PREDICATES numberp ------- NUMBERP thing NUMBER? thing outputs TRUE if the input is a number, FALSE otherwise.  File: ucblogo.info, Node: BACKSLASHEDP, Prev: NUMBERP, Up: PREDICATES backslashedp ------------ BACKSLASHEDP char BACKSLASHED? char outputs TRUE if the input character was originally entered into Logo with a backslash (\) before it or within vertical bars (|) to prevent its usual special syntactic meaning, FALSE otherwise. (Outputs TRUE only if the character is a backslashed space, tab, newline, or one of ()[]+-*/=<>":;\~?| )  File: ucblogo.info, Node: QUERIES, Prev: PREDICATES, Up: DATA STRUCTURE PRIMITIVES Queries ======= * Menu: * COUNT:: * ASCII:: * RAWASCII:: * CHAR:: * MEMBER:: * LOWERCASE:: * UPPERCASE:: * STANDOUT:: * PARSE:: * RUNPARSE::  File: ucblogo.info, Node: COUNT, Next: ASCII, Prev: QUERIES, Up: QUERIES count ----- COUNT thing outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.)  File: ucblogo.info, Node: ASCII, Next: RAWASCII, Prev: COUNT, Up: QUERIES ascii ----- ASCII char outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing backslashed punctuation, and returns the character code for the corresponding punctuation character without backslash. (Compare RAWASCII.)  File: ucblogo.info, Node: RAWASCII, Next: CHAR, Prev: ASCII, Up: QUERIES rawascii -------- RAWASCII char outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing themselves. To find out the ASCII code of an arbitrary keystroke, use RAWASCII RC.  File: ucblogo.info, Node: CHAR, Next: MEMBER, Prev: RAWASCII, Up: QUERIES char ---- CHAR int outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255. *Note ASCII:: .  File: ucblogo.info, Node: MEMBER, Next: LOWERCASE, Prev: CHAR, Up: QUERIES member ------ MEMBER thing1 thing2 if `thing2' is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of `thing2' from the first instance of `thing1' to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of `thing2'. It is an error for `thing2' to be an array. *Note MEMBERP:: .  File: ucblogo.info, Node: LOWERCASE, Next: UPPERCASE, Prev: MEMBER, Up: QUERIES lowercase --------- LOWERCASE word outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter.  File: ucblogo.info, Node: UPPERCASE, Next: STANDOUT, Prev: LOWERCASE, Up: QUERIES uppercase --------- UPPERCASE word outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter.  File: ucblogo.info, Node: STANDOUT, Next: PARSE, Prev: UPPERCASE, Up: QUERIES standout -------- STANDOUT thing outputs a word that, when printed, will appear like the input but displayed in standout mode (boldface, reverse video, or whatever your terminal does for standout). The word contains terminal-specific magic characters at the beginning and end; in between is the printed form (as if displayed using TYPE) of the input. The output is always a word, even if the input is of some other type, but it may include spaces and other formatting characters. Note: a word output by STANDOUT while Logo is running on one terminal will probably not have the desired effect if printed on another type of terminal. On the Macintosh, the way that standout works is incompatible with the use of characters whose ASCII code is greater than 127. Therefore, you have a choice to make: The instruction CANINVERSE 0 disables standout, but enables the display of ASCII codes above 127, and the instruction CANINVERSE 1 restores the default situation in which standout is enabled and the extra graphic characters cannot be printed.  File: ucblogo.info, Node: PARSE, Next: RUNPARSE, Prev: STANDOUT, Up: QUERIES parse ----- PARSE word outputs the list that would result if the input word were entered in response to a READLIST operation. That is, PARSE READWORD has the same value as READLIST for the same characters read. *Note READLIST:: , *Note READWORD::  File: ucblogo.info, Node: RUNPARSE, Prev: PARSE, Up: QUERIES runparse -------- RUNPARSE wordorlist outputs the list that would result if the input word or list were entered as an instruction line; characters such as infix operators and parentheses are separate members of the output. Note that sublists of a runparsed list are not themselves runparsed.  File: ucblogo.info, Node: COMMUNICATION, Next: ARITHMETIC, Prev: DATA STRUCTURE PRIMITIVES, Up: Top Communication ************* * Menu: * TRANSMITTERS:: * RECEIVERS:: * FILE ACCESS:: * TERMINAL ACCESS::  File: ucblogo.info, Node: TRANSMITTERS, Next: RECEIVERS, Prev: COMMUNICATION, Up: COMMUNICATION Transmitters ============ * Menu: * PRINT:: * TYPE:: * SHOW:: Note: If there is a variable named PRINTDEPTHLIMIT with a nonnegative integer value, then complex list and array structures will be printed only to the allowed depth. That is, members of members of... of members will be allowed only so far. The members omitted because they are just past the depth limit are indicated by an ellipsis for each one, so a too-deep list of two members will print as [... ...]. If there is a variable named PRINTWIDTHLIMIT with a nonnegative integer value, then only the first so many members of any array or list will be printed. A single ellipsis replaces all missing data within the structure. The width limit also applies to the number of characters printed in a word, except that a PRINTWIDTHLIMIT between 0 and 9 will be treated as if it were 10 when applied to words. This limit applies not only to the top-level printed datum but to any substructures within it. *Note PRINTDEPTHLIMIT:: , *Note PRINTWIDTHLIMIT:: If there is a variable named FULLPRINTP whose value is TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.) *Note FULLPRINTP:: .  File: ucblogo.info, Node: PRINT, Next: TYPE, Prev: TRANSMITTERS, Up: TRANSMITTERS print ----- PRINT thing PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...) command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays.  File: ucblogo.info, Node: TYPE, Next: SHOW, Prev: PRINT, Up: TRANSMITTERS type ---- TYPE thing (TYPE thing1 thing2 ...) command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces. Note: printing to the terminal is ordinarily "line buffered"; that is, the characters you print using TYPE will not actually appear on the screen until either a newline character is printed (for example, by PRINT or SHOW) or Logo tries to read from the keyboard (either at the request of your program or after an instruction prompt). This buffering makes the program much faster than it would be if each character appeared immediately, and in most cases the effect is not disconcerting. To accommodate programs that do a lot of positioned text display using TYPE, Logo will force printing whenever SETCURSOR is invoked. This solves most buffering problems. Still, on occasion you may find it necessary to force the buffered characters to be printed explicitly; this can be done using the WAIT command. WAIT 0 will force printing without actually waiting. *Note SETCURSOR:: , *Note WAIT::  File: ucblogo.info, Node: SHOW, Prev: TYPE, Up: TRANSMITTERS show ---- SHOW thing (SHOW thing1 thing2 ...) command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets. *Note PRINT:: .  File: ucblogo.info, Node: RECEIVERS, Next: FILE ACCESS, Prev: TRANSMITTERS, Up: COMMUNICATION Receivers ========= * Menu: * READLIST:: * READWORD:: * READRAWLINE:: * READCHAR:: * READCHARS:: * SHELL::  File: ucblogo.info, Node: READLIST, Next: READWORD, Prev: RECEIVERS, Up: RECEIVERS readlist -------- READLIST RL reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character.  File: ucblogo.info, Node: READWORD, Next: READRAWLINE, Prev: READLIST, Up: RECEIVERS readword -------- READWORD RW reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READWORD outputs the empty list (not the empty word). READWORD processes backslash, vertical bar, and tilde characters in the read stream. In the case of a tilde used for line continuation, the output word DOES include the tilde and the newline characters, so that the user program can tell exactly what the user entered. Vertical bars in the line are also preserved in the output. Backslash characters are not preserved in the output, but the character following the backslash has 128 added to its representation. Programs can use BACKSLASHEDP to check for this code. (Backslashedness is preserved only for certain characters.) *Note BACKSLASHEDP:: .  File: ucblogo.info, Node: READRAWLINE, Next: READCHAR, Prev: READWORD, Up: RECEIVERS readrawline ----------- READRAWLINE reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters. *Note READWORD:: .  File: ucblogo.info, Node: READCHAR, Next: READCHARS, Prev: READRAWLINE, Up: RECEIVERS readchar -------- READCHAR RC reads a single character from the read stream and outputs that character as a word. If the read stream is a file, and the end of file is reached, READCHAR outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHAR is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. *Note READLIST:: .  File: ucblogo.info, Node: READCHARS, Next: SHELL, Prev: READCHAR, Up: RECEIVERS readchars --------- READCHARS num RCS num reads `num' characters from the read stream and outputs those characters as a word. If the read stream is a file, and the end of file is reached, READCHARS outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHARS is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. *Note READLIST:: , *Note READWORD:: ucblogo-5.5/docs/ucblogo.info-20100644000161300001330000014150610276035443014341 0ustar bhdoeThis is ucblogo.info, produced by makeinfo version 4.5 from usermanual.texi.  File: ucblogo.info, Node: SHELL, Prev: READCHARS, Up: RECEIVERS shell ----- SHELL command (SHELL command wordflag) Under Unix, outputs the result of running `command' as a shell command. (The command is sent to `/bin/sh', not `csh' or other alternatives.) If the command is a literal list in the instruction line, and if you want a backslash character sent to the shell, you must use \\ to get the backslash through Logo's reader intact. The output is a list containing one member for each line generated by the shell command. Ordinarily each such line is represented by a list in the output, as though the line were read using READLIST. If a second input is given, regardless of the value of the input, each line is represented by a word in the output as though it were read with READWORD. Example: to dayofweek output first first shell [date] end This is "first first" to extract the first word of the first (and only) line of the shell output. Under DOS, SHELL is a command, not an operation; it sends its input to a DOS command processor but does not collect the result of the command. The Macintosh, of course, is not programmable (unless you are running the Unix version of UCBLogo under OS X).  File: ucblogo.info, Node: FILE ACCESS, Next: TERMINAL ACCESS, Prev: RECEIVERS, Up: COMMUNICATION File Access =========== * Menu: * SETPREFIX:: * PREFIX:: * OPENREAD:: * OPENWRITE:: * OPENAPPEND:: * OPENUPDATE:: * CLOSE:: * ALLOPEN:: * CLOSEALL:: * ERASEFILE:: * DRIBBLE:: * NODRIBBLE:: * SETREAD:: * SETWRITE:: * READER:: * WRITER:: * SETREADPOS:: * SETWRITEPOS:: * READPOS:: * WRITEPOS:: * EOFP:: * FILEP::  File: ucblogo.info, Node: SETPREFIX, Next: PREFIX, Prev: FILE ACCESS, Up: FILE ACCESS setprefix --------- SETPREFIX string command. Sets a prefix that will be used as the implicit beginning of filenames in OPENREAD, OPENWRITE, OPENAPPEND, OPENUPDATE, LOAD, and SAVE commands. Logo will put the appropriate separator character (slash for Unix, backslash for DOS/Windows, colon for MacOS) between the prefix and the filename entered by the user. The input to SETPREFIX must be a word, unless it is the empty list, to indicate that there should be no prefix. *Note OPENREAD:: , *Note OPENWRITE:: , *Note OPENAPPEND:: , *Note OPENUPDATE:: , *Note LOAD:: , *Note SAVE:: .  File: ucblogo.info, Node: PREFIX, Next: OPENREAD, Prev: SETPREFIX, Up: FILE ACCESS prefix ------ PREFIX outputs the current file prefix, or [] if there is no prefix. *Note SETPREFIX:: .  File: ucblogo.info, Node: OPENREAD, Next: OPENWRITE, Prev: PREFIX, Up: FILE ACCESS openread -------- OPENREAD filename command. Opens the named file for reading. The read position is initially at the beginning of the file.  File: ucblogo.info, Node: OPENWRITE, Next: OPENAPPEND, Prev: OPENREAD, Up: FILE ACCESS openwrite --------- OPENWRITE filename command. Opens the named file for writing. If the file already existed, the old version is deleted and a new, empty file created. OPENWRITE, but not the other OPEN variants, will accept as input a two-element list, in which the first element must be a variable name, and the second must be a positive integer. A character buffer of the specified size will be created. When a SETWRITE is done with this same list (in the sense of .EQ, not a copy, so you must do something like ? make "buf [foo 100] ? openwrite :buf ? setwrite :buf [...] ? close :buf and not just ? openwrite [foo 100] ? setwrite [foo 100] and so on), the printed characters are stored in the buffer; when a CLOSE is done with the same list as input, the characters from the buffer (treated as one long word, even if spaces and newlines are included) become the value of the specified variable.  File: ucblogo.info, Node: OPENAPPEND, Next: OPENUPDATE, Prev: OPENWRITE, Up: FILE ACCESS openappend ---------- OPENAPPEND filename command. Opens the named file for writing. If the file already exists, the write position is initially set to the end of the old file, so that newly written data will be appended to it.  File: ucblogo.info, Node: OPENUPDATE, Next: CLOSE, Prev: OPENAPPEND, Up: FILE ACCESS openupdate ---------- OPENUPDATE filename command. Opens the named file for reading and writing. The read and write position is initially set to the end of the old file, if any. Note: each open file has only one position, for both reading and writing. If a file opened for update is both READER and WRITER at the same time, then SETREADPOS will also affect WRITEPOS and vice versa. Also, if you alternate reading and writing the same file, you must SETREADPOS between a write and a read, and SETWRITEPOS between a read and a write. *Note READER:: , *Note WRITER:: , *Note SETREADPOS:: , *Note SETWRITEPOS::  File: ucblogo.info, Node: CLOSE, Next: ALLOPEN, Prev: OPENUPDATE, Up: FILE ACCESS close ----- CLOSE filename command. Closes the named file. If the file was currently the reader or writer, then the reader or writer is changed to the keyboard or screen, as if SETREAD [] or SETWRITE [] had been done.  File: ucblogo.info, Node: ALLOPEN, Next: CLOSEALL, Prev: CLOSE, Up: FILE ACCESS allopen ------- ALLOPEN outputs a list whose members are the names of all files currently open. This list does not include the dribble file, if any.  File: ucblogo.info, Node: CLOSEALL, Next: ERASEFILE, Prev: ALLOPEN, Up: FILE ACCESS closeall -------- CLOSEALL (library procedure) command. Closes all open files. Abbreviates FOREACH ALLOPEN [CLOSE ?] *Note FOREACH:: , *Note CLOSE::  File: ucblogo.info, Node: ERASEFILE, Next: DRIBBLE, Prev: CLOSEALL, Up: FILE ACCESS erasefile --------- ERASEFILE filename ERF filename command. Erases (deletes, removes) the named file, which should not currently be open.  File: ucblogo.info, Node: DRIBBLE, Next: NODRIBBLE, Prev: ERASEFILE, Up: FILE ACCESS dribble ------- DRIBBLE filename command. Creates a new file whose name is the input, like OPENWRITE, and begins recording in that file everything that is read from the keyboard or written to the terminal. That is, this writing is in addition to the writing to WRITER. The intent is to create a transcript of a Logo session, including things like prompt characters and interactions. *Note OPENWRITE:: , *Note WRITER::  File: ucblogo.info, Node: NODRIBBLE, Next: SETREAD, Prev: DRIBBLE, Up: FILE ACCESS nodribble --------- NODRIBBLE command. Stops copying information into the dribble file, and closes the file.  File: ucblogo.info, Node: SETREAD, Next: SETWRITE, Prev: NODRIBBLE, Up: FILE ACCESS setread ------- SETREAD filename command. Makes the named file the read stream, used for READLIST, etc. The file must already be open with OPENREAD or OPENUPDATE. If the input is the empty list, then the read stream becomes the terminal, as usual. Changing the read stream does not close the file that was previously the read stream, so it is possible to alternate between files. *Note READLIST:: , *Note OPENREAD:: , *Note OPENUPDATE::  File: ucblogo.info, Node: SETWRITE, Next: READER, Prev: SETREAD, Up: FILE ACCESS setwrite -------- SETWRITE filename command. Makes the named file the write stream, used for PRINT, etc. The file must already be open with OPENWRITE, OPENAPPEND, or OPENUPDATE. If the input is the empty list, then the write stream becomes the terminal, as usual. Changing the write stream does not close the file that was previously the write stream, so it is possible to alternate between files. If the input is a list, then its first element must be a variable name, and its second and last element must be a positive integer; a buffer of that many characters will be allocated, and will become the writestream. If the same list (same in the .EQ sense, not a copy) has been used as input to OPENWRITE, then the already-allocated buffer will be used, and the writer can be changed to and from this buffer, with all the characters accumulated as in a file. When the same list is used as input to CLOSE, the contents of the buffer (as an unparsed word, which may contain newline characters) will become the value of the named variable. For compatibility with earlier versions, if the list has not been opened when the SETWRITE is done, it will be opened implicitly, but the first SETWRITE after this one will implicitly close it, setting the variable and freeing the allocated buffer. *Note PRINT:: , *Note OPENWRITE:: ; *Note OPENAPPEND:: ; *Note OPENUPDATE::  File: ucblogo.info, Node: READER, Next: WRITER, Prev: SETWRITE, Up: FILE ACCESS reader ------ READER outputs the name of the current read stream file, or the empty list if the read stream is the terminal.  File: ucblogo.info, Node: WRITER, Next: SETREADPOS, Prev: READER, Up: FILE ACCESS writer ------ WRITER outputs the name of the current write stream file, or the empty list if the write stream is the terminal.  File: ucblogo.info, Node: SETREADPOS, Next: SETWRITEPOS, Prev: WRITER, Up: FILE ACCESS setreadpos ---------- SETREADPOS charpos command. Sets the file pointer of the read stream file so that the next READLIST, etc., will begin reading at the `charpos'th character in the file, counting from 0. (That is, SETREADPOS 0 will start reading from the beginning of the file.) Meaningless if the read stream is the terminal. *Note READLIST:: .  File: ucblogo.info, Node: SETWRITEPOS, Next: READPOS, Prev: SETREADPOS, Up: FILE ACCESS setwritepos ----------- SETWRITEPOS charpos command. Sets the file pointer of the write stream file so that the next PRINT, etc., will begin writing at the `charpos'th character in the file, counting from 0. (That is, SETWRITEPOS 0 will start writing from the beginning of the file.) Meaningless if the write stream is the terminal. *Note PRINT:: .  File: ucblogo.info, Node: READPOS, Next: WRITEPOS, Prev: SETWRITEPOS, Up: FILE ACCESS readpos ------- READPOS outputs the file position of the current read stream file.  File: ucblogo.info, Node: WRITEPOS, Next: EOFP, Prev: READPOS, Up: FILE ACCESS writepos -------- WRITEPOS outputs the file position of the current write stream file.  File: ucblogo.info, Node: EOFP, Next: FILEP, Prev: WRITEPOS, Up: FILE ACCESS eofp ---- EOFP EOF? predicate, outputs TRUE if there are no more characters to be read in the read stream file, FALSE otherwise.  File: ucblogo.info, Node: FILEP, Prev: EOFP, Up: FILE ACCESS filep ----- FILEP filename FILE? filename (library procedure) predicate, outputs TRUE if a file of the specified name exists and can be read, FALSE otherwise.  File: ucblogo.info, Node: TERMINAL ACCESS, Prev: FILE ACCESS, Up: COMMUNICATION Terminal Access =============== * Menu: * KEYP:: * CLEARTEXT:: * SETCURSOR:: * CURSOR:: * SETMARGINS:: * SETTEXTCOLOR::  File: ucblogo.info, Node: KEYP, Next: CLEARTEXT, Prev: TERMINAL ACCESS, Up: TERMINAL ACCESS keyp ---- KEYP KEY? predicate, outputs TRUE if there are characters waiting to be read from the read stream. If the read stream is a file, this is equivalent to NOT EOFP. If the read stream is the terminal, then echoing is turned off and the terminal is set to CBREAK (character at a time instead of line at a time) mode. It remains in this mode until some line-mode reading is requested (e.g., READLIST). The Unix operating system forgets about any pending characters when it switches modes, so the first KEYP invocation will always output FALSE. *Note EOFP:: , *Note READLIST::  File: ucblogo.info, Node: CLEARTEXT, Next: SETCURSOR, Prev: KEYP, Up: TERMINAL ACCESS cleartext --------- CLEARTEXT CT command. Clears the text screen of the terminal.  File: ucblogo.info, Node: SETCURSOR, Next: CURSOR, Prev: CLEARTEXT, Up: TERMINAL ACCESS setcursor --------- SETCURSOR vector command. The input is a list of two numbers, the x and y coordinates of a screen position (origin in the upper left corner, positive direction is southeast). The screen cursor is moved to the requested position. This command also forces the immediate printing of any buffered characters.  File: ucblogo.info, Node: CURSOR, Next: SETMARGINS, Prev: SETCURSOR, Up: TERMINAL ACCESS cursor ------ CURSOR outputs a list containing the current x and y coordinates of the screen cursor. Logo may get confused about the current cursor position if, e.g., you type in a long line that wraps around or your program prints escape codes that affect the terminal strangely.  File: ucblogo.info, Node: SETMARGINS, Next: SETTEXTCOLOR, Prev: CURSOR, Up: TERMINAL ACCESS setmargins ---------- SETMARGINS vector command. The input must be a list of two numbers, as for SETCURSOR. The effect is to clear the screen and then arrange for all further printing to be shifted down and to the right according to the indicated margins. Specifically, every time a newline character is printed (explicitly or implicitly) Logo will type x_margin spaces, and on every invocation of SETCURSOR the margins will be added to the input x and y coordinates. (CURSOR will report the cursor position relative to the margins, so that this shift will be invisible to Logo programs.) The purpose of this command is to accommodate the display of terminal screens in lecture halls with inadequate TV monitors that miss the top and left edges of the screen. *Note SETCURSOR:: .  File: ucblogo.info, Node: SETTEXTCOLOR, Prev: SETMARGINS, Up: TERMINAL ACCESS settextcolor ------------ SETTEXTCOLOR foreground background SETTC foreground background Command (Windows and DOS extended only). The inputs are color numbers, as for turtle graphics. Future printing to the text window will use the specified colors for foreground (the characters printed) and background (the space under those characters). Using STANDOUT will revert to the default text window colors. In the DOS extended (ucblogo.exe) version, colors in textscreen mode are limited to numbers 0-7, and the coloring applies only to text printed by the program, not to the echoing of text typed by the user. Neither limitation applies to the text portion of splitscreen mode, which is actually drawn as graphics internally. *Note STANDOUT:: .  File: ucblogo.info, Node: ARITHMETIC, Next: LOGICAL OPERATIONS, Prev: COMMUNICATION, Up: Top Arithmetic ********** * Menu: * NUMERIC OPERATIONS:: * NUMERIC PREDICATES:: * RANDOM NUMBERS:: * PRINT FORMATTING:: * BITWISE OPERATIONS::  File: ucblogo.info, Node: NUMERIC OPERATIONS, Next: NUMERIC PREDICATES, Prev: ARITHMETIC, Up: ARITHMETIC Numeric Operations ================== * Menu: * SUM:: * DIFFERENCE:: * MINUS:: * PRODUCT:: * QUOTIENT:: * REMAINDER:: * MODULO:: * INT:: * ROUND:: * SQRT:: * POWER:: * EXP:: * LOG10:: * LN:: * SIN:: * RADSIN:: * COS:: * RADCOS:: * ARCTAN:: * RADARCTAN:: * ISEQ:: * RSEQ::  File: ucblogo.info, Node: SUM, Next: DIFFERENCE, Prev: NUMERIC OPERATIONS, Up: NUMERIC OPERATIONS sum --- SUM num1 num2 (SUM num1 num2 num3 ...) num1 + num2 outputs the sum of its inputs.  File: ucblogo.info, Node: DIFFERENCE, Next: MINUS, Prev: SUM, Up: NUMERIC OPERATIONS difference ---------- DIFFERENCE num1 num2 num1 - num2 outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.)  File: ucblogo.info, Node: MINUS, Next: PRODUCT, Prev: DIFFERENCE, Up: NUMERIC OPERATIONS minus ----- MINUS num - num outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms: MINUS 3 + 4 means -(3+4) - 3 + 4 means (-3)+4  File: ucblogo.info, Node: PRODUCT, Next: QUOTIENT, Prev: MINUS, Up: NUMERIC OPERATIONS product ------- PRODUCT num1 num2 (PRODUCT num1 num2 num3 ...) num1 * num2 outputs the product of its inputs.  File: ucblogo.info, Node: QUOTIENT, Next: REMAINDER, Prev: PRODUCT, Up: NUMERIC OPERATIONS quotient -------- QUOTIENT num1 num2 (QUOTIENT num) num1 / num2 outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is 2, not 2.0 -- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input.  File: ucblogo.info, Node: REMAINDER, Next: MODULO, Prev: QUOTIENT, Up: NUMERIC OPERATIONS remainder --------- REMAINDER num1 num2 outputs the remainder on dividing `num1' by `num2'; both must be integers and the result is an integer with the same sign as num1.  File: ucblogo.info, Node: MODULO, Next: INT, Prev: REMAINDER, Up: NUMERIC OPERATIONS modulo ------ MODULO num1 num2 outputs the remainder on dividing `num1' by `num2'; both must be integers and the result is an integer with the same sign as num2.  File: ucblogo.info, Node: INT, Next: ROUND, Prev: MODULO, Up: NUMERIC OPERATIONS int --- INT num outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input.  File: ucblogo.info, Node: ROUND, Next: SQRT, Prev: INT, Up: NUMERIC OPERATIONS round ----- ROUND num outputs the nearest integer to the input.  File: ucblogo.info, Node: SQRT, Next: POWER, Prev: ROUND, Up: NUMERIC OPERATIONS sqrt ---- SQRT num outputs the square root of the input, which must be nonnegative.  File: ucblogo.info, Node: POWER, Next: EXP, Prev: SQRT, Up: NUMERIC OPERATIONS power ----- POWER num1 num2 outputs `num1' to the `num2' power. If num1 is negative, then num2 must be an integer.  File: ucblogo.info, Node: EXP, Next: LOG10, Prev: POWER, Up: NUMERIC OPERATIONS exp --- EXP num outputs e (2.718281828+) to the input power.  File: ucblogo.info, Node: LOG10, Next: LN, Prev: EXP, Up: NUMERIC OPERATIONS log10 ----- LOG10 num outputs the common logarithm of the input.  File: ucblogo.info, Node: LN, Next: SIN, Prev: LOG10, Up: NUMERIC OPERATIONS ln -- LN num outputs the natural logarithm of the input.  File: ucblogo.info, Node: SIN, Next: RADSIN, Prev: LN, Up: NUMERIC OPERATIONS sin --- SIN degrees outputs the sine of its input, which is taken in degrees.  File: ucblogo.info, Node: RADSIN, Next: COS, Prev: SIN, Up: NUMERIC OPERATIONS radsin ------ RADSIN radians outputs the sine of its input, which is taken in radians.  File: ucblogo.info, Node: COS, Next: RADCOS, Prev: RADSIN, Up: NUMERIC OPERATIONS cos --- COS degrees outputs the cosine of its input, which is taken in degrees.  File: ucblogo.info, Node: RADCOS, Next: ARCTAN, Prev: COS, Up: NUMERIC OPERATIONS radcos ------ RADCOS radians outputs the cosine of its input, which is taken in radians.  File: ucblogo.info, Node: ARCTAN, Next: RADARCTAN, Prev: RADCOS, Up: NUMERIC OPERATIONS arctan ------ ARCTAN num (ARCTAN x y) outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or -90 depending on the sign of y, if x is zero.  File: ucblogo.info, Node: RADARCTAN, Next: ISEQ, Prev: ARCTAN, Up: NUMERIC OPERATIONS radarctan --------- RADARCTAN num (RADARCTAN x y) outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or -pi/2 depending on the sign of y, if x is zero. The expression 2*(RADARCTAN 0 1) can be used to get the value of pi.  File: ucblogo.info, Node: ISEQ, Next: RSEQ, Prev: RADARCTAN, Up: NUMERIC OPERATIONS iseq ---- ISEQ from to (library procedure) outputs a list of the integers from FROM to TO, inclusive. ? show iseq 3 7 [3 4 5 6 7] ? show iseq 7 3 [7 6 5 4 3]  File: ucblogo.info, Node: RSEQ, Prev: ISEQ, Up: NUMERIC OPERATIONS rseq ---- RSEQ from to count (library procedure) outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive. ? show rseq 3 5 9 [3 3.25 3.5 3.75 4 4.25 4.5 4.75 5] ? show rseq 3 5 5 [3 3.5 4 4.5 5]  File: ucblogo.info, Node: NUMERIC PREDICATES, Next: RANDOM NUMBERS, Prev: NUMERIC OPERATIONS, Up: ARITHMETIC Numeric Predicates ================== * Menu: * LESSP:: * GREATERP:: * LESSEQUALP:: * GREATEREQUALP::  File: ucblogo.info, Node: LESSP, Next: GREATERP, Prev: NUMERIC PREDICATES, Up: NUMERIC PREDICATES lessp ----- LESSP num1 num2 LESS? num1 num2 num1 < num2 outputs TRUE if its first input is strictly less than its second.  File: ucblogo.info, Node: GREATERP, Next: LESSEQUALP, Prev: LESSP, Up: NUMERIC PREDICATES greaterp -------- GREATERP num1 num2 GREATER? num1 num2 num1 > num2 outputs TRUE if its first input is strictly greater than its second.  File: ucblogo.info, Node: LESSEQUALP, Next: GREATEREQUALP, Prev: GREATERP, Up: NUMERIC PREDICATES lessequalp ---------- LESSEQUALP num1 num2 LESSEQUAL? num1 num2 num1 <= num2 outputs TRUE if its first input is less than or equal to its second.  File: ucblogo.info, Node: GREATEREQUALP, Prev: LESSEQUALP, Up: NUMERIC PREDICATES greaterequalp ------------- GREATEREQUALP num1 num2 GREATEREQUAL? num1 num2 num1 >= num2 outputs TRUE if its first input is greater than or equal to its second.  File: ucblogo.info, Node: RANDOM NUMBERS, Next: PRINT FORMATTING, Prev: NUMERIC PREDICATES, Up: ARITHMETIC Random Numbers ============== * Menu: * RANDOM:: * RERANDOM::  File: ucblogo.info, Node: RANDOM, Next: RERANDOM, Prev: RANDOM NUMBERS, Up: RANDOM NUMBERS random ------ RANDOM num (RANDOM start end) with one input, outputs a random nonnegative integer less than its input, which must be a positive integer. With two inputs, RANDOM outputs a random integer greater than or equal to the first input, and less than or equal to the second input. Both inputs must be integers, and the first must be less than the second. (RANDOM 0 9) is equivalent to RANDOM 10; (RANDOM 3 8) is equivalent to (RANDOM 6)+3.  File: ucblogo.info, Node: RERANDOM, Prev: RANDOM, Up: RANDOM NUMBERS rerandom -------- RERANDOM (RERANDOM seed) command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers.  File: ucblogo.info, Node: PRINT FORMATTING, Next: BITWISE OPERATIONS, Prev: RANDOM NUMBERS, Up: ARITHMETIC Print Formatting ================ * Menu: * FORM::  File: ucblogo.info, Node: FORM, Prev: PRINT FORMATTING, Up: PRINT FORMATTING form ---- FORM num width precision outputs a word containing a printable representation of `num', possibly preceded by spaces (and therefore not a number for purposes of performing arithmetic operations), with at least `width' characters, including exactly `precision' digits after the decimal point. (If `precision' is 0 then there will be no decimal point in the output.) As a debugging feature, (FORM num -1 format) will print the floating point `num' according to the C printf `format', to allow to hex :num op form :num -1 "|%08X %08X| end to allow finding out the exact result of floating point operations. The precise format needed may be machine-dependent.  File: ucblogo.info, Node: BITWISE OPERATIONS, Prev: PRINT FORMATTING, Up: ARITHMETIC Bitwise Operations ================== * Menu: * BITAND:: * BITOR:: * BITXOR:: * BITNOT:: * ASHIFT:: * LSHIFT::  File: ucblogo.info, Node: BITAND, Next: BITOR, Prev: BITWISE OPERATIONS, Up: BITWISE OPERATIONS bitand ------ BITAND num1 num2 (BITAND num1 num2 num3 ...) outputs the bitwise AND of its inputs, which must be integers. *Note AND:: .  File: ucblogo.info, Node: BITOR, Next: BITXOR, Prev: BITAND, Up: BITWISE OPERATIONS bitor ----- BITOR num1 num2 (BITOR num1 num2 num3 ...) outputs the bitwise OR of its inputs, which must be integers. *Note OR:: .  File: ucblogo.info, Node: BITXOR, Next: BITNOT, Prev: BITOR, Up: BITWISE OPERATIONS bitxor ------ BITXOR num1 num2 (BITXOR num1 num2 num3 ...) outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers. *Note OR:: .  File: ucblogo.info, Node: BITNOT, Next: ASHIFT, Prev: BITXOR, Up: BITWISE OPERATIONS bitnot ------ BITNOT num outputs the bitwise NOT of its input, which must be an integer. *Note NOT:: .  File: ucblogo.info, Node: ASHIFT, Next: LSHIFT, Prev: BITNOT, Up: BITWISE OPERATIONS ashift ------ ASHIFT num1 num2 outputs `num1' arithmetic-shifted to the left by `num2' bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers.  File: ucblogo.info, Node: LSHIFT, Prev: ASHIFT, Up: BITWISE OPERATIONS lshift ------ LSHIFT num1 num2 outputs `num1' logical-shifted to the left by `num2' bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers.  File: ucblogo.info, Node: LOGICAL OPERATIONS, Next: GRAPHICS, Prev: ARITHMETIC, Up: Top Logical Operations ****************** * Menu: * AND:: * OR:: * NOT::  File: ucblogo.info, Node: AND, Next: OR, Prev: LOGICAL OPERATIONS, Up: LOGICAL OPERATIONS and --- AND tf1 tf2 (AND tf1 tf2 tf3 ...) outputs TRUE if all inputs are TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, `true' or `True' or `TRUE' are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example: MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5] to avoid the division by zero if the first part is false. *Note CASEIGNOREDP:: .  File: ucblogo.info, Node: OR, Next: NOT, Prev: AND, Up: LOGICAL OPERATIONS or -- OR tf1 tf2 (OR tf1 tf2 tf3 ...) outputs TRUE if any input is TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, `true' or `True' or `TRUE' are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example: IF OR :X=0 [some.long.computation] [...] to avoid the long computation if the first condition is met. *Note CASEIGNOREDP:: .  File: ucblogo.info, Node: NOT, Prev: OR, Up: LOGICAL OPERATIONS not --- NOT tf outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value.  File: ucblogo.info, Node: GRAPHICS, Next: WORKSPACE MANAGEMENT, Prev: LOGICAL OPERATIONS, Up: Top Graphics ******** Berkeley Logo provides traditional Logo turtle graphics with one turtle. Multiple turtles, dynamic turtles, and collision detection are not supported. This is the most hardware-dependent part of Logo; some features may exist on some machines but not others. Nevertheless, the goal has been to make Logo programs as portable as possible, rather than to take fullest advantage of the capabilities of each machine. In particular, Logo attempts to scale the screen so that turtle coordinates [-100 -100] and [100 100] fit on the graphics window, and so that the aspect ratio is 1:1. The center of the graphics window (which may or may not be the entire screen, depending on the machine used) is turtle location [0 0]. Positive X is to the right; positive Y is up. Headings (angles) are measured in degrees clockwise from the positive Y axis. (This differs from the common mathematical convention of measuring angles counterclockwise from the positive X axis.) The turtle is represented as an isoceles triangle; the actual turtle position is at the midpoint of the base (the short side). However, the turtle is drawn one step behind its actual position, so that the display of the base of the turtle's triangle does not obscure a line drawn perpendicular to it (as would happen after drawing a square). Colors are, of course, hardware-dependent. However, Logo provides partial hardware independence by interpreting color numbers 0 through 7 uniformly on all computers: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white Where possible, Logo provides additional user-settable colors; how many are available depends on the hardware and operating system environment. If at least 16 colors are available, Logo tries to provide uniform initial settings for the colors 8-15: 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey Logo begins with a black background and white pen. * Menu: * TURTLE MOTION:: * TURTLE MOTION QUERIES:: * TURTLE AND WINDOW CONTROL:: * TURTLE AND WINDOW QUERIES:: * PEN AND BACKGROUND CONTROL:: * PEN QUERIES:: * SAVING AND LOADING PICTURES:: * MOUSE QUERIES::  File: ucblogo.info, Node: TURTLE MOTION, Next: TURTLE MOTION QUERIES, Prev: GRAPHICS, Up: GRAPHICS Turtle Motion ============= * Menu: * FORWARD:: * BACK:: * LEFT:: * RIGHT:: * SETPOS:: * SETXY:: * SETX:: * SETY:: * SETHEADING:: * HOME:: * ARC::  File: ucblogo.info, Node: FORWARD, Next: BACK, Prev: TURTLE MOTION, Up: TURTLE MOTION forward ------- FORWARD dist FD dist moves the turtle forward, in the direction that it's facing, by the specified distance (measured in turtle steps).  File: ucblogo.info, Node: BACK, Next: LEFT, Prev: FORWARD, Up: TURTLE MOTION back ---- BACK dist BK dist moves the turtle backward, i.e., exactly opposite to the direction that it's facing, by the specified distance. (The heading of the turtle does not change.)  File: ucblogo.info, Node: LEFT, Next: RIGHT, Prev: BACK, Up: TURTLE MOTION left ---- LEFT degrees LT degrees turns the turtle counterclockwise by the specified angle, measured in degrees (1/360 of a circle).  File: ucblogo.info, Node: RIGHT, Next: SETPOS, Prev: LEFT, Up: TURTLE MOTION right ----- RIGHT degrees RT degrees turns the turtle clockwise by the specified angle, measured in degrees (1/360 of a circle).  File: ucblogo.info, Node: SETPOS, Next: SETXY, Prev: RIGHT, Up: TURTLE MOTION setpos ------ SETPOS pos moves the turtle to an absolute screen position. The input is a list of two numbers, the X and Y coordinates.  File: ucblogo.info, Node: SETXY, Next: SETX, Prev: SETPOS, Up: TURTLE MOTION setxy ----- SETXY xcor ycor moves the turtle to an absolute screen position. The two inputs are numbers, the X and Y coordinates.  File: ucblogo.info, Node: SETX, Next: SETY, Prev: SETXY, Up: TURTLE MOTION setx ---- SETX xcor moves the turtle horizontally from its old position to a new absolute horizontal coordinate. The input is the new X coordinate.  File: ucblogo.info, Node: SETY, Next: SETHEADING, Prev: SETX, Up: TURTLE MOTION sety ---- SETY ycor moves the turtle vertically from its old position to a new absolute vertical coordinate. The input is the new Y coordinate.  File: ucblogo.info, Node: SETHEADING, Next: HOME, Prev: SETY, Up: TURTLE MOTION setheading ---------- SETHEADING degrees SETH degrees turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive Y axis.  File: ucblogo.info, Node: HOME, Next: ARC, Prev: SETHEADING, Up: TURTLE MOTION home ---- HOME moves the turtle to the center of the screen. Equivalent to SETPOS [0 0] SETHEADING 0. *Note SETPOS:: , *Note SETHEADING:: .  File: ucblogo.info, Node: ARC, Prev: HOME, Up: TURTLE MOTION arc --- ARC angle radius draws an arc of a circle, with the turtle at the center, with the specified radius, starting at the turtle's heading and extending clockwise through the specified angle. The turtle does not move.  File: ucblogo.info, Node: TURTLE MOTION QUERIES, Next: TURTLE AND WINDOW CONTROL, Prev: TURTLE MOTION, Up: GRAPHICS Turtle Motion Queries ===================== * Menu: * POS:: * XCOR:: * YCOR:: * HEADING:: * TOWARDS:: * SCRUNCH::  File: ucblogo.info, Node: POS, Next: XCOR, Prev: TURTLE MOTION QUERIES, Up: TURTLE MOTION QUERIES pos --- POS outputs the turtle's current position, as a list of two numbers, the X and Y coordinates.  File: ucblogo.info, Node: XCOR, Next: YCOR, Prev: POS, Up: TURTLE MOTION QUERIES xcor ---- XCOR (library procedure) outputs a number, the turtle's X coordinate.  File: ucblogo.info, Node: YCOR, Next: HEADING, Prev: XCOR, Up: TURTLE MOTION QUERIES ycor ---- YCOR (library procedure) outputs a number, the turtle's Y coordinate.  File: ucblogo.info, Node: HEADING, Next: TOWARDS, Prev: YCOR, Up: TURTLE MOTION QUERIES heading ------- HEADING outputs a number, the turtle's heading in degrees.  File: ucblogo.info, Node: TOWARDS, Next: SCRUNCH, Prev: HEADING, Up: TURTLE MOTION QUERIES towards ------- TOWARDS pos outputs a number, the heading at which the turtle should be facing so that it would point from its current position to the position given as the input.  File: ucblogo.info, Node: SCRUNCH, Prev: TOWARDS, Up: TURTLE MOTION QUERIES scrunch ------- SCRUNCH outputs a list containing two numbers, the X and Y scrunch factors, as used by SETSCRUNCH. (But note that SETSCRUNCH takes two numbers as inputs, not one list of numbers.) *Note SETSCRUNCH:: .  File: ucblogo.info, Node: TURTLE AND WINDOW CONTROL, Next: TURTLE AND WINDOW QUERIES, Prev: TURTLE MOTION QUERIES, Up: GRAPHICS Turtle and Window Control ========================= * Menu: * SHOWTURTLE:: * HIDETURTLE:: * CLEAN:: * CLEARSCREEN:: * WRAP:: * WINDOW:: * FENCE:: * FILL:: * LABEL:: * TEXTSCREEN:: * FULLSCREEN:: * SPLITSCREEN:: * SETSCRUNCH:: * REFRESH:: * NOREFRESH::  File: ucblogo.info, Node: SHOWTURTLE, Next: HIDETURTLE, Prev: TURTLE AND WINDOW CONTROL, Up: TURTLE AND WINDOW CONTROL showturtle ---------- SHOWTURTLE ST makes the turtle visible.  File: ucblogo.info, Node: HIDETURTLE, Next: CLEAN, Prev: SHOWTURTLE, Up: TURTLE AND WINDOW CONTROL hideturtle ---------- HIDETURTLE HT makes the turtle invisible. It's a good idea to do this while you're in the middle of a complicated drawing, because hiding the turtle speeds up the drawing substantially.  File: ucblogo.info, Node: CLEAN, Next: CLEARSCREEN, Prev: HIDETURTLE, Up: TURTLE AND WINDOW CONTROL clean ----- CLEAN erases all lines that the turtle has drawn on the graphics window. The turtle's state (position, heading, pen mode, etc.) is not changed.  File: ucblogo.info, Node: CLEARSCREEN, Next: WRAP, Prev: CLEAN, Up: TURTLE AND WINDOW CONTROL clearscreen ----------- CLEARSCREEN CS erases the graphics window and sends the turtle to its initial position and heading. Like HOME and CLEAN together. *Note HOME:: .  File: ucblogo.info, Node: WRAP, Next: WINDOW, Prev: CLEARSCREEN, Up: TURTLE AND WINDOW CONTROL wrap ---- WRAP tells the turtle to enter wrap mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will "wrap around" and reappear at the opposite edge of the window. The top edge wraps to the bottom edge, while the left edge wraps to the right edge. (So the window is topologically equivalent to a torus.) This is the turtle's initial mode. Compare WINDOW and FENCE. *Note FENCE:: .  File: ucblogo.info, Node: WINDOW, Next: FENCE, Prev: WRAP, Up: TURTLE AND WINDOW CONTROL window ------ WINDOW tells the turtle to enter window mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move offscreen. The visible graphics window is considered as just part of an infinite graphics plane; the turtle can be anywhere on the plane. (If you lose the turtle, HOME will bring it back to the center of the window.) Compare WRAP and FENCE. *Note HOME:: .  File: ucblogo.info, Node: FENCE, Next: FILL, Prev: WINDOW, Up: TURTLE AND WINDOW CONTROL fence ----- FENCE tells the turtle to enter fence mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move as far as it can and then stop at the edge with an "out of bounds" error message. Compare WRAP and WINDOW. *Note WRAP:: .  File: ucblogo.info, Node: FILL, Next: LABEL, Prev: FENCE, Up: TURTLE AND WINDOW CONTROL fill ---- FILL fills in a region of the graphics window containing the turtle and bounded by lines that have been drawn earlier. This is not portable; it doesn't work for all machines, and may not work exactly the same way on different machines.  File: ucblogo.info, Node: LABEL, Next: TEXTSCREEN, Prev: FILL, Up: TURTLE AND WINDOW CONTROL label ----- LABEL text takes a word or list as input, and prints the input on the graphics window, starting at the turtle's position.  File: ucblogo.info, Node: TEXTSCREEN, Next: FULLSCREEN, Prev: LABEL, Up: TURTLE AND WINDOW CONTROL textscreen ---------- TEXTSCREEN TS rearranges the size and position of windows to maximize the space available in the text window (the window used for interaction with Logo). The details differ among machines. Compare SPLITSCREEN and FULLSCREEN. *Note SPLITSCREEN:: .  File: ucblogo.info, Node: FULLSCREEN, Next: SPLITSCREEN, Prev: TEXTSCREEN, Up: TURTLE AND WINDOW CONTROL fullscreen ---------- FULLSCREEN FS rearranges the size and position of windows to maximize the space available in the graphics window. The details differ among machines. Compare SPLITSCREEN and TEXTSCREEN. In the DOS version, switching from fullscreen to splitscreen loses the part of the picture that's hidden by the text window. Also, since there must be a text window to allow printing (including the printing of the Logo prompt), Logo automatically switches from fullscreen to splitscreen whenever anything is printed. [This design decision follows from the scarcity of memory, so that the extra memory to remember an invisible part of a drawing seems too expensive.]  File: ucblogo.info, Node: SPLITSCREEN, Next: SETSCRUNCH, Prev: FULLSCREEN, Up: TURTLE AND WINDOW CONTROL splitscreen ----------- SPLITSCREEN SS rearranges the size and position of windows to allow some room for text interaction while also keeping most of the graphics window visible. The details differ among machines. Compare TEXTSCREEN and FULLSCREEN. *Note TEXTSCREEN:: .  File: ucblogo.info, Node: SETSCRUNCH, Next: REFRESH, Prev: SPLITSCREEN, Up: TURTLE AND WINDOW CONTROL setscrunch ---------- SETSCRUNCH xscale yscale adjusts the aspect ratio and scaling of the graphics display. After this command is used, all further turtle motion will be adjusted by multiplying the horizontal and vertical extent of the motion by the two numbers given as inputs. For example, after the instruction `SETSCRUNCH 2 1' motion at a heading of 45 degrees will move twice as far horizontally as vertically. If your squares don't come out square, try this. (Alternatively, you can deliberately misadjust the aspect ratio to draw an ellipse.) For Unix machines and Macintoshes, both scale factors are initially 1. For DOS machines, the scale factors are initially set according to what the hardware claims the aspect ratio is, but the hardware sometimes lies. The values set by SETSCRUNCH are remembered in a file (called SCRUNCH.DAT) and are automatically put into effect when a Logo session begins.  File: ucblogo.info, Node: REFRESH, Next: NOREFRESH, Prev: SETSCRUNCH, Up: TURTLE AND WINDOW CONTROL refresh ------- REFRESH tells Logo to remember the turtle's motions so that they can be reconstructed in case the graphics window is overlayed. The effectiveness of this command may depend on the machine used.  File: ucblogo.info, Node: NOREFRESH, Prev: REFRESH, Up: TURTLE AND WINDOW CONTROL norefresh --------- NOREFRESH tells Logo not to remember the turtle's motions. This will make drawing faster, but prevents recovery if the window is overlayed.  File: ucblogo.info, Node: TURTLE AND WINDOW QUERIES, Next: PEN AND BACKGROUND CONTROL, Prev: TURTLE AND WINDOW CONTROL, Up: GRAPHICS Turtle and Window Queries ========================= * Menu: * SHOWNP:: * SCREENMODE:: * TURTLEMODE::  File: ucblogo.info, Node: SHOWNP, Next: SCREENMODE, Prev: TURTLE AND WINDOW QUERIES, Up: TURTLE AND WINDOW QUERIES shownp ------ SHOWNP SHOWN? outputs TRUE if the turtle is shown (visible), FALSE if the turtle is hidden. See SHOWTURTLE and HIDETURTLE. *Note SHOWTURTLE:: , *Note HIDETURTLE:: .  File: ucblogo.info, Node: SCREENMODE, Next: TURTLEMODE, Prev: SHOWNP, Up: TURTLE AND WINDOW QUERIES screenmode ---------- SCREENMODE outputs the word TEXTSCREEN, SPLITSCREEN, or FULLSCREEN depending on the current screen mode.  File: ucblogo.info, Node: TURTLEMODE, Prev: SCREENMODE, Up: TURTLE AND WINDOW QUERIES turtlemode ---------- TURTLEMODE outputs the word WRAP, FENCE, or WINDOW depending on the current turtle mode.  File: ucblogo.info, Node: PEN AND BACKGROUND CONTROL, Next: PEN QUERIES, Prev: TURTLE AND WINDOW QUERIES, Up: GRAPHICS Pen and Background Control ========================== The turtle carries a pen that can draw pictures. At any time the pen can be UP (in which case moving the turtle does not change what's on the graphics screen) or DOWN (in which case the turtle leaves a trace). If the pen is down, it can operate in one of three modes: PAINT (so that it draws lines when the turtle moves), ERASE (so that it erases any lines that might have been drawn on or through that path earlier), or REVERSE (so that it inverts the status of each point along the turtle's path). * Menu: * PENDOWN:: * PENUP:: * PENPAINT:: * PENERASE:: * PENREVERSE:: * SETPENCOLOR:: * SETPALETTE:: * SETPENSIZE:: * SETPENPATTERN:: * SETPEN:: * SETBACKGROUND::  File: ucblogo.info, Node: PENDOWN, Next: PENUP, Prev: PEN AND BACKGROUND CONTROL, Up: PEN AND BACKGROUND CONTROL pendown ------- PENDOWN PD sets the pen's position to DOWN, without changing its mode.  File: ucblogo.info, Node: PENUP, Next: PENPAINT, Prev: PENDOWN, Up: PEN AND BACKGROUND CONTROL penup ----- PENUP PU sets the pen's position to UP, without changing its mode.  File: ucblogo.info, Node: PENPAINT, Next: PENERASE, Prev: PENUP, Up: PEN AND BACKGROUND CONTROL penpaint -------- PENPAINT PPT sets the pen's position to DOWN and mode to PAINT.  File: ucblogo.info, Node: PENERASE, Next: PENREVERSE, Prev: PENPAINT, Up: PEN AND BACKGROUND CONTROL penerase -------- PENERASE PE sets the pen's position to DOWN and mode to ERASE. *Note ERASE:: .  File: ucblogo.info, Node: PENREVERSE, Next: SETPENCOLOR, Prev: PENERASE, Up: PEN AND BACKGROUND CONTROL penreverse ---------- PENREVERSE PX sets the pen's position to DOWN and mode to REVERSE. (This may interact in hardware-dependent ways with use of color.) *Note REVERSE:: .  File: ucblogo.info, Node: SETPENCOLOR, Next: SETPALETTE, Prev: PENREVERSE, Up: PEN AND BACKGROUND CONTROL setpencolor ----------- SETPENCOLOR colornumber.or.rgblist SETPC colornumber.or.rgblist sets the pen color to the given number, which must be a nonnegative integer. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command. Alternatively, sets the pen color to the given RGB values (a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color).  File: ucblogo.info, Node: SETPALETTE, Next: SETPENSIZE, Prev: SETPENCOLOR, Up: PEN AND BACKGROUND CONTROL setpalette ---------- SETPALETTE colornumber rgblist sets the actual color corresponding to a given number, if allowed by the hardware and operating system. Colornumber must be an integer greater than or equal to 8. (Logo tries to keep the first 8 colors constant.) The second input is a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color. The actual color resolution on any screen is probably less than 64K, but Logo scales as needed.  File: ucblogo.info, Node: SETPENSIZE, Next: SETPENPATTERN, Prev: SETPALETTE, Up: PEN AND BACKGROUND CONTROL setpensize ---------- SETPENSIZE size sets the thickness of the pen. The input is either a single positive integer or a list of two positive integers (for horizontal and vertical thickness). Some versions pay no attention to the second number, but always have a square pen. SETPENPATTERN pattern sets hardware-dependent pen characteristics. This command is not guaranteed compatible between implementations on different machines.  File: ucblogo.info, Node: SETPENPATTERN, Next: SETPEN, Prev: SETPENSIZE, Up: PEN AND BACKGROUND CONTROL setpenpattern ------------- SETPENSIZE size SETPENPATTERN pattern set hardware-dependent pen characteristics. These commands are not guaranteed compatible between implementations on different machines.  File: ucblogo.info, Node: SETPEN, Next: SETBACKGROUND, Prev: SETPENPATTERN, Up: PEN AND BACKGROUND CONTROL setpen ------ SETPEN list (library procedure) sets the pen's position, mode, thickness, and hardware-dependent characteristics according to the information in the input list, which should be taken from an earlier invocation of PEN. *Note PEN:: .  File: ucblogo.info, Node: SETBACKGROUND, Prev: SETPEN, Up: PEN AND BACKGROUND CONTROL setbackground ------------- SETBACKGROUND colornumber.or.rgblist SETBG colornumber.or.rgblist set the screen background color by slot number or RGB values. See SETPENCOLOR for details. *Note SETPENCOLOR:: .  File: ucblogo.info, Node: PEN QUERIES, Next: SAVING AND LOADING PICTURES, Prev: PEN AND BACKGROUND CONTROL, Up: GRAPHICS Pen Queries =========== * Menu: * PENDOWNP:: * PENMODE:: * PENCOLOR:: * PALETTE:: * PENSIZE:: * PEN:: * BACKGROUND::  File: ucblogo.info, Node: PENDOWNP, Next: PENMODE, Prev: PEN QUERIES, Up: PEN QUERIES pendownp -------- PENDOWNP PENDOWN? outputs TRUE if the pen is down, FALSE if it's up.  File: ucblogo.info, Node: PENMODE, Next: PENCOLOR, Prev: PENDOWNP, Up: PEN QUERIES penmode ------- PENMODE outputs one of the words PAINT, ERASE, or REVERSE according to the current pen mode. *Note ERASE:: , *Note REVERSE:: .  File: ucblogo.info, Node: PENCOLOR, Next: PALETTE, Prev: PENMODE, Up: PEN QUERIES pencolor -------- PENCOLOR PC outputs a color number, a nonnegative integer that is associated with a particular color, or a list of RGB values if such a list was used as the most recent input to SETPENCOLOR. There are initial assignments for the first 16 colors: 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey but other colors can be assigned to numbers by the PALETTE command.  File: ucblogo.info, Node: PALETTE, Next: PENSIZE, Prev: PENCOLOR, Up: PEN QUERIES palette ------- PALETTE colornumber outputs a list of three integers, each in the range 0-65535, representing the amount of red, green, and blue in the color associated with the given number.  File: ucblogo.info, Node: PENSIZE, Next: PEN, Prev: PALETTE, Up: PEN QUERIES pensize ------- PENSIZE outputs a list of two positive integers, specifying the horizontal and vertical thickness of the turtle pen. (In some implementations the two numbers may always be equal.) PENPATTERN outputs hardware-specific pen information.  File: ucblogo.info, Node: PEN, Next: BACKGROUND, Prev: PENSIZE, Up: PEN QUERIES pen --- PEN (library procedure) outputs a list containing the pen's position, mode, thickness, and hardware-specific characteristics, for use by SETPEN. *Note SETPEN:: . ucblogo-5.5/docs/ucblogo.info-30100644000161300001330000013733210276035443014344 0ustar bhdoeThis is ucblogo.info, produced by makeinfo version 4.5 from usermanual.texi.  File: ucblogo.info, Node: BACKGROUND, Prev: PEN, Up: PEN QUERIES background ---------- BACKGROUND BG outputs the graphics background color, either as a slot number or as an RGB list, whichever way it was set. (See PENCOLOR.)  File: ucblogo.info, Node: SAVING AND LOADING PICTURES, Next: MOUSE QUERIES, Prev: PEN QUERIES, Up: GRAPHICS saving and loading pictures =========================== * Menu: * SAVEPICT:: * LOADPICT:: * EPSPICT::  File: ucblogo.info, Node: SAVEPICT, Next: LOADPICT, Prev: SAVING AND LOADING PICTURES, Up: SAVING AND LOADING PICTURES savepict -------- SAVEPICT filename command. Writes a file with the specified name containing the state of the graphics window, including any nonstandard color palette settings, in Logo's internal format. This picture can be restored to the screen using LOADPICT. The format is not portable between platforms, nor is it readable by other programs. *Note EPSPICT:: to export Logo graphics for other programs.  File: ucblogo.info, Node: LOADPICT, Next: EPSPICT, Prev: SAVEPICT, Up: SAVING AND LOADING PICTURES loadpict -------- LOADPICT filename command. Reads the specified file, which must have been written by a SAVEPICT command, and restores the graphics window and color palette settings to the values stored in the file. Any drawing previously on the screen is cleared. *Note SAVEPICT:: .  File: ucblogo.info, Node: EPSPICT, Prev: LOADPICT, Up: SAVING AND LOADING PICTURES epspict ------- EPSPICT filename command. Writes a file with the specified name, containing an Encapsulated Postscript (EPS) representation of the state of the graphics window. This file can be imported into other programs that understand EPS format. Restrictions: the drawing cannot use ARC, FILL, PENERASE, or PENREVERSE; any such instructions will be ignored in the translation to Postscript form. *Note ARC:: , *Note FILL:: , *Note PENERASE:: , *Note PENREVERSE:: .  File: ucblogo.info, Node: MOUSE QUERIES, Prev: SAVING AND LOADING PICTURES, Up: GRAPHICS Mouse Queries ============= * Menu: * MOUSEPOS:: * BUTTONP:: * BUTTON::  File: ucblogo.info, Node: MOUSEPOS, Next: BUTTONP, Prev: MOUSE QUERIES, Up: MOUSE QUERIES mousepos -------- MOUSEPOS outputs the coordinates of the mouse, provided that it's within the graphics window, in turtle coordinates. If the mouse is outside the graphics window, then the last position within the window is returned. Exception: If a mouse button is pressed within the graphics window and held while the mouse is dragged outside the window, the mouse's position is returned as if the window were big enough to include it.  File: ucblogo.info, Node: BUTTONP, Next: BUTTON, Prev: MOUSEPOS, Up: MOUSE QUERIES buttonp ------- BUTTONP BUTTON? outputs TRUE if a mouse button is down and the mouse is over the graphics window. Once the button is down, BUTTONP remains true until the button is released, even if the mouse is dragged out of the graphics window.  File: ucblogo.info, Node: BUTTON, Prev: BUTTONP, Up: MOUSE QUERIES buttonp ------- BUTTON outputs 0 if BUTTONP would output FALSE; otherwise, it outputs an integer between 1 and 3 indicating which button was pressed. Ordinarily 1 means left, 2 means right, and 3 means center, but operating systems may reconfigure these.  File: ucblogo.info, Node: WORKSPACE MANAGEMENT, Next: CONTROL STRUCTURES, Prev: GRAPHICS, Up: Top Workspace Management ******************** * Menu: * PROCEDURE DEFINITION:: * VARIABLE DEFINITION:: * PROPERTY LISTS:: * WORKSPACE PREDICATES:: * WORKSPACE QUERIES:: * WORKSPACE INSPECTION:: * WORKSPACE CONTROL::  File: ucblogo.info, Node: PROCEDURE DEFINITION, Next: VARIABLE DEFINITION, Prev: WORKSPACE MANAGEMENT, Up: WORKSPACE MANAGEMENT Procedure Definition ==================== * Menu: * TO:: * DEFINE:: * TEXT:: * FULLTEXT:: * COPYDEF::  File: ucblogo.info, Node: TO, Next: DEFINE, Prev: PROCEDURE DEFINITION, Up: PROCEDURE DEFINITION to -- TO procname :input1 :input2 ... (special form) command. Prepares Logo to accept a procedure definition. The procedure will be named `procname' and there must not already be a procedure by that name. The inputs will be called `input1' etc. Any number of inputs are allowed, including none. Names of procedures and inputs are case-insensitive. Unlike every other Logo procedure, TO takes as its inputs the actual words typed in the instruction line, as if they were all quoted, rather than the results of evaluating expressions to provide the inputs. (That's what "special form" means.) This version of Logo allows variable numbers of inputs to a procedure. After the procedure name come four kinds of things, *in this order*: 1. 0 or more REQUIRED inputs :FOO :FROBOZZ 2. 0 or more OPTIONAL inputs [:BAZ 87] [:THINGO 5+9] 3. 0 or 1 REST input [:GARPLY] 4. 0 or 1 DEFAULT number 5 Every procedure has a MINIMUM, DEFAULT, and MAXIMUM number of inputs. (The latter can be infinite.) The MINIMUM number of inputs is the number of required inputs, which must come first. A required input is indicated by the :inputname notation. After all the required inputs can be zero or more optional inputs, each of which is represented by the following notation: [:inputname default.value.expression] When the procedure is invoked, if actual inputs are not supplied for these optional inputs, the default value expressions are evaluated to set values for the corresponding input names. The inputs are processed from left to right, so a default value expression can be based on earlier inputs. Example: to proc :inlist [:startvalue first :inlist] If the procedure is invoked by saying proc [a b c] then the variable `inlist' will have the value [A B C] and the variable `startvalue' will have the value A. If the procedure is invoked by saying (proc [a b c] "x) then `inlist' will have the value [A B C] and `startvalue' will have the value X. After all the required and optional input can come a single `rest' input, represented by the following notation: [:inputname] This is a rest input rather than an optional input because there is no default value expression. There can be at most one rest input. When the procedure is invoked, the value of this input will be a list containing all of the actual inputs provided that were not used for required or optional inputs. Example: to proc :in1 [:in2 "foo] [:in3 "baz] [:in4] If this procedure is invoked by saying proc "x then `in1' has the value X, `in2' has the value FOO, `in3' has the value BAZ,and `in4' has the value [] (the empty list). If it's invoked by saying (proc "a "b "c "d "e) then `in1' has the value A, `in2' has the value B, `in3' has the value C, and `in4' has the value [D E]. The MAXIMUM number of inputs for a procedure is infinite if a rest input is given; otherwise, it is the number of required inputs plus the number of optional inputs. The DEFAULT number of inputs for a procedure, which is the number of inputs that it will accept if its invocation is not enclosed in parentheses, is ordinarily equal to the minimum number. If you want a different default number you can indicate that by putting the desired default number as the last thing on the TO line. example: to proc :in1 [:in2 "foo] [:in3] 3 This procedure has a minimum of one input, a default of three inputs, and an infinite maximum. Logo responds to the TO command by entering procedure definition mode. The prompt character changes from `?' to `>' and whatever instructions you type become part of the definition until you type a line containing only the word END.  File: ucblogo.info, Node: DEFINE, Next: TEXT, Prev: TO, Up: PROCEDURE DEFINITION define ------ DEFINE procname text command. Defines a procedure with name `procname' and text `text'. If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.) It is an error to redefine a primitive procedure unless the variable REDEFP has the value TRUE. *Note REDEFP:: .  File: ucblogo.info, Node: TEXT, Next: FULLTEXT, Prev: DEFINE, Up: PROCEDURE DEFINITION text ---- TEXT procname outputs the text of the procedure named `procname' in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces.  File: ucblogo.info, Node: FULLTEXT, Next: COPYDEF, Prev: TEXT, Up: PROCEDURE DEFINITION fulltext -------- FULLTEXT procname outputs a representation of the procedure `procname' in which formatting information is preserved. If the procedure was defined with TO, EDIT, or LOAD, then the output is a list of words. Each word represents one entire line of the definition in the form output by READWORD, including extra spaces and continuation lines. The last member of the output represents the END line. If the procedure was defined with DEFINE, then the output is a list of lists. If these lists are printed, one per line, the result will look like a definition using TO. Note: the output from FULLTEXT is not suitable for use as input to DEFINE! *Note TO:: , *Note EDIT:: , *Note LOAD:: , *Note DEFINE:: .  File: ucblogo.info, Node: COPYDEF, Prev: FULLTEXT, Up: PROCEDURE DEFINITION copydef ------- COPYDEF newname oldname command. Makes `newname' a procedure identical to `oldname'. The latter may be a primitive. If `newname' was already defined, its previous definition is lost. If `newname' was already a primitive, the redefinition is not permitted unless the variable REDEFP has the value TRUE. Note: dialects of Logo differ as to the order of inputs to COPYDEF. This dialect uses "MAKE order," not "NAME order." *Note REDEFP:: , *Note SAVE:: , *Note PO:: , *Note POT:: .  File: ucblogo.info, Node: VARIABLE DEFINITION, Next: PROPERTY LISTS, Prev: PROCEDURE DEFINITION, Up: WORKSPACE MANAGEMENT Variable Definition =================== * Menu: * MAKE:: * NAME:: * LOCAL:: * LOCALMAKE:: * THING:: * GLOBAL::  File: ucblogo.info, Node: MAKE, Next: NAME, Prev: VARIABLE DEFINITION, Up: VARIABLE DEFINITION make ---- MAKE varname value command. Assigns the value `value' to the variable named `varname', which must be a word. Variable names are case-insensitive. If a variable with the same name already exists, the value of that variable is changed. If not, a new global variable is created.  File: ucblogo.info, Node: NAME, Next: LOCAL, Prev: MAKE, Up: VARIABLE DEFINITION name ---- NAME value varname (library procedure) command. Same as MAKE but with the inputs in reverse order.  File: ucblogo.info, Node: LOCAL, Next: LOCALMAKE, Prev: NAME, Up: VARIABLE DEFINITION local ----- LOCAL varname LOCAL varnamelist (LOCAL varname1 varname2 ...) command. Accepts as inputs one or more words, or a list of words. A variable is created for each of these words, with that word as its name. The variables are local to the currently running procedure. Logo variables follow dynamic scope rules; a variable that is local to a procedure is available to any subprocedure invoked by that procedure. The variables created by LOCAL have no initial value; they must be assigned a value (e.g., with MAKE) before the procedure attempts to read their value. *Note MAKE:: .  File: ucblogo.info, Node: LOCALMAKE, Next: THING, Prev: LOCAL, Up: VARIABLE DEFINITION localmake --------- LOCALMAKE varname value (library procedure) command. Makes the named variable local, like LOCAL, and assigns it the given value, like MAKE. *Note LOCAL:: , *Note MAKE:: .  File: ucblogo.info, Node: THING, Next: GLOBAL, Prev: LOCALMAKE, Up: VARIABLE DEFINITION thing ----- THING varname :quoted.varname outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination thing " so that :FOO means THING "FOO.  File: ucblogo.info, Node: GLOBAL, Prev: THING, Up: VARIABLE DEFINITION global ------ GLOBAL varname GLOBAL varnamelist (GLOBAL varname1 varname2 ...) command. Accepts as inputs one or more words, or a list of words. A global variable is created for each of these words, with that word as its name. The only reason this is necessary is that you might want to use the "setter" notation SETXYZ for a variable XYZ that does not already have a value; GLOBAL "XYZ makes that legal. Note: If there is currently a local variable of the same name, this command does *not* make Logo use the global value instead of the local one.  File: ucblogo.info, Node: PROPERTY LISTS, Next: WORKSPACE PREDICATES, Prev: VARIABLE DEFINITION, Up: WORKSPACE MANAGEMENT Property Lists ============== Note: Names of property lists are always case-insensitive. Names of individual properties are case-sensitive or case-insensitive depending on the value of CASEIGNOREDP, which is TRUE by default. *Note CASEIGNOREDP:: . In principle, every possible name is the name of a property list, which is initially empty. So Logo never gives a "no such property list" error, as it would for undefined procedure or variable names. But the primitive procedures that deal with "all" property lists (CONTENTS, PLISTS, etc.) list only nonempty ones. To "erase" a property list *Note ERASE:: means to make it empty, removing all properties from it. * Menu: * PPROP:: * GPROP:: * REMPROP:: * PLIST::  File: ucblogo.info, Node: PPROP, Next: GPROP, Prev: PROPERTY LISTS, Up: PROPERTY LISTS pprop ----- PPROP plistname propname value command. Adds a property to the `plistname' property list with name `propname' and value `value'.  File: ucblogo.info, Node: GPROP, Next: REMPROP, Prev: PPROP, Up: PROPERTY LISTS gprop ----- GPROP plistname propname outputs the value of the `propname' property in the `plistname' property list, or the empty list if there is no such property.  File: ucblogo.info, Node: REMPROP, Next: PLIST, Prev: GPROP, Up: PROPERTY LISTS remprop ------- REMPROP plistname propname command. Removes the property named `propname' from the property list named `plistname'.  File: ucblogo.info, Node: PLIST, Prev: REMPROP, Up: PROPERTY LISTS plist ----- PLIST plistname outputs a list whose odd-numbered members are the names, and whose even-numbered members are the values, of the properties in the property list named `plistname'. The output is a copy of the actual property list; changing properties later will not magically change a list output earlier by PLIST.  File: ucblogo.info, Node: WORKSPACE PREDICATES, Next: WORKSPACE QUERIES, Prev: PROPERTY LISTS, Up: WORKSPACE MANAGEMENT Workspace Predicates ==================== * Menu: * PROCEDUREP:: * PRIMITIVEP:: * DEFINEDP:: * NAMEP:: * PLISTP::  File: ucblogo.info, Node: PROCEDUREP, Next: PRIMITIVEP, Prev: WORKSPACE PREDICATES, Up: WORKSPACE PREDICATES procedurep ---------- PROCEDUREP name PROCEDURE? name outputs TRUE if the input is the name of a procedure.  File: ucblogo.info, Node: PRIMITIVEP, Next: DEFINEDP, Prev: PROCEDUREP, Up: WORKSPACE PREDICATES primitivep ---------- PRIMITIVEP name PRIMITIVE? name outputs TRUE if the input is the name of a primitive procedure (one built into Logo). Note that some of the procedures described in this document are library procedures, not primitives.  File: ucblogo.info, Node: DEFINEDP, Next: NAMEP, Prev: PRIMITIVEP, Up: WORKSPACE PREDICATES definedp -------- DEFINEDP name DEFINED? name outputs TRUE if the input is the name of a user-defined procedure, including a library procedure. (However, Logo does not know about a library procedure until that procedure has been invoked.)  File: ucblogo.info, Node: NAMEP, Next: PLISTP, Prev: DEFINEDP, Up: WORKSPACE PREDICATES namep ----- NAMEP name NAME? name outputs TRUE if the input is the name of a variable.  File: ucblogo.info, Node: PLISTP, Prev: NAMEP, Up: WORKSPACE PREDICATES plistp ------ PLISTP name PLIST? name outputs TRUE if the input is the name of a *nonempty* property list. (In principle every word is the name of a property list; if you haven't put any properties in it, PLIST of that name outputs an empty list, rather than giving an error message.)  File: ucblogo.info, Node: WORKSPACE QUERIES, Next: WORKSPACE INSPECTION, Prev: WORKSPACE PREDICATES, Up: WORKSPACE MANAGEMENT Workspace Queries ================= * Menu: * CONTENTS:: * BURIED:: * TRACED:: * STEPPED:: * PROCEDURES:: * PRIMITIVES:: * NAMES:: * PLISTS:: * NAMELIST:: * PLLIST:: * ARITY:: * NODES::  File: ucblogo.info, Node: CONTENTS, Next: BURIED, Prev: WORKSPACE QUERIES, Up: WORKSPACE QUERIES contents -------- CONTENTS outputs a "contents list," i.e., a list of three lists containing names of defined procedures, variables, and property lists respectively. This list includes all unburied named items in the workspace.  File: ucblogo.info, Node: BURIED, Next: TRACED, Prev: CONTENTS, Up: WORKSPACE QUERIES buried ------ BURIED outputs a contents list including all buried named items in the workspace.  File: ucblogo.info, Node: TRACED, Next: STEPPED, Prev: BURIED, Up: WORKSPACE QUERIES traced ------ TRACED outputs a contents list including all traced named items in the workspace.  File: ucblogo.info, Node: STEPPED, Next: PROCEDURES, Prev: TRACED, Up: WORKSPACE QUERIES stepped ------- STEPPED outputs a contents list including all stepped named items in the workspace.  File: ucblogo.info, Node: PROCEDURES, Next: PRIMITIVES, Prev: STEPPED, Up: WORKSPACE QUERIES procedures ---------- PROCEDURES outputs a list of the names of all unburied user-defined procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.)  File: ucblogo.info, Node: PRIMITIVES, Next: NAMES, Prev: PROCEDURES, Up: WORKSPACE QUERIES primitives ---------- PRIMITIVES outputs a list of the names of all primitive procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.)  File: ucblogo.info, Node: NAMES, Next: PLISTS, Prev: PRIMITIVES, Up: WORKSPACE QUERIES names ----- NAMES outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace.  File: ucblogo.info, Node: PLISTS, Next: NAMELIST, Prev: NAMES, Up: WORKSPACE QUERIES plists ------ PLISTS outputs a contents list consisting of two empty lists (indicating no procedures or variables) followed by a list of all unburied nonempty property lists in the workspace.  File: ucblogo.info, Node: NAMELIST, Next: PLLIST, Prev: PLISTS, Up: WORKSPACE QUERIES namelist -------- NAMELIST varname (library procedure) NAMELIST varnamelist outputs a contents list consisting of an empty list followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input.  File: ucblogo.info, Node: PLLIST, Next: ARITY, Prev: NAMELIST, Up: WORKSPACE QUERIES pllist ------ PLLIST plname (library procedure) PLLIST plnamelist outputs a contents list consisting of two empty lists followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. Note: All procedures whose input is indicated as `contentslist' will accept a single word (taken as a procedure name), a list of words (taken as names of procedures), or a list of three lists as described under the CONTENTS command above. *Note CONTENTS:: .  File: ucblogo.info, Node: ARITY, Next: NODES, Prev: PLLIST, Up: WORKSPACE QUERIES arity ----- ARITY procedurename outputs a list of three numbers: the minimum, default, and maximum number of inputs for the procedure whose name is the input. It is an error if there is no such procedure. A maximum of -1 means that the number of inputs is unlimited.  File: ucblogo.info, Node: NODES, Prev: ARITY, Up: WORKSPACE QUERIES nodes ----- NODES outputs a list of two numbers. The first represents the number of nodes of memory currently in use. The second shows the maximum number of nodes that have been in use at any time since the last invocation of NODES. (A node is a small block of computer memory as used by Logo. Each number uses one node. Each non-numeric word uses one node, plus some non-node memory for the characters in the word. Each array takes one node, plus some non-node memory, as well as the memory required by its elements. Each list requires one node per element, as well as the memory within the elements.) If you want to track the memory use of an algorithm, it is best if you invoke GC at the beginning of each iteration, since otherwise the maximum will include storage that is unused but not yet collected.  File: ucblogo.info, Node: WORKSPACE INSPECTION, Next: WORKSPACE CONTROL, Prev: WORKSPACE QUERIES, Up: WORKSPACE MANAGEMENT Workspace Inspection ==================== * Menu: * PO:: * POALL:: * POPS:: * PONS:: * POPLS:: * PON:: * POPL:: * POT:: * POTS::  File: ucblogo.info, Node: PO, Next: POALL, Prev: WORKSPACE INSPECTION, Up: WORKSPACE INSPECTION po -- PRINTOUT contentslist PO contentslist command. Prints to the write stream the definitions of all procedures, variables, and property lists named in the input contents list.  File: ucblogo.info, Node: POALL, Next: POPS, Prev: PO, Up: WORKSPACE INSPECTION poall ----- POALL (library procedure) command. Prints all unburied definitions in the workspace. Abbreviates PO CONTENTS. *Note CONTENTS:: .  File: ucblogo.info, Node: POPS, Next: PONS, Prev: POALL, Up: WORKSPACE INSPECTION pops ---- POPS (library procedure) command. Prints the definitions of all unburied procedures in the workspace. Abbreviates PO PROCEDURES. *Note PO:: , *Note PROCEDURES:: .  File: ucblogo.info, Node: PONS, Next: POPLS, Prev: POPS, Up: WORKSPACE INSPECTION pons ---- PONS (library procedure) command. Prints the definitions of all unburied variables in the workspace. Abbreviates PO NAMES. *Note PO:: , *Note NAMES:: .  File: ucblogo.info, Node: POPLS, Next: PON, Prev: PONS, Up: WORKSPACE INSPECTION popls ----- POPLS (library procedure) command. Prints the contents of all unburied nonempty property lists in the workspace. Abbreviates PO PLISTS. *Note PO:: , *Note PLISTS:: .  File: ucblogo.info, Node: PON, Next: POPL, Prev: POPLS, Up: WORKSPACE INSPECTION pon --- PON varname (library procedure) PON varnamelist command. Prints the definitions of the named variable(s). Abbreviates PO NAMELIST varname(list). *Note PO:: , *Note NAMELIST:: .  File: ucblogo.info, Node: POPL, Next: POT, Prev: PON, Up: WORKSPACE INSPECTION popl ---- POPL plname (library procedure) POPL plnamelist command. Prints the definitions of the named property list(s). Abbreviates PO PLLIST plname(list). *Note PO:: , *Note PLLIST:: .  File: ucblogo.info, Node: POT, Next: POTS, Prev: POPL, Up: WORKSPACE INSPECTION pot --- POT contentslist command. Prints the title lines of the named procedures and the definitions of the named variables and property lists. For property lists, the entire list is shown on one line instead of as a series of PPROP instructions as in PO. *Note PPROP:: , *Note PO:: .  File: ucblogo.info, Node: POTS, Prev: POT, Up: WORKSPACE INSPECTION pots ---- POTS (library procedure) command. Prints the title lines of all unburied procedures in the workspace. Abbreviates POT PROCEDURES. *Note PROCEDURES:: .  File: ucblogo.info, Node: WORKSPACE CONTROL, Prev: WORKSPACE INSPECTION, Up: WORKSPACE MANAGEMENT Workspace Control ================= * Menu: * ERASE:: * ERALL:: * ERPS:: * ERNS:: * ERPLS:: * ERN:: * ERPL:: * BURY:: * BURYALL:: * BURYNAME:: * UNBURY:: * UNBURYALL:: * UNBURYNAME:: * BURIEDP:: * TRACE:: * UNTRACE:: * TRACEDP:: * STEP:: * UNSTEP:: * STEPPEDP:: * EDIT:: * EDITFILE:: * EDALL:: * EDPS:: * EDNS:: * EDPLS:: * EDN:: * EDPL:: * SAVE:: * SAVEL:: * LOAD:: * CSLSLOAD:: * HELP:: * SETEDITOR:: * SETLIBLOC:: * SETHELPLOC:: * SETCSLSLOC:: * SETTEMPLOC:: * GC:: * .SETSEGMENTSIZE::  File: ucblogo.info, Node: ERASE, Next: ERALL, Prev: WORKSPACE CONTROL, Up: WORKSPACE CONTROL erase ----- ERASE contentslist ER contentslist command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE. *Note REDEFP:: .  File: ucblogo.info, Node: ERALL, Next: ERPS, Prev: ERASE, Up: WORKSPACE CONTROL erall ----- ERALL command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates ERASE CONTENTS. *Note CONTENTS:: .  File: ucblogo.info, Node: ERPS, Next: ERNS, Prev: ERALL, Up: WORKSPACE CONTROL erps ---- ERPS command. Erases all unburied procedures from the workspace. Abbreviates ERASE PROCEDURES. *Note ERASE:: , *Note PROCEDURES:: .  File: ucblogo.info, Node: ERNS, Next: ERPLS, Prev: ERPS, Up: WORKSPACE CONTROL erns ---- ERNS command. Erases all unburied variables from the workspace. Abbreviates ERASE NAMES. *Note ERASE:: , *Note NAMES:: .  File: ucblogo.info, Node: ERPLS, Next: ERN, Prev: ERNS, Up: WORKSPACE CONTROL erpls ----- ERPLS command. Erases all unburied property lists from the workspace. Abbreviates ERASE PLISTS. *Note ERASE:: , *Note PLISTS:: .  File: ucblogo.info, Node: ERN, Next: ERPL, Prev: ERPLS, Up: WORKSPACE CONTROL ern --- ERN varname (library procedure) ERN varnamelist command. Erases from the workspace the variable(s) named in the input. Abbreviates ERASE NAMELIST varname(list). *Note ERASE:: , *Note NAMELIST:: .  File: ucblogo.info, Node: ERPL, Next: BURY, Prev: ERN, Up: WORKSPACE CONTROL erpl ---- ERPL plname (library procedure) ERPL plnamelist command. Erases from the workspace the property list(s) named in the input. Abbreviates ERASE PLLIST plname(list). *Note ERASE:: , *Note PLLIST:: .  File: ucblogo.info, Node: BURY, Next: BURYALL, Prev: ERPL, Up: WORKSPACE CONTROL bury ---- BURY contentslist command. Buries the procedures, variables, and property lists named in the input. A buried item is not included in the lists output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is included in the list output by BURIED. By implication, buried things are not printed by POALL or saved by SAVE. *Note CONTENTS:: , *Note PROCEDURES:: , *Note PONS:: , *Note PLISTS:: , *Note POALL:: , *Note SAVE:: .  File: ucblogo.info, Node: BURYALL, Next: BURYNAME, Prev: BURY, Up: WORKSPACE CONTROL buryall ------- BURYALL (library procedure) command. Abbreviates BURY CONTENTS. *Note CONTENTS:: .  File: ucblogo.info, Node: BURYNAME, Next: UNBURY, Prev: BURYALL, Up: WORKSPACE CONTROL buryname -------- BURYNAME varname (library procedure) BURYNAME varnamelist command. Abbreviates BURY NAMELIST varname(list). *Note BURY:: , *Note NAMELIST:: .  File: ucblogo.info, Node: UNBURY, Next: UNBURYALL, Prev: BURYNAME, Up: WORKSPACE CONTROL unbury ------ UNBURY contentslist command. Unburies the procedures, variables, and property lists named in the input. That is, the named items will be returned to view in CONTENTS, etc. *Note CONTENTS:: .  File: ucblogo.info, Node: UNBURYALL, Next: UNBURYNAME, Prev: UNBURY, Up: WORKSPACE CONTROL unburyall --------- UNBURYALL (library procedure) command. Abbreviates UNBURY BURIED. *Note BURIED:: .  File: ucblogo.info, Node: UNBURYNAME, Next: BURIEDP, Prev: UNBURYALL, Up: WORKSPACE CONTROL unburyname ---------- UNBURYNAME varname (library procedure) UNBURYNAME varnamelist command. Abbreviates UNBURY NAMELIST varname(list). *Note UNBURY:: , *Note NAMELIST:: .  File: ucblogo.info, Node: BURIEDP, Next: TRACE, Prev: UNBURYNAME, Up: WORKSPACE CONTROL buriedp ------- BURIEDP contentslist BURIED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is buried, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can `BURIEDP [[] [VARIABLE]]' or `BURIEDP [[] [] [PROPLIST]]'.  File: ucblogo.info, Node: TRACE, Next: UNTRACE, Prev: BURIEDP, Up: WORKSPACE CONTROL trace ----- TRACE contentslist command. Marks the named items for tracing. A message is printed whenever a traced procedure is invoked, giving the actual input values, and whenever a traced procedure STOPs or OUTPUTs. A message is printed whenever a new value is assigned to a traced variable using MAKE. A message is printed whenever a new property is given to a traced property list using PPROP. *Note STOP:: , *Note OUTPUT:: , *Note MAKE:: , *Note PPROP:: .  File: ucblogo.info, Node: UNTRACE, Next: TRACEDP, Prev: TRACE, Up: WORKSPACE CONTROL untrace ------- UNTRACE contentslist command. Turns off tracing for the named items.  File: ucblogo.info, Node: TRACEDP, Next: STEP, Prev: UNTRACE, Up: WORKSPACE CONTROL tracedp ------- TRACEDP contentslist TRACED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is traced, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can `TRACEDP [[] [VARIABLE]]' or `TRACEDP [[] [] [PROPLIST]]'.  File: ucblogo.info, Node: STEP, Next: UNSTEP, Prev: TRACEDP, Up: WORKSPACE CONTROL step ---- STEP contentslist command. Marks the named items for stepping. Whenever a stepped procedure is invoked, each instruction line in the procedure body is printed before being executed, and Logo waits for the user to type a newline at the terminal. A message is printed whenever a stepped variable name is `shadowed' because a local variable of the same name is created either as a procedure input or by the LOCAL command. *Note LOCAL:: .  File: ucblogo.info, Node: UNSTEP, Next: STEPPEDP, Prev: STEP, Up: WORKSPACE CONTROL unstep ------ UNSTEP contentslist command. Turns off stepping for the named items.  File: ucblogo.info, Node: STEPPEDP, Next: EDIT, Prev: UNSTEP, Up: WORKSPACE CONTROL steppedp -------- STEPPEDP contentslist STEPPED? contentslist outputs TRUE if the first procedure, variable, or property list named in the contents list is stepped, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can `STEPPEDP [[] [VARIABLE]]' or `STEPPEDP [[] [] [PROPLIST]]'.  File: ucblogo.info, Node: EDIT, Next: EDITFILE, Prev: STEPPEDP, Up: WORKSPACE CONTROL edit ---- EDIT contentslist ED contentslist (EDIT) (ED) command. If invoked with an input, EDIT writes the definitions of the named items into a temporary file and edits that file, using your favorite editor as determined by the EDITOR environment variable. If you don't have an EDITOR variable, edits the definitions using jove. If invoked without an input, EDIT edits the same file left over from a previous EDIT or EDITFILE instruction. When you leave the editor, Logo reads the revised definitions and modifies the workspace accordingly. It is not an error if the input includes names for which there is no previous definition. If there is a variable LOADNOISILY whose value is TRUE, then, after leaving the editor, TO commands in the temporary file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. If there is an environment variable called TEMP, then Logo uses its value as the directory in which to write the temporary file used for editing. Exceptionally, the EDIT command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. *Note LOADNOISILY:: , *Note EDITFILE:: .  File: ucblogo.info, Node: EDITFILE, Next: EDALL, Prev: EDIT, Up: WORKSPACE CONTROL editfile -------- EDITFILE filename command. Starts the Logo editor, like EDIT, but instead of editing a temporary file it edits the file specified by the input. When you leave the editor, Logo reads the revised file, as for EDIT. EDITFILE also remembers the filename, so that a subsequent EDIT command with no input will re-edit the same file. EDITFILE is intended as an alternative to LOAD and SAVE. You can maintain a workspace file yourself, controlling the order in which definitions appear, maintaining comments in the file, and so on.  File: ucblogo.info, Node: EDALL, Next: EDPS, Prev: EDITFILE, Up: WORKSPACE CONTROL edall ----- EDALL (library procedure) command. Abbreviates EDIT CONTENTS. *Note CONTENTS:: .  File: ucblogo.info, Node: EDPS, Next: EDNS, Prev: EDALL, Up: WORKSPACE CONTROL edps ---- EDPS (library procedure) command. Abbreviates EDIT PROCEDURES. *Note EDIT:: , *Note PROCEDURES:: .  File: ucblogo.info, Node: EDNS, Next: EDPLS, Prev: EDPS, Up: WORKSPACE CONTROL edns ---- EDNS (library procedure) command. Abbreviates EDIT NAMES. *Note EDIT:: , *Note NAMES:: .  File: ucblogo.info, Node: EDPLS, Next: EDN, Prev: EDNS, Up: WORKSPACE CONTROL edpls ----- EDPLS (library procedure) command. Abbreviates EDIT PLISTS. *Note EDIT:: , *Note PLISTS:: .  File: ucblogo.info, Node: EDN, Next: EDPL, Prev: EDPLS, Up: WORKSPACE CONTROL edn --- EDN varname (library procedure) EDN varnamelist command. Abbreviates EDIT NAMELIST varname(list). *Note EDIT:: , *Note NAMELIST:: .  File: ucblogo.info, Node: EDPL, Next: SAVE, Prev: EDN, Up: WORKSPACE CONTROL edpl ---- EDPL plname (library procedure) EDPL plnamelist command. Abbreviates EDIT PLLIST plname(list). *Note EDIT:: , *Note PLLIST:: .  File: ucblogo.info, Node: SAVE, Next: SAVEL, Prev: EDPL, Up: WORKSPACE CONTROL save ---- SAVE filename command. Saves the definitions of all unburied procedures, variables, and nonempty property lists in the named file. Equivalent to to save :filename local "oldwriter make "oldwriter writer openwrite :filename setwrite :filename poall setwrite :oldwriter close :filename end  File: ucblogo.info, Node: SAVEL, Next: LOAD, Prev: SAVE, Up: WORKSPACE CONTROL savel ----- SAVEL contentslist filename (library procedure) command. Saves the definitions of the procedures, variables, and property lists specified by `contentslist' to the file named `filename'.  File: ucblogo.info, Node: LOAD, Next: CSLSLOAD, Prev: SAVEL, Up: WORKSPACE CONTROL load ---- LOAD filename command. Reads instructions from the named file and executes them. The file can include procedure definitions with TO, and these are accepted even if a procedure by the same name already exists. If the file assigns a list value to a variable named STARTUP, then that list is run as an instructionlist after the file is loaded. If there is a variable LOADNOISILY whose value is TRUE, then TO commands in the file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if LOADNOISILY is FALSE or undefined, TO commands in the file are carried out silently. *Note STARTUP:: , *Note LOADNOISILY:: .  File: ucblogo.info, Node: CSLSLOAD, Next: HELP, Prev: LOAD, Up: WORKSPACE CONTROL cslsload -------- CSLSLOAD name command. Loads the named file, like LOAD, but from the directory containing the Computer Science Logo Style programs instead of the current user's directory. *Note LOAD:: .  File: ucblogo.info, Node: HELP, Next: SETEDITOR, Prev: CSLSLOAD, Up: WORKSPACE CONTROL help ---- HELP name (HELP) command. Prints information from the reference manual about the primitive procedure named by the input. With no input, lists all the primitives about which help is available. If there is an environment variable LOGOHELP, then its value is taken as the directory in which to look for help files, instead of the default help directory. If HELP is called with the name of a defined procedure for which there is no help file, it will print the title line of the procedure followed by lines from the procedure body that start with semicolon, stopping when a non-semicolon line is seen. Exceptionally, the HELP command can be used without its default input and without parentheses provided that nothing follows it on the instruction line.  File: ucblogo.info, Node: SETEDITOR, Next: SETLIBLOC, Prev: HELP, Up: WORKSPACE CONTROL seteditor --------- SETEDITOR path command. Tells Logo to use the specified program as its editor instead of the default editor. The format of a path depends on your operating system.  File: ucblogo.info, Node: SETLIBLOC, Next: SETCSLSLOC, Prev: SETEDITOR, Up: WORKSPACE CONTROL setlibloc --------- SETLIBLOC path command. Tells Logo to use the specified directory as its library instead of the default. (Note that many Logo "primitive" procedures are actually found in the library, so they may become unavailable if your new library does not include them!) The format of a path depends on your operating system.  File: ucblogo.info, Node: SETCSLSLOC, Next: SETHELPLOC, Prev: SETLIBLOC, Up: WORKSPACE CONTROL setcslsloc ---------- SETCSLSLOC path command. Tells Logo to use the specified directory for the CSLSLOAD command, instead of the default directory. The format of a path depends on your operating system. *Note CSLSLOAD:: .  File: ucblogo.info, Node: SETHELPLOC, Next: SETTEMPLOC, Prev: SETCSLSLOC, Up: WORKSPACE CONTROL sethelploc ---------- SETHELPLOC path command. Tells Logo to look in the specified directory for the information provided by the HELP command, instead of the default directory. The format of a path depends on your operating system.  File: ucblogo.info, Node: SETTEMPLOC, Next: GC, Prev: SETHELPLOC, Up: WORKSPACE CONTROL settemploc ---------- SETTEMPLOC path command. Tells Logo to write editor temporary files in the specified directory rather than in the default directory. You must have write permission for this directory. The format of a path depends on your operating system.  File: ucblogo.info, Node: GC, Next: .SETSEGMENTSIZE, Prev: SETTEMPLOC, Up: WORKSPACE CONTROL gc -- GC (GC anything) command. Runs the garbage collector, reclaiming unused nodes. Logo does this when necessary anyway, but you may want to use this command to control exactly when Logo does it. In particular, the numbers output by the NODES operation will not be very meaningful unless garbage has been collected. Another reason to use GC is that a garbage collection takes a noticeable fraction of a second, and you may want to schedule collections for times before or after some time-critical animation. If invoked with an argument (of any value), GC runs a full garbage collection, including GCTWA (Garbage Collect Truly Worthless Atoms, which means that it removes from Logo's memory words that used to be procedure or variable names but aren't any more); without an argument, GC does a generational garbage collection, which means that only recently created nodes are examined. (The latter is usually good enough.)  File: ucblogo.info, Node: .SETSEGMENTSIZE, Prev: GC, Up: WORKSPACE CONTROL .setsegmentsize --------------- .SETSEGMENTSIZE num command. Sets the number of nodes that Logo allocates from the operating system at once to num, which mush be a positive integer. The name is dotted because bad things will happen if you use a number that's too small or too large for your computer. The initial value is 16,000 for most systems, but is smaller for 68000-based Macs. Making it larger will speed up computations (by reducing the number of garbage collections) at the cost of allocating more memory than necessary.  File: ucblogo.info, Node: CONTROL STRUCTURES, Next: MACROS, Prev: WORKSPACE MANAGEMENT, Up: Top Control Structures ****************** * Menu: * CONTROL:: * TEMPLATE-BASED ITERATION::  File: ucblogo.info, Node: CONTROL, Next: TEMPLATE-BASED ITERATION, Prev: CONTROL STRUCTURES, Up: CONTROL STRUCTURES Control ======= Note: in the following descriptions, an `instructionlist' can be a list or a word. In the latter case, the word is parsed into list form before it is run. Thus, RUN READWORD or RUN READLIST will work. The former is slightly preferable because it allows for a continued line (with ~) that includes a comment (with ;) on the first line. A `tf' input must be the word TRUE, the word FALSE, or a list. If it's a list, then it must be a Logo expression, which will be evaluated to produce a value that must be TRUE or FALSE. The comparisons with TRUE and FALSE are always case-insensitive. * Menu: * RUN:: * RUNRESULT:: * REPEAT:: * FOREVER:: * REPCOUNT:: * IF:: * IFELSE:: * TEST:: * IFTRUE:: * IFFALSE:: * STOP:: * OUTPUT:: * CATCH:: * THROW:: * ERROR:: * PAUSE:: * CONTINUE:: * WAIT:: * BYE:: * dMAYBEOUTPUT:: MAYBEOUTPUT * GOTO:: * TAG:: * IGNORE:: * back-quote:: * FOR:: * DOdWHILE:: DO.WHILE * WHILE:: * DOdUNTIL:: DO.UNTIL * UNTIL:: * CASE:: * COND::  File: ucblogo.info, Node: RUN, Next: RUNRESULT, Prev: CONTROL, Up: CONTROL run --- RUN instructionlist command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs. *Note READWORD:: , *Note READLIST:: .  File: ucblogo.info, Node: RUNRESULT, Next: REPEAT, Prev: RUN, Up: CONTROL runresult --------- RUNRESULT instructionlist runs the instructions in the input; outputs an empty list if those instructions produce no output, or a list whose only member is the output from running the input instructionlist. Useful for inventing command-or-operation control structures: local "result make "result runresult [something] if emptyp :result [stop] output first :result  File: ucblogo.info, Node: REPEAT, Next: FOREVER, Prev: RUNRESULT, Up: CONTROL repeat ------ REPEAT num instructionlist command. Runs the `instructionlist' repeatedly, `num' times.  File: ucblogo.info, Node: FOREVER, Next: REPCOUNT, Prev: REPEAT, Up: CONTROL forever ------- FOREVER instructionlist command. Runs the "instructionlist" repeatedly, until something inside the instructionlist (such as STOP or THROW) makes it stop. *Note STOP:: , *Note THROW:: .  File: ucblogo.info, Node: REPCOUNT, Next: IF, Prev: FOREVER, Up: CONTROL repcount -------- REPCOUNT outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs -1.  File: ucblogo.info, Node: IF, Next: IFELSE, Prev: REPCOUNT, Up: CONTROL if -- IF tf instructionlist (IF tf instructionlist1 instructionlist2) command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE. For compatibility with earlier versions of Logo, if an IF instruction is not enclosed in parentheses, but the first thing on the instruction line after the second input expression is a literal list (i.e., a list in square brackets), the IF is treated as if it were IFELSE, but a warning message is given. If this aberrant IF appears in a procedure body, the warning is given only the first time the procedure is invoked in each Logo session.  File: ucblogo.info, Node: IFELSE, Next: TEST, Prev: IF, Up: CONTROL ifelse ------ IFELSE tf instructionlist1 instructionlist2 command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value.  File: ucblogo.info, Node: TEST, Next: IFTRUE, Prev: IFELSE, Up: CONTROL test ---- TEST tf command. Remembers its input, which must be TRUE or FALSE, for use by later IFTRUE or IFFALSE instructions. The effect of TEST is local to the procedure in which it is used; any corresponding IFTRUE or IFFALSE must be in the same procedure or a subprocedure. *Note IFFALSE:: .  File: ucblogo.info, Node: IFTRUE, Next: IFFALSE, Prev: TEST, Up: CONTROL iftrue ------ IFTRUE instructionlist IFT instructionlist command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure.  File: ucblogo.info, Node: IFFALSE, Next: STOP, Prev: IFTRUE, Up: CONTROL iffalse ------- IFFALSE instructionlist IFF instructionlist command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure. *Note TEST:: .  File: ucblogo.info, Node: STOP, Next: OUTPUT, Prev: IFFALSE, Up: CONTROL stop ---- STOP command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value.  File: ucblogo.info, Node: OUTPUT, Next: CATCH, Prev: STOP, Up: CONTROL output ------ OUTPUT value OP value command. Ends the running of the procedure in which it appears. That procedure outputs the value `value' to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation.  File: ucblogo.info, Node: CATCH, Next: THROW, Prev: OUTPUT, Up: CONTROL catch ----- CATCH tag instructionlist command or operation. Runs its second input. Outputs if that instructionlist outputs. If, while running the instructionlist, a THROW instruction is executed with a tag equal to the first input (case-insensitive comparison), then the running of the instructionlist is terminated immediately. In this case the CATCH outputs if a value input is given to THROW. The `tag' must be a word. If the tag is the word ERROR, then any error condition that arises during the running of the instructionlist has the effect of THROW "ERROR instead of printing an error message and returning to toplevel. The CATCH does not output if an error is caught. Also, during the running of the instructionlist, the variable ERRACT is temporarily unbound. (If there is an error while ERRACT has a value, that value is taken as an instructionlist to be run after printing the error message. Typically the value of ERRACT, if any, is the list [PAUSE].) *Note ERROR:: , *Note ERRACT:: , *Note PAUSE:: . ucblogo-5.5/docs/ucblogo.info-40100644000161300001330000013160210276035443014337 0ustar bhdoeThis is ucblogo.info, produced by makeinfo version 4.5 from usermanual.texi.  File: ucblogo.info, Node: THROW, Next: ERROR, Prev: CATCH, Up: CONTROL throw ----- THROW tag (THROW tag value) command. Must be used within the scope of a CATCH with an equal tag. Ends the running of the instructionlist of the CATCH. If THROW is used with only one input, the corresponding CATCH does not output a value. If THROW is used with two inputs, the second provides an output for the CATCH. THROW "TOPLEVEL can be used to terminate all running procedures and interactive pauses, and return to the toplevel instruction prompt. Typing the system interrupt character (normally for Unix, for DOS, or for Mac) has the same effect. THROW "ERROR can be used to generate an error condition. If the error is not caught, it prints a message (THROW "ERROR) with the usual indication of where the error (in this case the THROW) occurred. If a second input is used along with a tag of ERROR, that second input is used as the text of the error message instead of the standard message. Also, in this case, the location indicated for the error will be, not the location of the THROW, but the location where the procedure containing the THROW was invoked. This allows user-defined procedures to generate error messages as if they were primitives. Note: in this case the corresponding CATCH "ERROR, if any, does not output, since the second input to THROW is not considered a return value. THROW "SYSTEM immediately leaves Logo, returning to the operating system, without printing the usual parting message and without deleting any editor temporary file written by EDIT. *Note EDIT:: .  File: ucblogo.info, Node: ERROR, Next: PAUSE, Prev: THROW, Up: CONTROL error ----- ERROR outputs a list describing the error just caught, if any. If there was not an error caught since the last use of ERROR, the empty list will be output. The error list contains four members: an integer code corresponding to the type of error, the text of the error message, the name of the procedure in which the error occurred, and the instruction line on which the error occurred.  File: ucblogo.info, Node: PAUSE, Next: CONTINUE, Prev: ERROR, Up: CONTROL pause ----- PAUSE command or operation. Enters an interactive pause. The user is prompted for instructions, as at toplevel, but with a prompt that includes the name of the procedure in which PAUSE was invoked. Local variables of that procedure are available during the pause. PAUSE outputs if the pause is ended by a CONTINUE with an input. If the variable ERRACT exists, and an error condition occurs, the contents of that variable are run as an instructionlist. Typically ERRACT is given the value [PAUSE] so that an interactive pause will be entered on the event of an error. This allows the user to check values of local variables at the time of the error. Typing the system quit character (normally for Unix, for DOS, or for Mac) will also enter a pause. *Note ERRACT:: .  File: ucblogo.info, Node: CONTINUE, Next: WAIT, Prev: PAUSE, Up: CONTROL continue -------- CONTINUE value CO value (CONTINUE) (CO) command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output. Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line.  File: ucblogo.info, Node: WAIT, Next: BYE, Prev: CONTINUE, Up: CONTROL wait ---- WAIT time command. Delays further execution for `time' 60ths of a second. Also causes any buffered characters destined for the terminal to be printed immediately. WAIT 0 can be used to achieve this buffer flushing without actually waiting.  File: ucblogo.info, Node: BYE, Next: dMAYBEOUTPUT, Prev: WAIT, Up: CONTROL bye --- BYE command. Exits from Logo; returns to the operating system.  File: ucblogo.info, Node: dMAYBEOUTPUT, Next: GOTO, Prev: BYE, Up: CONTROL .maybeoutput ------------ .MAYBEOUTPUT value (special form) works like OUTPUT except that the expression that provides the input value might not, in fact, output a value, in which case the effect is like STOP. This is intended for use in control structure definitions, for cases in which you don't know whether or not some expression produces a value. Example: to invoke :function [:inputs] 2 .maybeoutput apply :function :inputs end ? (invoke "print "a "b "c) a b c ? print (invoke "word "a "b "c) abc This is an alternative to RUNRESULT. It's fast and easy to use, at the cost of being an exception to Logo's evaluation rules. (Ordinarily, it should be an error if the expression that's supposed to provide an input to something doesn't have a value.) *Note OUTPUT:: , *Note STOP:: , *Note RUNRESULT:: .  File: ucblogo.info, Node: GOTO, Next: TAG, Prev: dMAYBEOUTPUT, Up: CONTROL goto ---- GOTO word command. Looks for a TAG command with the same input in the same procedure, and continues running the procedure from the location of that TAG. It is meaningless to use GOTO outside of a procedure.  File: ucblogo.info, Node: TAG, Next: IGNORE, Prev: GOTO, Up: CONTROL tag --- TAG quoted.word command. Does nothing. The input must be a literal word following a quotation mark ("), not the result of a computation. Tags are used by the GOTO command.  File: ucblogo.info, Node: IGNORE, Next: back-quote, Prev: TAG, Up: CONTROL ignore ------ IGNORE value (library procedure) command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant.  File: ucblogo.info, Node: back-quote, Next: FOR, Prev: IGNORE, Up: CONTROL ` - ` list (library procedure) outputs a list equal to its input but with certain substitutions. If a member of the input list is the word `,' (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word `,@' (comma atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the `,@' and the instructionlist. Example: show `[foo baz ,[bf [a b c]] garply ,@[bf [a b c]]] will print [foo baz [b c] garply b c] A word starting with `,' or `,@' is treated as if the rest of the word were a one-word list, e.g., `,:foo' is equivalent to `,[:Foo]'. A word starting with `",' (quote comma) or `:,' (colon comma) becomes a word starting with `"' or `:' but with the result of running the substitution (or its first word, if the result is a list) replacing what comes after the comma. Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found: ? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f] [a ` [b , [1+2] , [foo 4 d] e] f] ?make "name1 "x ?make "name2 "y ? show `[a `[b ,:,:name1 ,",:name2 d] e] [a ` [b , [:x] , ["y] d] e]  File: ucblogo.info, Node: FOR, Next: DOdWHILE, Prev: back-quote, Up: CONTROL for --- FOR forcontrol instructionlist (library procedure) command. The first input must be a list containing three or four members: (1) a word, which will be used as the name of a local variable; (2) a word or list that will be evaluated as by RUN to determine a number, the starting value of the variable; (3) a word or list that will be evaluated to determine a number, the limit value of the variable; (4) an optional word or list that will be evaluated to determine the step size. If the fourth member is missing, the step size will be 1 or -1 depending on whether the limit value is greater than or less than the starting value, respectively. The second input is an instructionlist. The effect of FOR is to run that instructionlist repeatedly, assigning a new value to the control variable (the one named by the first member of the forcontrol list) each time. First the starting value is assigned to the control variable. Then the value is compared to the limit value. FOR is complete when the sign of (current-limit) is the same as the sign of the step size. (If no explicit step size is provided, the instructionlist is always run at least once. An explicit step size can lead to a zero-trip FOR, e.g., FOR [I 1 0 1] ...). Otherwise, the instructionlist is run, then the step is added to the current value of the control variable and FOR returns to the comparison step. ? for [i 2 7 1.5] [print :i] 2 3.5 5 6.5 ? *Note RUN:: .  File: ucblogo.info, Node: DOdWHILE, Next: WHILE, Prev: FOR, Up: CONTROL do.while -------- DO.WHILE instructionlist tfexpression (library procedure) command. Repeatedly evaluates the `instructionlist' as long as the evaluated `tfexpression' remains TRUE. Evaluates the first input first, so the `instructionlist' is always run at least once. The `tfexpression' must be an expressionlist whose value when evaluated is TRUE or FALSE.  File: ucblogo.info, Node: WHILE, Next: DOdUNTIL, Prev: DOdWHILE, Up: CONTROL while ----- WHILE tfexpression instructionlist (library procedure) command. Repeatedly evaluates the `instructionlist' as long as the evaluated `tfexpression' remains TRUE. Evaluates the first input first, so the `instructionlist' may never be run at all. The `tfexpression' must be an expressionlist whose value when evaluated is TRUE or FALSE.  File: ucblogo.info, Node: DOdUNTIL, Next: UNTIL, Prev: WHILE, Up: CONTROL do.until -------- DO.UNTIL instructionlist tfexpression (library procedure) command. Repeatedly evaluates the `instructionlist' as long as the evaluated `tfexpression' remains FALSE. Evaluates the first input first, so the `instructionlist' is always run at least once. The `tfexpression' must be an expressionlist whose value when evaluated is TRUE or FALSE.  File: ucblogo.info, Node: UNTIL, Next: CASE, Prev: DOdUNTIL, Up: CONTROL until ----- UNTIL tfexpression instructionlist (library procedure) command. Repeatedly evaluates the `instructionlist' as long as the evaluated `tfexpression' remains FALSE. Evaluates the first input first, so the `instructionlist' may never be run at all. The `tfexpression' must be an expressionlist whose value when evaluated is TRUE or FALSE.  File: ucblogo.info, Node: CASE, Next: COND, Prev: UNTIL, Up: CONTROL case ---- CASE value clauses (library procedure) command or operation. The second input is a list of lists (clauses); each clause is a list whose first element is either a list of values or the word ELSE and whose butfirst is a Logo expression or instruction. CASE examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. If the first input to CASE is a member of the first element of a clause, then the butfirst of that clause is evaluated and CASE outputs its value, if any. If neither of these conditions is met, then CASE goes on to the next clause. If no clause is satisfied, CASE does nothing. Example: to vowelp :letter output case :letter [ [[a e i o u] "true] [else "false] ] end  File: ucblogo.info, Node: COND, Prev: CASE, Up: CONTROL cond ---- COND clauses (library procedure) command or operation. The input is a list of lists (clauses); each clause is a list whose first element is either an expression whose value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo expression or instruction. COND examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. Otherwise, the first element of the clause is evaluated; the resulting value must be TRUE or FALSE. If it's TRUE, then the butfirst of that clause is evaluated and COND outputs its value, if any. If the value is FALSE, then COND goes on to the next clause. If no clause is satisfied, COND does nothing. Example: to evens :numbers ; select even numbers from a list op cond [ [[emptyp :numbers] []] [[evenp first :numbers] ; assuming EVENP is defined fput first :numbers evens butfirst :numbers] [else evens butfirst :numbers] ] end  File: ucblogo.info, Node: TEMPLATE-BASED ITERATION, Prev: CONTROL, Up: CONTROL STRUCTURES Template-based Iteration ======================== The procedures in this section are iteration tools based on the idea of a `template.' This is a generalization of an instruction list or an expression list in which `slots' are provided for the tool to insert varying data. Four different forms of template can be used. The most commonly used form for a template is `explicit-slot' form, or `question mark' form. Example: ? show map [? * ?] [2 3 4 5] [4 9 16 25] ? In this example, the MAP tool evaluated the template [? * ?] repeatedly, with each of the members of the data list [2 3 4 5] substituted in turn for the question marks. The same value was used for every question mark in a given evaluation. Some tools allow for more than one datum to be substituted in parallel; in these cases the slots are indicated by ?1 for the first datum, ?2 for the second, and so on: ? show (map [(word ?1 ?2 ?1)] [a b c] [d e f]) [ada beb cfc] ? If the template wishes to compute the datum number, the form (? 1) is equivalent to ?1, so (? ?1) means the datum whose number is given in datum number 1. Some tools allow additional slot designations, as shown in the individual descriptions. The second form of template is the `named-procedure' form. If the template is a word rather than a list, it is taken as the name of a procedure. That procedure must accept a number of inputs equal to the number of parallel data slots provided by the tool; the procedure is applied to all of the available data in order. That is, if data ?1 through ?3 are available, the template "PROC is equivalent to [PROC ?1 ?2 ?3]. ? show (map "word [a b c] [d e f]) [ad be cf] ? to dotprod :a :b ; vector dot product op apply "sum (map "product :a :b) end The third form of template is `named-slot' or `lambda' form. This form is indicated by a template list containing more than one member, whose first member is itself a list. The first member is taken as a list of names; local variables are created with those names and given the available data in order as their values. The number of names must equal the number of available data. This form is needed primarily when one iteration tool must be used within the template list of another, and the ? notation would be ambiguous in the inner template. Example: to matmul :m1 :m2 [:tm2 transpose :m2] ; multiply two matrices output map [[row] map [[col] dotprod :row :col] :tm2] :m1 end The fourth form is `procedure text' form, a variant of lambda form. In this form, the template list contains at least two members, all of which are lists. This is the form used by the DEFINE and TEXT primitives, and APPLY accepts it so that the text of a defined procedure can be used as a template. Note: The fourth form of template is interpreted differently from the others, in that Logo considers it to be an independent defined procedure for the purposes of OUTPUT and STOP. For example, the following two instructions are identical: ? print apply [[x] :x+3] [5] 8 ? print apply [[x] [output :x+3]] [5] 8 although the first instruction is in named-slot form and the second is in procedure-text form. The named-slot form can be understood as telling Logo to evaluate the expression :x+3 in place of the entire invocation of apply, with the variable x temporarily given the value 5. The procedure-text form can be understood as invoking the procedure to foo :x output :x+3 end with input 5, but without actually giving the procedure a name. If the use of OUTPUT were interchanged in these two examples, we'd get errors: ? print apply [[x] output :x+3] [5] Can only use output inside a procedure ? print apply [[x] [:x+3]] [5] You don't say what to do with 8 The named-slot form can be used with STOP or OUTPUT inside a procedure, to stop the enclosing procedure. The following iteration tools are extended versions of the ones in Appendix B of the book _Computer_Science_Logo_Style,_Volume_3: _Advanced_Topics_ by Brian Harvey [MIT Press, 1987]. The extensions are primarily to allow for variable numbers of inputs. * Menu: * APPLY:: * INVOKE:: * FOREACH:: * MAP:: * MAPdSE:: MAP.SE * FILTER:: * FIND:: * REDUCE:: * CROSSMAP:: * CASCADE:: * CASCADEd2:: CASCADE.2 * TRANSFER::  File: ucblogo.info, Node: APPLY, Next: INVOKE, Prev: TEMPLATE-BASED ITERATION, Up: TEMPLATE-BASED ITERATION apply ----- APPLY template inputlist command or operation. Runs the "template," filling its slots with the members of `inputlist.' The number of members in `inputlist' must be an acceptable number of slots for `template.' It is illegal to apply the primitive TO as a template, but anything else is okay. APPLY outputs what `template' outputs, if anything. *Note TO:: .  File: ucblogo.info, Node: INVOKE, Next: FOREACH, Prev: APPLY, Up: TEMPLATE-BASED ITERATION invoke ------ INVOKE template input (library procedure) (INVOKE template input1 input2 ...) command or operation. Exactly like APPLY except that the inputs are provided as separate expressions rather than in a list.  File: ucblogo.info, Node: FOREACH, Next: MAP, Prev: INVOKE, Up: TEMPLATE-BASED ITERATION foreach ------- FOREACH data template (library procedure) (FOREACH data1 data2 ... template) command. Evaluates the template list repeatedly, once for each member of the data list. If more than one data list are given, each of them must be the same length. (The data inputs can be words, in which case the template is evaluated once for each character. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.  File: ucblogo.info, Node: MAP, Next: MAPdSE, Prev: FOREACH, Up: TEMPLATE-BASED ITERATION map --- MAP template data (library procedure) (MAP template data1 data2 ...) outputs a word or list, depending on the type of the data input, of the same length as that data input. (If more than one data input are given, the output is of the same type as data1.) Each member of the output is the result of evaluating the template list, filling the slots with the corresponding member(s) of the data input(s). (All data inputs must be the same length.) In the case of a word output, the results of the template evaluation must be words, and they are concatenated with WORD. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. *Note WORD:: .  File: ucblogo.info, Node: MAPdSE, Next: FILTER, Prev: MAP, Up: TEMPLATE-BASED ITERATION map.se ------ MAP.SE template data (library procedure) (MAP.SE template data1 data2 ...) outputs a list formed by evaluating the template list repeatedly and concatenating the results using SENTENCE. That is, the members of the output are the members of the results of the evaluations. The output list might, therefore, be of a different length from that of the data input(s). (If the result of an evaluation is the empty list, it contributes nothing to the final output.) The data inputs may be words or lists. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2. *Note SENTENCE:: .  File: ucblogo.info, Node: FILTER, Next: FIND, Prev: MAPdSE, Up: TEMPLATE-BASED ITERATION filter ------ FILTER tftemplate data (library procedure) outputs a word or list, depending on the type of the data input, containing a subset of the members (for a list) or characters (for a word) of the input. The template is evaluated once for each member or character of the data, and it must produce a TRUE or FALSE value. If the value is TRUE, then the corresponding input constituent is included in the output. ? print filter "vowelp "elephant eea ? In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.  File: ucblogo.info, Node: FIND, Next: REDUCE, Prev: FILTER, Up: TEMPLATE-BASED ITERATION find ---- FIND tftemplate data (library procedure) outputs the first constituent of the data input (the first member of a list, or the first character of a word) for which the value produced by evaluating the template with that consituent in its slot is TRUE. If there is no such constituent, the empty list is output. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.  File: ucblogo.info, Node: REDUCE, Next: CROSSMAP, Prev: FIND, Up: TEMPLATE-BASED ITERATION reduce ------ REDUCE template data (library procedure) outputs the result of applying the template to accumulate the members of the data input. The template must be a two-slot function. Typically it is an associative function name like "SUM. If the data input has only one constituent (member in a list or character in a word), the output is that consituent. Otherwise, the template is first applied with ?1 filled with the next-to-last consitient and ?2 with the last constituent. Then, if there are more constituents, the template is applied with ?1 filled with the next constituent to the left and ?2 with the result from the previous evaluation. This process continues until all constituents have been used. The data input may not be empty. Note: If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs: to max :a :b output ifelse :a > :b [:a] [:b] end print reduce "max [...] Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does: to max [:inputs] 2 if emptyp :inputs ~ [(throw "error [not enough inputs to max])] output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs end *Note SUM:: , *Note APPLY:: .  File: ucblogo.info, Node: CROSSMAP, Next: CASCADE, Prev: REDUCE, Up: TEMPLATE-BASED ITERATION crossmap -------- CROSSMAP template listlist (library procedure) (CROSSMAP template data1 data2 ...) outputs a list containing the results of template evaluations. Each data list contributes to a slot in the template; the number of slots is equal to the number of data list inputs. As a special case, if only one data list input is given, that list is taken as a list of data lists, and each of its members contributes values to a slot. CROSSMAP differs from MAP in that instead of taking members from the data inputs in parallel, it takes all possible combinations of members of data inputs, which need not be the same length. ? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4]) [a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4] ? For compatibility with the version in the first edition of CSLS (1), CROSSMAP templates may use the notation :1 instead of ?1 to indicate slots. *Note MAP:: . ---------- Footnotes ---------- (1) Computer Science Logo Style  File: ucblogo.info, Node: CASCADE, Next: CASCADEd2, Prev: CROSSMAP, Up: TEMPLATE-BASED ITERATION cascade ------- CASCADE endtest template startvalue (library procedure) (CASCADE endtest tmp1 sv1 tmp2 sv2 ...) (CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate) outputs the result of applying a template (or several templates, as explained below) repeatedly, with a given value filling the slot the first time, and the result of each application filling the slot for the following application. In the simplest case, CASCADE has three inputs. The second input is a one-slot expression template. That template is evaluated some number of times (perhaps zero). On the first evaluation, the slot is filled with the third input; on subsequent evaluations, the slot is filled with the result of the previous evaluation. The number of evaluations is determined by the first input. This can be either a nonnegative integer, in which case the template is evaluated that many times, or a predicate expression template, in which case it is evaluated (with the same slot filler that will be used for the evaluation of the second input) repeatedly, and the CASCADE evaluation continues as long as the predicate value is FALSE. (In other words, the predicate template indicates the condition for stopping.) If the template is evaluated zero times, the output from CASCADE is the third (startvalue) input. Otherwise, the output is the value produced by the last template evaluation. CASCADE templates may include the symbol # to represent the number of times the template has been evaluated. This slot is filled with 1 for the first evaluation, 2 for the second, and so on. ? show cascade 5 [lput # ?] [] [1 2 3 4 5] ? show cascade [vowelp first ?] [bf ?] "spring ing ? show cascade 5 [# * ?] 1 120 ? Several cascaded results can be computed in parallel by providing additional template-startvalue pairs as inputs to CASCADE. In this case, all templates (including the endtest template, if used) are multi-slot, with the number of slots equal to the number of pairs of inputs. In each round of evaluations, ?2 represents the result of evaluating the second template in the previous round. If the total number of inputs (including the first endtest input) is odd, then the output from CASCADE is the final value of the first template. If the total number of inputs is even, then the last input is a template that is evaluated once, after the end test is satisfied, to determine the output from CASCADE. to fibonacci :n output (cascade :n [?1 + ?2] 1 [?1] 0) end to piglatin :word output (cascade [vowelp first ?] ~ [word bf ? first ?] ~ :word ~ [word ? "ay]) end  File: ucblogo.info, Node: CASCADEd2, Next: TRANSFER, Prev: CASCADE, Up: TEMPLATE-BASED ITERATION cascade.2 --------- CASCADE.2 endtest temp1 startval1 temp2 startval2 (library procedure) outputs the result of invoking CASCADE with the same inputs. The only difference is that the default number of inputs is five instead of three.  File: ucblogo.info, Node: TRANSFER, Prev: CASCADEd2, Up: TEMPLATE-BASED ITERATION transfer -------- TRANSFER endtest template inbasket (library procedure) outputs the result of repeated evaluation of the template. The template is evaluated once for each member of the list `inbasket.' TRANSFER maintains an `outbasket' that is initially the empty list. After each evaluation of the template, the resulting value becomes the new outbasket. In the template, the symbol ?IN represents the current member from the inbasket; the symbol ?OUT represents the entire current outbasket. Other slot symbols should not be used. If the first (endtest) input is an empty list, evaluation continues until all inbasket members have been used. If not, the first input must be a predicate expression template, and evaluation continues until either that template's value is TRUE or the inbasket is used up.  File: ucblogo.info, Node: MACROS, Next: ERROR PROCESSING, Prev: CONTROL STRUCTURES, Up: Top Macros ****** * Menu: * dMACRO:: MACRO * dDEFMACRO:: DEFMACRO * MACROP:: * MACROEXPAND::  File: ucblogo.info, Node: dMACRO, Next: dDEFMACRO, Prev: MACROS, Up: MACROS .macro ------ .MACRO procname :input1 :input2 ... (special form) .DEFMACRO procname text A macro is a special kind of procedure whose output is evaluated as Logo instructions in the context of the macro's caller. .MACRO is exactly like TO except that the new procedure becomes a macro; .DEFMACRO is exactly like DEFINE with the same exception. Macros are useful for inventing new control structures comparable to REPEAT, IF, and so on. Such control structures can almost, but not quite, be duplicated by ordinary Logo procedures. For example, here is an ordinary procedure version of REPEAT: to my.repeat :num :instructions if :num=0 [stop] run :instructions my.repeat :num-1 :instructions end This version works fine for most purposes, e.g., my.repeat 5 [print "hello] But it doesn't work if the instructions to be carried out include OUTPUT, STOP, or LOCAL. For example, consider this procedure: to example print [Guess my secret word. You get three guesses.] repeat 3 [type "|?? | ~ if readword = "secret [pr "Right! stop]] print [Sorry, the word was "secret"!] end This procedure works as written, but if MY.REPEAT is used instead of REPEAT, it won't work because the STOP will stop MY.REPEAT instead of stopping EXAMPLE as desired. The solution is to make MY.REPEAT a macro. Instead of actually carrying out the computation, a macro must return a list containing Logo instructions. The contents of that list are evaluated as if they appeared in place of the call to the macro. Here's a macro version of REPEAT: .macro my.repeat :num :instructions if :num=0 [output []] output sentence :instructions ~ (list "my.repeat :num-1 :instructions) end Every macro is an operation -- it must always output something. Even in the base case, MY.REPEAT outputs an empty instruction list. To show how MY.REPEAT works, let's take the example my.repeat 5 [print "hello] For this example, MY.REPEAT will output the instruction list [print "hello my.repeat 4 [print "hello]] Logo then executes these instructions in place of the original invocation of MY.REPEAT; this prints `hello' once and invokes another repetition. The technique just shown, although fairly easy to understand, has the defect of slowness because each repetition has to construct an instruction list for evaluation. Another approach is to make my.repeat a macro that works just like the non-macro version unless the instructions to be repeated include OUTPUT or STOP: .macro my.repeat :num :instructions catch "repeat.catchtag ~ [op repeat.done runresult [repeat1 :num :instructions]] op [] end to repeat1 :num :instructions if :num=0 [throw "repeat.catchtag] run :instructions .maybeoutput repeat1 :num-1 :instructions end to repeat.done :repeat.result if emptyp :repeat.result [op [stop]] op list "output quoted first :repeat.result end If the instructions do not include STOP or OUTPUT, then REPEAT1 will reach its base case and invoke THROW. As a result, my.repeat's last instruction line will output an empty list, so the second evaluation of the macro result will do nothing. But if a STOP or OUTPUT happens, then REPEAT.DONE will output a STOP or OUTPUT instruction that will be re-executed in the caller's context. The macro-defining commands have names starting with a dot because macros are an advanced feature of Logo; it's easy to get in trouble by defining a macro that doesn't terminate, or by failing to construct the instruction list properly. Lisp users should note that Logo macros are NOT special forms. That is, the inputs to the macro are evaluated normally, as they would be for any other Logo procedure. It's only the output from the macro that's handled unusually. Here's another example: .macro localmake :name :value output (list "local~ word "" :name ~ "apply ~ ""make ~ (list :name :value)) end It's used this way: to try localmake "garply "hello print :garply end LOCALMAKE outputs the list [local "garply apply "make [garply hello]] The reason for the use of APPLY is to avoid having to decide whether or not the second input to MAKE requires a quotation mark before it. (In this case it would -- MAKE "GARPLY "HELLO -- but the quotation mark would be wrong if the value were a list.) It's often convenient to use the ` function to construct the instruction list: .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end On the other hand, ` is pretty slow, since it's tree recursive and written in Logo. *Note TO:: , *Note DEFINE:: , *Note APPLY:: , *Note STOP:: , *Note OUTPUT:: .  File: ucblogo.info, Node: dDEFMACRO, Next: MACROP, Prev: dMACRO, Up: MACROS .defmacro --------- *Note dMACRO:: .  File: ucblogo.info, Node: MACROP, Next: MACROEXPAND, Prev: dDEFMACRO, Up: MACROS macrop ------ MACROP name MACRO? name outputs TRUE if its input is the name of a macro.  File: ucblogo.info, Node: MACROEXPAND, Prev: MACROP, Up: MACROS macroexpand ----------- MACROEXPAND expr (library procedure) takes as its input a Logo expression that invokes a macro (that is, one that begins with the name of a macro) and outputs the the Logo expression into which the macro would translate the input expression. .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end ? show macroexpand [localmake "pi 3.14159] [local "pi apply "make [pi 3.14159]]  File: ucblogo.info, Node: ERROR PROCESSING, Next: SPECIAL VARIABLES, Prev: MACROS, Up: Top Error Processing **************** * Menu: * ERROR CODES:: If an error occurs, Logo takes the following steps. First, if there is an available variable named ERRACT, Logo takes its value as an instructionlist and runs the instructions. The operation ERROR may be used within the instructions (once) to examine the error condition. If the instructionlist invokes PAUSE, the error message is printed before the pause happens. Certain errors are "recoverable"; for one of those errors, if the instructionlist outputs a value, that value is used in place of the expression that caused the error. (If ERRACT invokes PAUSE and the user then invokes CONTINUE with an input, that input becomes the output from PAUSE and therefore the output from the ERRACT instructionlist.) It is possible for an ERRACT instructionlist to produce an inappropriate value or no value where one is needed. As a result, the same error condition could recur forever because of this mechanism. To avoid that danger, if the same error condition occurs twice in a row from an ERRACT instructionlist without user interaction, the message "Erract loop" is printed and control returns to toplevel. "Without user interaction" means that if ERRACT invokes PAUSE and the user provides an incorrect value, this loop prevention mechanism does not take effect and the user gets to try again. During the running of the ERRACT instructionlist, ERRACT is locally unbound, so an error in the ERRACT instructions themselves will not cause a loop. In particular, an error during a pause will not cause a pause-within-a-pause unless the user reassigns the value [PAUSE] to ERRACT during the pause. But such an error will not return to toplevel; it will remain within the original pause loop. If there is no available ERRACT value, Logo handles the error by generating an internal THROW "ERROR. (A user program can also generate an error condition deliberately by invoking THROW.) If this throw is not caught by a CATCH "ERROR in the user program, it is eventually caught either by the toplevel instruction loop or by a pause loop, which prints the error message. An invocation of CATCH "ERROR in a user program locally unbinds ERRACT, so the effect is that whichever of ERRACT and CATCH "ERROR is more local will take precedence. If a floating point overflow occurs during an arithmetic operation, or a two-input mathematical function (like POWER) is invoked with an illegal combination of inputs, the `doesn't like' message refers to the second operand, but should be taken as meaning the combination. *Note ERRACT:: , *Note THROW:: , *Note ERROR:: , *Note CATCH:: , *Note PAUSE:: , *Note CONTINUE:: .  File: ucblogo.info, Node: ERROR CODES, Prev: ERROR PROCESSING, Up: ERROR PROCESSING Error Codes =========== Here are the numeric codes that appear as the first member of the list output by ERROR when an error is caught, with the corresponding messages. Some messages may have two different codes depending on whether or not the error is recoverable (that is, a substitute value can be provided through the ERRACT mechanism) in the specific context. Some messages are warnings rather than errors; these will not be caught. Errors 0 and 32 are so bad that Logo exits immediately. 0 Fatal internal error (can't be caught) 1 Out of memory 2 Stack overflow 3 Turtle out of bounds 4 PROC doesn't like DATUM as input (not recoverable) 5 PROC didn't output to PROC 6 Not enough inputs to PROC 7 PROC doesn't like DATUM as input (recoverable) 8 Too much inside ()'s 9 You don't say what to do with DATUM 10 ')' not found 11 VAR has no value 12 Unexpected ')' 13 I don't know how to PROC (recoverable) 14 Can't find catch tag for THROWTAG 15 PROC is already defined 16 Stopped 17 Already dribbling 18 File system error 19 Assuming you mean IFELSE, not IF (warning only) 20 VAR shadowed by local in procedure call (warning only) 21 Throw "Error 22 PROC is a primitive 23 Can't use TO inside a procedure 24 I don't know how to PROC (not recoverable) 25 IFTRUE/IFFALSE without TEST 26 Unexpected ']' 27 Unexpected '}' 28 Couldn't initialize graphics 29 Macro returned VALUE instead of a list 30 You don't say what to do with VALUE 31 Can only use STOP or OUTPUT inside a procedure 32 APPLY doesn't like BADTHING as input 33 END inside multi-line instruction 34 Really out of memory (can't be caught)  File: ucblogo.info, Node: SPECIAL VARIABLES, Next: INTERNATIONALIZATION, Prev: ERROR PROCESSING, Up: Top Special Variables ***************** Logo takes special action if any of the following variable names exists. They follow the normal scoping rules, so a procedure can locally set one of them to limit the scope of its effect. Initially, no variables exist except for ALLOWGETSET, CASEIGNOREDP, and UNBURYONEDIT, which are TRUE and buried. * Menu: * ALLOWGETSET:: * CASEIGNOREDP:: * ERRACT:: * FULLPRINTP:: * LOADNOISILY:: * PRINTDEPTHLIMIT:: * PRINTWIDTHLIMIT:: * REDEFP:: * STARTUP:: * UNBURYONEDIT:: * USEALTERNATENAMES::  File: ucblogo.info, Node: ALLOWGETSET, Next: CASEIGNOREDP, Prev: SPECIAL VARIABLES, Up: SPECIAL VARIABLES allowgetset ----------- ALLOWGETSET (variable) if TRUE, indicates that an attempt to use a procedure that doesn't exist should be taken as an implicit getter or setter procedure (setter if the first three letters of the name are SET) for a variable of the same name (without the SET if appropriate).  File: ucblogo.info, Node: CASEIGNOREDP, Next: ERRACT, Prev: ALLOWGETSET, Up: SPECIAL VARIABLES caseignoredp ------------ CASEIGNOREDP (variable) if TRUE, indicates that lower case and upper case letters should be considered equal by EQUALP, BEFOREP, MEMBERP, etc. Logo initially makes this variable TRUE, and buries it. *Note EQUALP:: , *Note BEFOREP:: , *Note MEMBERP:: .  File: ucblogo.info, Node: ERRACT, Next: FULLPRINTP, Prev: CASEIGNOREDP, Up: SPECIAL VARIABLES erract ------ ERRACT (variable) an instructionlist that will be run in the event of an error. Typically has the value [PAUSE] to allow interactive debugging. *Note PAUSE:: .  File: ucblogo.info, Node: FULLPRINTP, Next: LOADNOISILY, Prev: ERRACT, Up: SPECIAL VARIABLES fullprintp ---------- FULLPRINTP if TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as `||'. (Otherwise it prints as nothing at all.)  File: ucblogo.info, Node: LOADNOISILY, Next: PRINTDEPTHLIMIT, Prev: FULLPRINTP, Up: SPECIAL VARIABLES loadnoisily ----------- LOADNOISILY (variable) if TRUE, prints the names of procedures defined when loading from a file (including the temporary file made by EDIT). *Note EDIT:: .  File: ucblogo.info, Node: PRINTDEPTHLIMIT, Next: PRINTWIDTHLIMIT, Prev: LOADNOISILY, Up: SPECIAL VARIABLES printdepthlimit --------------- PRINTDEPTHLIMIT (variable) if a nonnegative integer, indicates the maximum depth of sublist structure that will be printed by PRINT, etc. *Note PRINT:: .  File: ucblogo.info, Node: PRINTWIDTHLIMIT, Next: REDEFP, Prev: PRINTDEPTHLIMIT, Up: SPECIAL VARIABLES printwidthlimit --------------- PRINTWIDTHLIMIT (variable) if a nonnegative integer, indicates the maximum number of members in any one list that will be printed by PRINT, etc. *Note PRINT:: .  File: ucblogo.info, Node: REDEFP, Next: STARTUP, Prev: PRINTWIDTHLIMIT, Up: SPECIAL VARIABLES redefp ------ REDEFP (variable) if TRUE, allows primitives to be erased (ERASE) or redefined (COPYDEF). *Note ERASE:: , *Note COPYDEF:: .  File: ucblogo.info, Node: STARTUP, Next: UNBURYONEDIT, Prev: REDEFP, Up: SPECIAL VARIABLES startup ------- STARTUP (variable) if assigned a list value in a file loaded by LOAD, that value is run as an instructionlist after the loading. *Note LOAD:: .  File: ucblogo.info, Node: UNBURYONEDIT, Next: USEALTERNATENAMES, Prev: STARTUP, Up: SPECIAL VARIABLES unburyonedit ------------ UNBURYONEDIT (variable) if TRUE, causes any procedure defined during EDIT or LOAD to be unburied, so that it will be saved by a later SAVE. Files that want to define and bury procedures must do it in that order. *Note EDIT:: , *Note LOAD:: , *Note SAVE:: .  File: ucblogo.info, Node: USEALTERNATENAMES, Prev: UNBURYONEDIT, Up: SPECIAL VARIABLES usealternatenames ----------------- USEALTERNATENAMES (variable) if TRUE, causes Logo to generate non-English words (from the Messages file) instead of TRUE, FALSE, END, etc. ucblogo-5.5/docs/usermanual.texi0100644000161300001330000063354210276035376014755 0ustar bhdoe\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename ucblogo.info @settitle BERKELEY LOGO 5.5 @setchapternewpage odd @c %**end of header @iftex @vsize = 8.9 in @parskip = 7 pt @parindent = 0 pt @hyphenation{set-scrunch set-write-pos} @end iftex @ifinfo @paragraphindent 0 @end ifinfo @finalout @titlepage @title BERKELEY LOGO 5.5 @subtitle Berkeley Logo User Manual @author Brian Harvey @end titlepage @c Node, Next, Previous, Up @node Top, INTRODUCTION, (dir), (dir) @ifinfo This is a TeXinfo version of Berkeley Logo User Manual Original written by: Brian Harvey @end ifinfo @menu * INTRODUCTION:: * DATA STRUCTURE PRIMITIVES:: * COMMUNICATION:: * ARITHMETIC:: * LOGICAL OPERATIONS:: * GRAPHICS:: * WORKSPACE MANAGEMENT:: * CONTROL STRUCTURES:: * MACROS:: * ERROR PROCESSING:: * SPECIAL VARIABLES:: * INTERNATIONALIZATION:: * INDEX:: @end menu @c Node, Next, Previous, Up @node INTRODUCTION, DATA STRUCTURE PRIMITIVES, Top, Top @chapter Introduction @menu * OVERVIEW:: * GETTER/SETTER VARIBLE SYNTAX:: * ENTERING AND LEAVING LOGO:: * TOKENIZATION:: @end menu @c Node, Next, Previous, Up @node OVERVIEW, GETTER/SETTER VARIBLE SYNTAX, INTRODUCTION, INTRODUCTION @section Overview @cindex Copyright @cindex Computer_Science_Logo_Style Copyright @copyright{} 1993 by the Regents of the University of California This program 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but @var{WITHOUT ANY WARRANTY}; without even the implied warranty of @var{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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. This is a program that is still being written. Many things are missing, including adequate documentation. This manual assumes that you already know how to program in Logo, and merely presents the details of this new implementation. Read Computer_Science_Logo_Style, Volume_1:_ _Symbolic_Computing_ by Brian Harvey (MIT Press, 1997) for a tutorial on Logo programming with emphasis on symbolic computation. Here are the special features of this dialect of Logo: @display Source file compatible among Unix, DOS, Windows, and Mac platforms. Random-access arrays. Variable number of inputs to user-defined procedures. Mutators for list structure (dangerous). Pause on error, and other improvements to error handling. Comments and continuation lines; formatting is preserved when procedure definitions are saved or edited. Terrapin-style tokenization (e.g., [2+3] is a list with one member) but LCSI-style syntax (no special forms except TO). The best of both worlds. First-class instruction and expression templates (see APPLY). Macros. @end display Features @strong{not} found in Berkeley Logo include robotics, music, GUIs, animation, parallelism, and multimedia. For those, buy a commercial version. @node GETTER/SETTER VARIBLE SYNTAX, ENTERING AND LEAVING LOGO, OVERVIEW, INTRODUCTION @comment node-name, next, previous, up @section Getter/Setter Variable Syntax @cindex getter @cindex setter Logo distinguishes @var{PROCEDURES} from @var{VARIABLES}. A procedure is a set of instructions to carry out some computation; a variable is a named container that holds a data value such as a number, word, list, or array. In traditional Logo syntax, a non-numeric word typed without punctuation represents a request to invoke the procedure named by that word. A word typed with a preceding quotation mark represents the word itself. For example, in the instruction @example PRINT FIRST "WORD @end example the procedures named @code{FIRST} and @code{PRINT} are invoked, but the procedure named @var{WORD} is not invoked; the word @var{W-O-R-D} is the input to FIRST. What about variables? There are two things one can do with a variable: give it a value, and find out its value. To give a variable a value, Logo provides the primitive procedure @code{MAKE}, which requires two inputs: the name of the variable and the new value to be assigned. The first input, the name of the variable, is just a word, and if (as is almost always the case) the programmer wants to assign a value to a specific variable whose name is known in advance, that input is quoted, just as any known specific word would be: @example MAKE "MY.VAR FIRST "WORD @end example gives the variable named @var{MY.VAR} the value W (the first letter of WORD). To find the value of a variable, Logo provides the primitive procedure @code{THING}, which takes a variable name as its input, and outputs the value of the accessible variable with that name. Thus @example PRINT THING "MY.VAR @end example will print W (supposing the @code{MAKE} above has been done). Since finding the value of a specific, known variable name is such a common operation, Logo also provides an abbreviated notation that combines @code{THING} with quote: @example PRINT :MY.VAR @end example The colon (which Logo old-timers pronounce "dots") replaces @code{THING} and @code{"} in the earlier version of the instruction. Newcomers to Logo often complain about the need for all this punctuation. In particular, Logo programmers who learned about dots and quotes without also learning about @code{THING} wonder why an instruction such as @example MAKE "NEW.VAR :OLD.VAR @end example uses two different punctuation marks to identify the two variables. (Having read the paragraphs above, you will understand that actually both variable names are quoted, but the procedure @code{THING} is invoked to find the value of @var{OLD.VAR}, since it's that value, not @var{OLD.VAR}'s name, that @code{MAKE} needs to know. It wouldn't make sense to ask for @code{THING} of @var{NEW.VAR}, since we haven't given @var{NEW.VAR} a value yet.) Although Logo's punctuation rules make sense once understood, they do form a barrier to entry for the Logo beginner. Why, then, couldn't Logo be designed so that an unpunctuated word would represent a procedure if there is a procedure by that name, or a variable if there is a variable by that name? Then we could say @example PRINT MY.VAR @end example and Logo would realize that @var{MY.VAR} is the name of a variable, not of a procedure. The traditional reason not to use this convention is that Logo allows the same word to name a procedure and a variable at the same time. This is most often important for words that name data types, as in the following procedure: @example TO PLURAL :WORD OUTPUT WORD :WORD "S END @end example Here the name @var{WORD} is a natural choice for the input to @code{PLURAL}, since it describes the kind of input that @code{PLURAL} expects. Within the procedure, we use @code{WORD} to represent Logo's primitive procedure that combines two input words to form a new, longer word; we use @code{:WORD} to represent the variable containing the input, whatever actual word is given when PLURAL is invoked. @example ? PRINT PLURAL "COMPUTER COMPUTERS @end example However, if a Logo instruction includes an unquoted word that is @strong{not} the name of a procedure, Logo could look for a variable of that name instead. This would allow a "punctuationless" Logo, @strong{* PROVIDED THAT USERS WHO WANT TO WORK WITHOUT COLONS FOR VARIABLES CHOOSE VARIABLE NAMES THAT ARE NOT ALSO PROCEDURE NAMES. *} What about assigning a value to a variable? Could we do without the quotation mark on @code{MAKE}'s first input? Alas, no. Although the first input to @code{MAKE} is @strong{usually} a constant, known variable name, sometimes it isn't, as in this example: @example TO INCREMENT :VAR MAKE :VAR (THING :VAR)+1 ; Note: it's not "VAR here! END ? MAKE "X 5 ? INCREMENT "X ? PRINT :X 6 @end example The procedure @code{INCREMENT} takes a variable name as its input and changes the value of that variable. In this example there are two variables; the variable whose name is @var{VAR}, and whose value is the word X; and the variable whose name is @var{X} and whose value changes from 5 to 6. Suppose we changed the behavior of @code{MAKE} so that it took the word after @code{MAKE} as the name of the variable to change; we would be unable to write @code{INCREMENT}: @example TO INCREMENT :VAR ; nonworking! MAKE VAR (THING VAR)+1 END @end example This would assign a new value to @var{VAR}, not to @var{X}. What we can do is to allow an @strong{alternative} to @code{MAKE}, a "setter" procedure for a particular variable. The notation will be @example ? SETFOO 7 ? PRINT FOO 7 @end example @code{SETFOO} is a "setter procedure" that takes one input (in this case the input 7) and assigns its value to the variable named FOO. Berkeley Logo allows users to choose either the traditional notation, in which case the same name can be used both for a procedure and for a variable, or the getter/setter notation, in which variable @var{FOO} is set with @code{SETFOO} and examined with @var{FOO}, but the same name can't be used for procedure and variable. Here is how this choice is allowed: Berkeley Logo uses traditional notation, with procedures distinct from variables. However, if there is a variable named @var{AllowGetSet} whose value is TRUE (which there is, by default, when Logo starts up), then if a Logo instruction refers to a @strong{nonexistent} procedure (so that the error message "I don't know how to ..." would result), Logo tries the following two steps: @cindex AllowGetSet @display 1. If the name is at least four characters long, and the first three characters are the letters SET (upper or lower case), and if the name is followed in the instruction by another value, and if the name without the SET is the name of a variable that already exists, then Logo will invoke @code{MAKE} with its first input being the name without the SET, and its second input being the following value. 2. If step 1's conditions are not met, but the name is the name of an accessible variable, then Logo will invoke @code{THING} with that name as input, to find the variable's value. @end display Step 1 requires that the variable already exist so that misspellings of names of SETxxx primitives (e.g., @code{SETHEADING}) will still be caught, instead of silently creating a new variable. The command @code{GLOBAL} can be used to create a variable without giving it a value. One final point: The @code{TO} command in Logo has always been a special case; the rest of the line starting with TO is not evaluated as ordinary Logo expressions are. In particular, the colons used to mark the names of inputs to the procedure do not cause @code{THING} to be invoked. They are merely mnemonic aids, reminding the Logo user that these words are names of variables. (Arguably, this nonstantard behavior of TO adds to Logo beginners' confusion about colons.) To a programmer using colonless variable references, the colons in the TO line are unnecessary and meaningless. Berkeley Logo therefore makes the colons optional: @example TO FOO :IN1 :IN2 @end example and @example TO FOO IN1 IN2 @end example are both allowed. @node ENTERING AND LEAVING LOGO, TOKENIZATION, GETTER/SETTER VARIBLE SYNTAX, INTRODUCTION @section Entering and Leaving Logo @cindex starting @t{ucblogo} @cindex leaving @t{ucblogo} The process to start Logo depends on your operating system: @table @samp @item Unix: Type the word @t{logo} to the shell. (The directory in which you've installed Logo must be in your path.) @item DOS: Change directories to the one containing Logo (probably @var{C:\UCBLOGO}). Then type @t{UCBLOGO} for the large memory version, or @t{BL} for the 640K version. @item Mac: Double-click on the LOGO icon within the "UCB Logo" folder. @item Windows: Double-click on the UCBWLOGO icon in the UCBLOGO folder. @end table To leave Logo, enter the command @t{bye}. After initialization, Logo looks for a file in the current working directory named startup.lg and, if one is found, executes the Logo instructions in it. Then, under Unix, DOS, or Windows, if you include one or more filenames on the command line when starting Logo, those files will be loaded before the interpreter starts reading commands from your terminal. If you load a file that executes some program that includes a @code{BYE} command, Logo will run that program and exit. You can therefore write standalone programs in Logo and run them with shell/batch scripts. To support this technique, Logo does not print its usual welcoming and parting messages if you give file arguments to the logo command. If you type your interrupt character (see table below) Logo will stop what it's doing and return to top-level, as if you did @w{@t{THROW "TOPLEVEL}}. If you type your quit character Logo will pause as if you did PAUSE. @example Unix DOS/Windows Mac toplevel usually ctrl-C ctrl-Q command-. (period) pause usually ctrl-\ ctrl-W command-, (comma) @end example If you have an environment variable called @var{LOGOLIB} whose value is the name of a directory, then Logo will use that directory instead of the default library. If you invoke a procedure that has not been defined, Logo first looks for a file in the current directory named proc.lg where @code{proc} is the procedure name in lower case letters. If such a file exists, Logo loads that file. If the missing procedure is still undefined, or if there is no such file, Logo then looks in the library directory for a file named proc (no @code{.lg}) and, if it exists, loads it. If neither file contains a definition for the procedure, then Logo signals an error. Several procedures that are primitive in most versions of Logo are included in the default library, so if you use a different library you may want to include some or all of the default library in it. @node TOKENIZATION, , ENTERING AND LEAVING LOGO, INTRODUCTION @section Tokenization @cindex case-insensitive @cindex delimiters @cindex runparsing @cindex line-continuation @cindex comments Names of procedures, variables, and property lists are case-insensitive. So are the special words END, TRUE, and FALSE. Case of letters is preserved in everything you type, however. Within square brackets, words are delimited only by spaces and square brackets. [2+3] is a list containing one word. Note, however, that the Logo primitives that interpret such a list as a Logo instruction or expression (RUN, IF, etc.) reparse the list as if it had not been typed inside brackets. After a quotation mark outside square brackets, a word is delimited by a space, a square bracket, or a parenthesis. A word not after a quotation mark or inside square brackets is delimited by a space, a bracket, a parenthesis, or an infix operator @w{@t{+-*/=<>}}. Note that words following colons are in this category. Note that quote and colon are not delimiters. Each infix operator character is a word in itself, except that the two-character sequences @w{@t{<=}} @w{@t{>=}} and @w{@t{<>}} (the latter meaning not-equal) with no intervening space are recognized as a single word. A word consisting of a question mark followed by a number (e.g., ?37), when runparsed (i.e., where a procedure name is expected), is treated as if it were the sequence @example ( ? 37 ) @end example making the number an input to the ? procedure. (See the discussion of templates, below.) This special treatment does not apply to words read as data, to words with a non-number following the question mark, or if the question mark is backslashed. A line (an instruction line or one read by READLIST or READWORD) can be continued onto the following line if its last character is a tilde (~). READWORD preserves the tilde and the newline; READLIST does not. Lines read with READRAWLINE are never continued. An instruction line or a line read by READLIST (but not by READWORD) is automatically continued to the next line, as if ended with a tilde, if there are unmatched brackets, parentheses, braces, or vertical bars pending. However, it's an error if the continuation line contains only the word END; this is to prevent runaway procedure definitions. Lines explicitly continued with a tilde avoid this restriction. If a line being typed interactively on the keyboard is continued, either with a tilde or automatically, Logo will display a tilde as a prompt character for the continuation line. A semicolon begins a comment in an instruction line. Logo ignores characters from the semicolon to the end of the line. A tilde as the last character still indicates a continuation line, but not a continuation of the comment. For example, typing the instruction @example print "abc;comment ~ def @end example will print the word abcdef. Semicolon has no special meaning in data lines read by READWORD or READLIST, but such a line can later be reparsed using RUNPARSE and then comments will be recognized. The two-character sequence #! at the beginning of a line also starts a comment. Unix users can therefore write a file containing Logo commands, starting with the line @example #! /usr/local/bin/logo @end example (or wherever your Logo executable lives) and the file will be executable directly from the shell. To include an otherwise delimiting character (including semicolon or tilde) in a word, precede it with backslash (\). If the last character of a line is a backslash, then the newline character following the backslash will be part of the last word on the line, and the line continues onto the following line. To include a backslash in a word, use \\. If the combination backslash-newline is entered at the terminal, Logo will issue a backslash as a prompt character for the continuation line. All of this applies to data lines read with READWORD or READLIST as well as to instruction lines. A character entered with backslash is EQUALP to the same character without the backslash, but can be distinguished by the BACKSLASHEDP predicate. (However, BACKSLASHEDP recognizes backslashedness only on characters for which it is necessary: whitespace, parentheses, brackets, infix operators, backslash, vertical bar, tilde, quote, question mark, colon, and semicolon.) A line read with READRAWLINE has no special quoting mechanism; both backslash and vertical bar (described below) are just ordinary characters. An alternative notation to include otherwise delimiting characters in words is to enclose a group of characters in vertical bars. All characters between vertical bars are treated as if they were letters. In data read with READWORD the vertical bars are preserved in the resulting word. In data read with READLIST (or resulting from a PARSE or RUNPARSE of a word) the vertical bars do not appear explicitly; all potentially delimiting characters (including spaces, brackets, parentheses, and infix operators) appear as though entered with a backslash. Within vertical bars, backslash may still be used; the only characters that must be backslashed in this context are backslash and vertical bar themselves. Characters entered between vertical bars are forever special, even if the word or list containing them is later reparsed with PARSE or RUNPARSE. Characters typed after a backslash are treated somewhat differently: When a quoted word containing a backslashed character is runparsed, the backslashed character loses its special quality and acts thereafter as if typed normally. This distinction is important only if you are building a Logo expression out of parts, to be RUN later, and want to use parentheses. For example, @example PRINT RUN (SE "\( 2 "+ 3 "\)) @end example will print 5, but @example RUN (SE "MAKE ""|(| 2) @end example will create a variable whose name is open-parenthesis. (Each example would fail if vertical bars and backslashes were interchanged.) @node DATA STRUCTURE PRIMITIVES, COMMUNICATION, INTRODUCTION, Top @chapter Data Structure Primitives @menu * CONSTRUCTORS:: * SELECTORS:: * MUTATORS:: * PREDICATES:: * QUERIES:: @end menu @node CONSTRUCTORS, SELECTORS, DATA STRUCTURE PRIMITIVES, DATA STRUCTURE PRIMITIVES @section Constructors @menu * WORD:: * LIST:: * SENTENCE:: * FPUT:: * LPUT:: * ARRAY:: * MDARRAY:: * LISTTOARRAY:: * ARRAYTOLIST:: * COMBINE:: * REVERSE:: * GENSYM:: @end menu @node WORD, LIST, CONSTRUCTORS, CONSTRUCTORS @unnumberedsubsec word @cindex word @example WORD word1 word2 (WORD word1 word2 word3 ...) @end example outputs a word formed by concatenating its inputs. @node LIST, SENTENCE, WORD, CONSTRUCTORS @unnumberedsubsec list @cindex list @example LIST thing1 thing2 (LIST thing1 thing2 thing3 ...) @end example outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array). @node SENTENCE, FPUT, LIST, CONSTRUCTORS @unnumberedsubsec sentence @cindex sentence @cindex se @example SENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...) @end example outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists. @node FPUT, LPUT, SENTENCE, CONSTRUCTORS @unnumberedsubsec fput @cindex fput @example FPUT thing list @end example outputs a list equal to its second input with one extra member, the first input, at the beginning. If the second input is a word, then the first input must be a one-letter word, and FPUT is equivalent to WORD. @node LPUT, ARRAY, FPUT, CONSTRUCTORS @unnumberedsubsec lput @cindex lput @example LPUT thing list @end example outputs a list equal to its second input with one extra member, the first input, at the end. If the second input is a word, then the first input must be a one-letter word, and LPUT is equivalent to WORD with its inputs in the other order. @node ARRAY, MDARRAY, LPUT, CONSTRUCTORS @unnumberedsubsec array @cindex array @example ARRAY size (ARRAY size origin) @end example outputs an array of @code{size} members (must be a positive integer), each of which initially is an empty list. Array members can be selected with ITEM and changed with SETITEM. The first member of the array is member number 1 unless an @code{origin} input (must be an integer) is given, in which case the first member of the array has that number as its index. (Typically 0 is used as the origin if anything.) Arrays are printed by PRINT and friends, and can be typed in, inside curly braces; indicate an origin with @w{@t{@{a b c@}@@0}}. @xref{ITEM} , @ref{SETITEM} , @ref{PRINT} . @node MDARRAY, LISTTOARRAY, ARRAY, CONSTRUCTORS @unnumberedsubsec mdarray @cindex mdarray @example MDARRAY sizelist (library procedure) (MDARRAY sizelist origin) @end example outputs a multi-dimensional array. The first input must be a list of one or more positive integers. The second input, if present, must be a single integer that applies to every dimension of the array. Ex: @w{@t{(MDARRAY [3 5] 0)}} outputs a two-dimensional array whose members range from @w{[0 0]} to @w{[2 4]}. @node LISTTOARRAY, ARRAYTOLIST, MDARRAY, CONSTRUCTORS @unnumberedsubsec listtoarray @cindex listtoarray @example LISTTOARRAY list (LISTTOARRAY list origin) @end example outputs an array of the same size as the input list, whose members are the members of the input list. @node ARRAYTOLIST, COMBINE, LISTTOARRAY, CONSTRUCTORS @unnumberedsubsec arraytolist @cindex arraytolist @example ARRAYTOLIST array @end example outputs a list whose members are the members of the input array. The first member of the output is the first member of the array, regardless of the array's origin. @node COMBINE, REVERSE, ARRAYTOLIST, CONSTRUCTORS @unnumberedsubsec combine @cindex combine @example COMBINE thing1 thing2 (library procedure) @end example if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2. @xref{WORD} , @ref{FPUT} @node REVERSE, GENSYM, COMBINE, CONSTRUCTORS @unnumberedsubsec reverse @cindex reverse @example REVERSE list (library procedure) @end example outputs a list whose members are the members of the input list, in reverse order. @node GENSYM, , REVERSE, CONSTRUCTORS @unnumberedsubsec gensym @cindex gensym @example GENSYM (library procedure) @end example outputs a unique word each time it's invoked. The words are of the form G1, G2, etc. @node SELECTORS, MUTATORS, CONSTRUCTORS, DATA STRUCTURE PRIMITIVES @section Data Selectors @menu * FIRST:: * FIRSTS:: * LAST:: * BUTFIRST:: * BUTFIRSTS:: * BUTLAST:: * ITEM:: * MDITEM:: * PICK:: * REMOVE:: * REMDUP:: * QUOTED:: @end menu @node FIRST, FIRSTS, SELECTORS, SELECTORS @unnumberedsubsec first @cindex first @example FIRST thing @end example if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array). @node FIRSTS, LAST, FIRST, SELECTORS @unnumberedsubsec firsts @cindex firsts @example FIRSTS list @end example outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as @example to firsts :list output map "first :list end @end example but is provided as a primitive in order to speed up the iteration tools @t{MAP}, @t{MAP.SE}, and @t{FOREACH}. @example to transpose :matrix if emptyp first :matrix [op []] op fput firsts :matrix transpose bfs :matrix end @end example @xref{MAP} , @ref{MAPdSE} , @ref{FOREACH} @node LAST, BUTFIRST, FIRSTS, SELECTORS @unnumberedsubsec last @cindex last @example LAST wordorlist @end example if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list. @node BUTFIRST, BUTFIRSTS, LAST, SELECTORS @unnumberedsubsec butfirst @cindex butfirst @cindex bf @example BUTFIRST wordorlist BF wordorlist @end example if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input. @node BUTFIRSTS, BUTLAST, BUTFIRST, SELECTORS @unnumberedsubsec butfirsts @cindex butfirsts @cindex bfs @example BUTFIRSTS list BFS list @end example outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as @example to butfirsts :list output map "butfirst :list end @end example but is provided as a primitive in order to speed up the iteration tools @t{MAP}, @t{MAP.SE}, and @t{FOREACH}. @xref{MAP} , @ref{MAPdSE} , @ref{FOREACH} @node BUTLAST, ITEM, BUTFIRSTS, SELECTORS @unnumberedsubsec butlast @cindex butlast @cindex bl @example BUTLAST wordorlist BL wordorlist @end example if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input. @node ITEM, MDITEM, BUTLAST, SELECTORS @unnumberedsubsec item @cindex item @example ITEM index thing @end example if the @code{thing} is a word, outputs the @code{index}th character of the word. If the @code{thing} is a list, outputs the @code{index}th member of the list. If the @code{thing} is an array, outputs the @code{index}th member of the array. @code{Index} starts at 1 for words and lists; the starting index of an array is specified when the array is created. @node MDITEM, PICK, ITEM, SELECTORS @unnumberedsubsec mditem @cindex mditem @example MDITEM indexlist array (library procedure) @end example outputs the member of the multidimensional @code{array} selected by the list of numbers @code{indexlist}. @node PICK, REMOVE, MDITEM, SELECTORS @unnumberedsubsec pick @cindex pick @example PICK list (library procedure) @end example outputs a randomly chosen member of the input list. @node REMOVE, REMDUP, PICK, SELECTORS @unnumberedsubsec remove @cindex remove @example REMOVE thing list (library procedure) @end example outputs a copy of @code{list} with every member equal to @code{thing} removed. @node REMDUP, QUOTED, REMOVE, SELECTORS @unnumberedsubsec remdup @cindex remdup @example REMDUP list (library procedure) @end example outputs a copy of @code{list} with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output. @node QUOTED, , REMDUP, SELECTORS @unnumberedsubsec quoted @cindex quoted @example QUOTED thing (library procedure) @end example outputs its input, if a list; outputs its input with a quotation mark prepended, if a word. @node MUTATORS, PREDICATES, SELECTORS, DATA STRUCTURE PRIMITIVES @section Data Mutators @menu * SETITEM:: * MDSETITEM:: * dSETFIRST:: SETFIRST * dSETBF:: SETBF * dSETITEM:: SETITEM * PUSH:: * POP:: * QUEUE:: * DEQUEUE:: @end menu @node SETITEM, MDSETITEM, MUTATORS, MUTATORS @unnumberedsubsec setitem @cindex setitem @example SETITEM index array value @end example command. Replaces the @code{index}th member of @code{array} with the new @code{value}. Ensures that the resulting array is not circular, i.e., @code{value} may not be a list or array that contains @code{array}. @node MDSETITEM, dSETFIRST, SETITEM, MUTATORS @unnumberedsubsec mdsetitem @cindex mdsetitem @example MDSETITEM indexlist array value (library procedure) @end example command. Replaces the member of @code{array} chosen by @code{indexlist} with the new @code{value}. @node dSETFIRST, dSETBF, MDSETITEM, MUTATORS @unnumberedsubsec .setfirst @cindex .setfirst @example .SETFIRST list value @end example command. Changes the first member of @code{list} to be @code{value}. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; and the loss of memory if a circular structure is released. @node dSETBF, dSETITEM, dSETFIRST, MUTATORS @unnumberedsubsec .setbf @cindex .setbf @example .SETBF list value @end example command. Changes the butfirst of @code{list} to be @code{value}. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified; Logo crashes and coredumps if the butfirst of a list is not itself a list; and the loss of memory if a circular structure is released. @node dSETITEM, PUSH, dSETBF, MUTATORS @unnumberedsubsec .setitem @cindex .setitem @example .SETITEM index array value @end example command. Changes the @code{index}th member of @code{array} to be @code{value}, like SETITEM, but without checking for circularity. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETITEM can lead to circular arrays, which will get some Logo primitives into infinite loops; and the loss of memory if a circular structure is released. @xref{SETITEM}. @node PUSH, POP, dSETITEM, MUTATORS @unnumberedsubsec push @cindex push @example PUSH stackname thing (library procedure) @end example command. Adds the @code{thing} to the stack that is the value of the variable whose name is @code{stackname}. This variable must have a list as its value; the initial value should be the empty list. New members are added at the front of the list. @node POP, QUEUE, PUSH, MUTATORS @unnumberedsubsec pop @cindex pop @example POP stackname (library procedure) @end example outputs the most recently PUSHed member of the stack that is the value of the variable whose name is @code{stackname} and removes that member from the stack. @node QUEUE, DEQUEUE, POP, MUTATORS @unnumberedsubsec queue @cindex queue @example QUEUE queuename thing (library procedure) @end example command. Adds the @code{thing} to the queue that is the value of the variable whose name is @code{queuename}. This variable must have a list as its value; the initial value should be the empty list. New members are added at the back of the list. @node DEQUEUE, , QUEUE, MUTATORS @unnumberedsubsec dequeue @cindex dequeue @example DEQUEUE queuename (library procedure) @end example outputs the least recently QUEUEd member of the queue that is the value of the variable whose name is @code{queuename} and removes that member from the queue. @node PREDICATES, QUERIES, MUTATORS, DATA STRUCTURE PRIMITIVES @section Predicates @menu * WORDP:: * LISTP:: * ARRAYP:: * EMPTYP:: * EQUALP:: * NOTEQUALP:: * BEFOREP:: * dEQ:: EQ * MEMBERP:: * SUBSTRINGP:: * NUMBERP:: * BACKSLASHEDP:: @end menu @node WORDP, LISTP, PREDICATES, PREDICATES @unnumberedsubsec wordp @cindex wordp @example WORDP thing WORD? thing @end example outputs TRUE if the input is a word, FALSE otherwise. @node LISTP, ARRAYP, WORDP, PREDICATES @unnumberedsubsec listp @cindex listp @cindex list? @example LISTP thing LIST? thing @end example outputs TRUE if the input is a list, FALSE otherwise. @node ARRAYP, EMPTYP, LISTP, PREDICATES @unnumberedsubsec arrayp @cindex arrayp @cindex array? @example ARRAYP thing ARRAY? thing @end example outputs TRUE if the input is an array, FALSE otherwise. @node EMPTYP, EQUALP, ARRAYP, PREDICATES @unnumberedsubsec emptyp @cindex emptyp @cindex empty? @example EMPTYP thing EMPTY? thing @end example outputs TRUE if the input is the empty word or the empty list, FALSE otherwise. @node EQUALP, NOTEQUALP, EMPTYP, PREDICATES @unnumberedsubsec equalp @cindex equalp @cindex equal? @cindex = @example EQUALP thing1 thing2 EQUAL? thing1 thing2 thing1 = thing2 @end example outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named @var{CASEIGNOREDP} whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.) @xref{CASEIGNOREDP} , @ref{SETITEM} @node NOTEQUALP, BEFOREP, EQUALP, PREDICATES @unnumberedsubsec notequalp @cindex notequalp @cindex notequal? @cindex <> @example NOTEQUALP thing1 thing2 NOTEQUAL? thing1 thing2 thing1 <> thing2 @end example outputs FALSE if the inputs are equal, TRUE otherwise. See EQUALP for the meaning of equality for different data types. @node BEFOREP, dEQ, NOTEQUALP, PREDICATES @unnumberedsubsec beforep @cindex beforep @cindex before? @example BEFOREP word1 word2 BEFORE? word1 word2 @end example outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, @w{@t{BEFOREP 3 12}} is false because 3 collates after 1. @xref{CASEIGNOREDP} , @ref{LESSP} @node dEQ, MEMBERP, BEFOREP, PREDICATES @unnumberedsubsec .eq @cindex .eq @example .EQ thing1 thing2 @end example outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of mutators can lead to circular data structures, infinite loops, or Logo crashes. @node MEMBERP, SUBSTRINGP, dEQ, PREDICATES @unnumberedsubsec memberp @cindex memberp @cindex member? @example MEMBERP thing1 thing2 MEMBER? thing1 thing2 @end example if @code{thing2} is a list or an array, outputs TRUE if @code{thing1} is EQUALP to a member of @code{thing2}, FALSE otherwise. If @code{thing2} is a word, outputs TRUE if @code{thing1} is a one-character word EQUALP to a character of @code{thing2}, FALSE otherwise. @xref{EQUALP} . @node SUBSTRINGP, NUMBERP, MEMBERP, PREDICATES @unnumberedsubsec substringp @cindex substringp @cindex substring? @example SUBSTRINGP thing1 thing2 SUBSTRING? thing1 thing2 @end example if @code{thing1} or @code{thing2} is a list or an array, outputs FALSE. If @code{thing2} is a word, outputs TRUE if @code{thing1} is EQUALP to a substring of @code{thing2}, FALSE otherwise. @xref{EQUALP} . @node NUMBERP, BACKSLASHEDP, SUBSTRINGP, PREDICATES @unnumberedsubsec numberp @cindex numberp @cindex number? @example NUMBERP thing NUMBER? thing @end example outputs TRUE if the input is a number, FALSE otherwise. @node BACKSLASHEDP, , NUMBERP, PREDICATES @unnumberedsubsec backslashedp @cindex backslashedp @cindex backslashed? @example BACKSLASHEDP char BACKSLASHED? char @end example outputs TRUE if the input character was originally entered into Logo with a backslash (\) before it or within vertical bars (|) to prevent its usual special syntactic meaning, FALSE otherwise. (Outputs TRUE only if the character is a backslashed space, tab, newline, or one of @w{@t{()[]+-*/=<>":;\~?|}} ) @node QUERIES, , PREDICATES, DATA STRUCTURE PRIMITIVES @section Queries @menu * COUNT:: * ASCII:: * RAWASCII:: * CHAR:: * MEMBER:: * LOWERCASE:: * UPPERCASE:: * STANDOUT:: * PARSE:: * RUNPARSE:: @end menu @node COUNT, ASCII, QUERIES, QUERIES @unnumberedsubsec count @cindex count @example COUNT thing @end example outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.) @node ASCII, RAWASCII, COUNT, QUERIES @unnumberedsubsec ascii @cindex ascii @example ASCII char @end example outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing backslashed punctuation, and returns the character code for the corresponding punctuation character without backslash. (Compare RAWASCII.) @node RAWASCII, CHAR, ASCII, QUERIES @unnumberedsubsec rawascii @cindex rawascii @example RAWASCII char @end example outputs the integer (between 0 and 255) that represents the input character in the ASCII code. Interprets control characters as representing themselves. To find out the ASCII code of an arbitrary keystroke, use @w{@t{RAWASCII RC}}. @node CHAR, MEMBER, RAWASCII, QUERIES @unnumberedsubsec char @cindex char @example CHAR int @end example outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255. @xref{ASCII} . @node MEMBER, LOWERCASE, CHAR, QUERIES @unnumberedsubsec member @cindex member @example MEMBER thing1 thing2 @end example if @code{thing2} is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of @code{thing2} from the first instance of @code{thing1} to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of @code{thing2}. It is an error for @code{thing2} to be an array. @xref{MEMBERP} . @node LOWERCASE, UPPERCASE, MEMBER, QUERIES @unnumberedsubsec lowercase @cindex lowercase @example LOWERCASE word @end example outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter. @node UPPERCASE, STANDOUT, LOWERCASE, QUERIES @unnumberedsubsec uppercase @cindex uppercase @example UPPERCASE word @end example outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter. @node STANDOUT, PARSE, UPPERCASE, QUERIES @unnumberedsubsec standout @cindex standout @example STANDOUT thing @end example outputs a word that, when printed, will appear like the input but displayed in standout mode (boldface, reverse video, or whatever your terminal does for standout). The word contains terminal-specific magic characters at the beginning and end; in between is the printed form (as if displayed using TYPE) of the input. The output is always a word, even if the input is of some other type, but it may include spaces and other formatting characters. Note: a word output by STANDOUT while Logo is running on one terminal will probably not have the desired effect if printed on another type of terminal. On the Macintosh, the way that standout works is incompatible with the use of characters whose ASCII code is greater than 127. Therefore, you have a choice to make: The instruction @example CANINVERSE 0 @end example disables standout, but enables the display of ASCII codes above 127, and the instruction @example CANINVERSE 1 @end example restores the default situation in which standout is enabled and the extra graphic characters cannot be printed. @node PARSE, RUNPARSE, STANDOUT, QUERIES @unnumberedsubsec parse @cindex parse @example PARSE word @end example outputs the list that would result if the input word were entered in response to a READLIST operation. That is, @w{@t{PARSE READWORD}} has the same value as READLIST for the same characters read. @xref{READLIST} , @ref{READWORD} @node RUNPARSE, , PARSE, QUERIES @unnumberedsubsec runparse @cindex runparse @example RUNPARSE wordorlist @end example outputs the list that would result if the input word or list were entered as an instruction line; characters such as infix operators and parentheses are separate members of the output. Note that sublists of a runparsed list are not themselves runparsed. @node COMMUNICATION, ARITHMETIC, DATA STRUCTURE PRIMITIVES, Top @chapter Communication @menu * TRANSMITTERS:: * RECEIVERS:: * FILE ACCESS:: * TERMINAL ACCESS:: @end menu @node TRANSMITTERS, RECEIVERS, COMMUNICATION, COMMUNICATION @section Transmitters @menu * PRINT:: * TYPE:: * SHOW:: @end menu Note: If there is a variable named @var{PRINTDEPTHLIMIT} with a nonnegative integer value, then complex list and array structures will be printed only to the allowed depth. That is, members of members of... of members will be allowed only so far. The members omitted because they are just past the depth limit are indicated by an ellipsis for each one, so a too-deep list of two members will print as [@dots{} @dots{}]. If there is a variable named @var{PRINTWIDTHLIMIT} with a nonnegative integer value, then only the first so many members of any array or list will be printed. A single ellipsis replaces all missing data within the structure. The width limit also applies to the number of characters printed in a word, except that a @var{PRINTWIDTHLIMIT} between 0 and 9 will be treated as if it were 10 when applied to words. This limit applies not only to the top-level printed datum but to any substructures within it. @xref{PRINTDEPTHLIMIT} , @ref{PRINTWIDTHLIMIT} If there is a variable named @var{FULLPRINTP} whose value is TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as ||. (Otherwise it prints as nothing at all.) @xref{FULLPRINTP} . @node PRINT, TYPE, TRANSMITTERS, TRANSMITTERS @unnumberedsubsec print @cindex print @cindex pr @example PRINT thing PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...) @end example command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays. @node TYPE, SHOW, PRINT, TRANSMITTERS @unnumberedsubsec type @cindex type @example TYPE thing (TYPE thing1 thing2 ...) @end example command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces. Note: printing to the terminal is ordinarily "line buffered"; that is, the characters you print using TYPE will not actually appear on the screen until either a newline character is printed (for example, by PRINT or SHOW) or Logo tries to read from the keyboard (either at the request of your program or after an instruction prompt). This buffering makes the program much faster than it would be if each character appeared immediately, and in most cases the effect is not disconcerting. To accommodate programs that do a lot of positioned text display using TYPE, Logo will force printing whenever SETCURSOR is invoked. This solves most buffering problems. Still, on occasion you may find it necessary to force the buffered characters to be printed explicitly; this can be done using the WAIT command. @w{@t{WAIT 0}} will force printing without actually waiting. @xref{SETCURSOR} , @ref{WAIT} @node SHOW, , TYPE, TRANSMITTERS @unnumberedsubsec show @cindex show @example SHOW thing (SHOW thing1 thing2 ...) @end example command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets. @xref{PRINT} . @node RECEIVERS, FILE ACCESS, TRANSMITTERS, COMMUNICATION @section Receivers @menu * READLIST:: * READWORD:: * READRAWLINE:: * READCHAR:: * READCHARS:: * SHELL:: @end menu @node READLIST, READWORD, RECEIVERS, RECEIVERS @unnumberedsubsec readlist @cindex readlist @cindex rl @example READLIST RL @end example reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character. @node READWORD, READRAWLINE, READLIST, RECEIVERS @unnumberedsubsec readword @cindex readword @cindex rw @example READWORD RW @end example reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READWORD outputs the empty list (not the empty word). READWORD processes backslash, vertical bar, and tilde characters in the read stream. In the case of a tilde used for line continuation, the output word DOES include the tilde and the newline characters, so that the user program can tell exactly what the user entered. Vertical bars in the line are also preserved in the output. Backslash characters are not preserved in the output, but the character following the backslash has 128 added to its representation. Programs can use BACKSLASHEDP to check for this code. (Backslashedness is preserved only for certain characters.) @xref{BACKSLASHEDP} . @node READRAWLINE, READCHAR, READWORD, RECEIVERS @comment node-name, next, previous, up @unnumberedsubsec readrawline @cindex readrawline @example READRAWLINE @end example reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters. @xref{READWORD} . @node READCHAR, READCHARS, READRAWLINE, RECEIVERS @unnumberedsubsec readchar @cindex readchar @cindex rc @example READCHAR RC @end example reads a single character from the read stream and outputs that character as a word. If the read stream is a file, and the end of file is reached, READCHAR outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHAR is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. @xref{READLIST} . @node READCHARS, SHELL, READCHAR, RECEIVERS @unnumberedsubsec readchars @cindex readchars @cindex rcs @example READCHARS num RCS num @end example reads @code{num} characters from the read stream and outputs those characters as a word. If the read stream is a file, and the end of file is reached, READCHARS outputs the empty list (not the empty word). If the read stream is a terminal, echoing is turned off when READCHARS is invoked, and remains off until READLIST or READWORD is invoked or a Logo prompt is printed. Backslash, vertical bar, and tilde characters have no special meaning in this context. @xref{READLIST} , @ref{READWORD} @node SHELL, , READCHARS, RECEIVERS @unnumberedsubsec shell @cindex shell @example SHELL command (SHELL command wordflag) @end example Under Unix, outputs the result of running @code{command} as a shell command. (The command is sent to @samp{/bin/sh}, not @samp{csh} or other alternatives.) If the command is a literal list in the instruction line, and if you want a backslash character sent to the shell, you must use \\ to get the backslash through Logo's reader intact. The output is a list containing one member for each line generated by the shell command. Ordinarily each such line is represented by a list in the output, as though the line were read using READLIST. If a second input is given, regardless of the value of the input, each line is represented by a word in the output as though it were read with READWORD. Example: @example to dayofweek output first first shell [date] end @end example This is "first first" to extract the first word of the first (and only) line of the shell output. Under DOS, SHELL is a command, not an operation; it sends its input to a DOS command processor but does not collect the result of the command. The Macintosh, of course, is not programmable (unless you are running the Unix version of UCBLogo under OS X). @node FILE ACCESS, TERMINAL ACCESS, RECEIVERS, COMMUNICATION @section File Access @menu * SETPREFIX:: * PREFIX:: * OPENREAD:: * OPENWRITE:: * OPENAPPEND:: * OPENUPDATE:: * CLOSE:: * ALLOPEN:: * CLOSEALL:: * ERASEFILE:: * DRIBBLE:: * NODRIBBLE:: * SETREAD:: * SETWRITE:: * READER:: * WRITER:: * SETREADPOS:: * SETWRITEPOS:: * READPOS:: * WRITEPOS:: * EOFP:: * FILEP:: @end menu @node SETPREFIX, PREFIX, FILE ACCESS, FILE ACCESS @comment node-name, next, previous, up @unnumberedsubsec setprefix @cindex setprefix @example SETPREFIX string @end example command. Sets a prefix that will be used as the implicit beginning of filenames in OPENREAD, OPENWRITE, OPENAPPEND, OPENUPDATE, LOAD, and SAVE commands. Logo will put the appropriate separator character (slash for Unix, backslash for DOS/Windows, colon for MacOS) between the prefix and the filename entered by the user. The input to SETPREFIX must be a word, unless it is the empty list, to indicate that there should be no prefix. @xref{OPENREAD} , @xref{OPENWRITE} , @xref{OPENAPPEND} , @xref{OPENUPDATE} , @xref{LOAD} , @xref{SAVE} . @node PREFIX, OPENREAD, SETPREFIX, FILE ACCESS @comment node-name, next, previous, up @unnumberedsubsec prefix @cindex prefix @example PREFIX @end example outputs the current file prefix, or [] if there is no prefix. @xref{SETPREFIX} . @node OPENREAD, OPENWRITE, PREFIX, FILE ACCESS @unnumberedsubsec openread @cindex openread @example OPENREAD filename @end example command. Opens the named file for reading. The read position is initially at the beginning of the file. @node OPENWRITE, OPENAPPEND, OPENREAD, FILE ACCESS @unnumberedsubsec openwrite @cindex openwrite @example OPENWRITE filename @end example command. Opens the named file for writing. If the file already existed, the old version is deleted and a new, empty file created. OPENWRITE, but not the other OPEN variants, will accept as input a two-element list, in which the first element must be a variable name, and the second must be a positive integer. A character buffer of the specified size will be created. When a SETWRITE is done with this same list (in the sense of .EQ, not a copy, so you must do something like @example ? make "buf [foo 100] ? openwrite :buf ? setwrite :buf [...] ? close :buf @end example and not just @example ? openwrite [foo 100] ? setwrite [foo 100] @end example and so on), the printed characters are stored in the buffer; when a CLOSE is done with the same list as input, the characters from the buffer (treated as one long word, even if spaces and newlines are included) become the value of the specified variable. @node OPENAPPEND, OPENUPDATE, OPENWRITE, FILE ACCESS @unnumberedsubsec openappend @cindex openappend @example OPENAPPEND filename @end example command. Opens the named file for writing. If the file already exists, the write position is initially set to the end of the old file, so that newly written data will be appended to it. @node OPENUPDATE, CLOSE, OPENAPPEND, FILE ACCESS @unnumberedsubsec openupdate @cindex openupdate @example OPENUPDATE filename @end example command. Opens the named file for reading and writing. The read and write position is initially set to the end of the old file, if any. Note: each open file has only one position, for both reading and writing. If a file opened for update is both READER and WRITER at the same time, then SETREADPOS will also affect WRITEPOS and vice versa. Also, if you alternate reading and writing the same file, you must SETREADPOS between a write and a read, and SETWRITEPOS between a read and a write. @xref{READER} , @ref{WRITER} , @ref{SETREADPOS} , @ref{SETWRITEPOS} @node CLOSE, ALLOPEN, OPENUPDATE, FILE ACCESS @unnumberedsubsec close @cindex close @example CLOSE filename @end example command. Closes the named file. If the file was currently the reader or writer, then the reader or writer is changed to the keyboard or screen, as if @w{@t{SETREAD []}} or @w{@t{SETWRITE []}} had been done. @node ALLOPEN, CLOSEALL, CLOSE, FILE ACCESS @unnumberedsubsec allopen @cindex allopen @example ALLOPEN @end example outputs a list whose members are the names of all files currently open. This list does not include the dribble file, if any. @node CLOSEALL, ERASEFILE, ALLOPEN, FILE ACCESS @unnumberedsubsec closeall @cindex closeall @example CLOSEALL (library procedure) @end example command. Closes all open files. Abbreviates @w{@t{FOREACH ALLOPEN [CLOSE ?]}} @xref{FOREACH} , @ref{CLOSE} @node ERASEFILE, DRIBBLE, CLOSEALL, FILE ACCESS @unnumberedsubsec erasefile @cindex erasefile @cindex erf @example ERASEFILE filename ERF filename @end example command. Erases (deletes, removes) the named file, which should not currently be open. @node DRIBBLE, NODRIBBLE, ERASEFILE, FILE ACCESS @unnumberedsubsec dribble @cindex dribble @example DRIBBLE filename @end example command. Creates a new file whose name is the input, like OPENWRITE, and begins recording in that file everything that is read from the keyboard or written to the terminal. That is, this writing is in addition to the writing to WRITER. The intent is to create a transcript of a Logo session, including things like prompt characters and interactions. @xref{OPENWRITE} , @ref{WRITER} @node NODRIBBLE, SETREAD, DRIBBLE, FILE ACCESS @unnumberedsubsec nodribble @cindex nodribble @example NODRIBBLE @end example command. Stops copying information into the dribble file, and closes the file. @node SETREAD, SETWRITE, NODRIBBLE, FILE ACCESS @unnumberedsubsec setread @cindex setread @example SETREAD filename @end example command. Makes the named file the read stream, used for READLIST, etc. The file must already be open with OPENREAD or OPENUPDATE. If the input is the empty list, then the read stream becomes the terminal, as usual. Changing the read stream does not close the file that was previously the read stream, so it is possible to alternate between files. @xref{READLIST} , @ref{OPENREAD} , @ref{OPENUPDATE} @node SETWRITE, READER, SETREAD, FILE ACCESS @unnumberedsubsec setwrite @cindex setwrite @example SETWRITE filename @end example command. Makes the named file the write stream, used for PRINT, etc. The file must already be open with OPENWRITE, OPENAPPEND, or OPENUPDATE. If the input is the empty list, then the write stream becomes the terminal, as usual. Changing the write stream does not close the file that was previously the write stream, so it is possible to alternate between files. If the input is a list, then its first element must be a variable name, and its second and last element must be a positive integer; a buffer of that many characters will be allocated, and will become the writestream. If the same list (same in the .EQ sense, not a copy) has been used as input to OPENWRITE, then the already-allocated buffer will be used, and the writer can be changed to and from this buffer, with all the characters accumulated as in a file. When the same list is used as input to CLOSE, the contents of the buffer (as an unparsed word, which may contain newline characters) will become the value of the named variable. For compatibility with earlier versions, if the list has not been opened when the SETWRITE is done, it will be opened implicitly, but the first SETWRITE after this one will implicitly close it, setting the variable and freeing the allocated buffer. @xref{PRINT} , @ref{OPENWRITE} ; @ref{OPENAPPEND} ; @ref{OPENUPDATE} @node READER, WRITER, SETWRITE, FILE ACCESS @unnumberedsubsec reader @cindex reader @example READER @end example outputs the name of the current read stream file, or the empty list if the read stream is the terminal. @node WRITER, SETREADPOS, READER, FILE ACCESS @unnumberedsubsec writer @cindex writer @example WRITER @end example outputs the name of the current write stream file, or the empty list if the write stream is the terminal. @node SETREADPOS, SETWRITEPOS, WRITER, FILE ACCESS @unnumberedsubsec setreadpos @cindex setreadpos @example SETREADPOS charpos @end example command. Sets the file pointer of the read stream file so that the next READLIST, etc., will begin reading at the @code{charpos}th character in the file, counting from 0. (That is, @w{@t{SETREADPOS 0}} will start reading from the beginning of the file.) Meaningless if the read stream is the terminal. @xref{READLIST} . @node SETWRITEPOS, READPOS, SETREADPOS, FILE ACCESS @unnumberedsubsec setwritepos @cindex setwritepos @example SETWRITEPOS charpos @end example command. Sets the file pointer of the write stream file so that the next PRINT, etc., will begin writing at the @code{charpos}th character in the file, counting from 0. (That is, @w{@t{SETWRITEPOS 0}} will start writing from the beginning of the file.) Meaningless if the write stream is the terminal. @xref{PRINT} . @node READPOS, WRITEPOS, SETWRITEPOS, FILE ACCESS @unnumberedsubsec readpos @cindex readpos @example READPOS @end example outputs the file position of the current read stream file. @node WRITEPOS, EOFP, READPOS, FILE ACCESS @unnumberedsubsec writepos @cindex writepos @example WRITEPOS @end example outputs the file position of the current write stream file. @node EOFP, FILEP, WRITEPOS, FILE ACCESS @unnumberedsubsec eofp @cindex eofp @cindex eof? @example EOFP EOF? @end example predicate, outputs TRUE if there are no more characters to be read in the read stream file, FALSE otherwise. @node FILEP, , EOFP, FILE ACCESS @unnumberedsubsec filep @cindex filep @cindex file? @example FILEP filename FILE? filename (library procedure) @end example predicate, outputs TRUE if a file of the specified name exists and can be read, FALSE otherwise. @node TERMINAL ACCESS, , FILE ACCESS, COMMUNICATION @section Terminal Access @menu * KEYP:: * CLEARTEXT:: * SETCURSOR:: * CURSOR:: * SETMARGINS:: * SETTEXTCOLOR:: @end menu @node KEYP, CLEARTEXT, TERMINAL ACCESS, TERMINAL ACCESS @unnumberedsubsec keyp @cindex keyp @cindex key? @example KEYP KEY? @end example predicate, outputs TRUE if there are characters waiting to be read from the read stream. If the read stream is a file, this is equivalent to @w{@t{NOT EOFP}}. If the read stream is the terminal, then echoing is turned off and the terminal is set to CBREAK (character at a time instead of line at a time) mode. It remains in this mode until some line-mode reading is requested (e.g., READLIST). The Unix operating system forgets about any pending characters when it switches modes, so the first KEYP invocation will always output FALSE. @xref{EOFP} , @ref{READLIST} @node CLEARTEXT, SETCURSOR, KEYP, TERMINAL ACCESS @unnumberedsubsec cleartext @cindex cleartext @cindex ct @example CLEARTEXT CT @end example command. Clears the text screen of the terminal. @node SETCURSOR, CURSOR, CLEARTEXT, TERMINAL ACCESS @unnumberedsubsec setcursor @cindex setcursor @example SETCURSOR vector @end example command. The input is a list of two numbers, the x and y coordinates of a screen position (origin in the upper left corner, positive direction is southeast). The screen cursor is moved to the requested position. This command also forces the immediate printing of any buffered characters. @node CURSOR, SETMARGINS, SETCURSOR, TERMINAL ACCESS @unnumberedsubsec cursor @cindex cursor @example CURSOR @end example outputs a list containing the current x and y coordinates of the screen cursor. Logo may get confused about the current cursor position if, e.g., you type in a long line that wraps around or your program prints escape codes that affect the terminal strangely. @node SETMARGINS, SETTEXTCOLOR, CURSOR, TERMINAL ACCESS @unnumberedsubsec setmargins @cindex setmargins @example SETMARGINS vector @end example command. The input must be a list of two numbers, as for SETCURSOR. The effect is to clear the screen and then arrange for all further printing to be shifted down and to the right according to the indicated margins. Specifically, every time a newline character is printed (explicitly or implicitly) Logo will type x_margin spaces, and on every invocation of SETCURSOR the margins will be added to the input x and y coordinates. (CURSOR will report the cursor position relative to the margins, so that this shift will be invisible to Logo programs.) The purpose of this command is to accommodate the display of terminal screens in lecture halls with inadequate TV monitors that miss the top and left edges of the screen. @xref{SETCURSOR} . @node SETTEXTCOLOR, , SETMARGINS, TERMINAL ACCESS @unnumberedsubsec settextcolor @cindex settextcolor @cindex settc @example SETTEXTCOLOR foreground background SETTC foreground background @end example Command (Windows and DOS extended only). The inputs are color numbers, as for turtle graphics. Future printing to the text window will use the specified colors for foreground (the characters printed) and background (the space under those characters). Using STANDOUT will revert to the default text window colors. In the DOS extended (ucblogo.exe) version, colors in textscreen mode are limited to numbers 0-7, and the coloring applies only to text printed by the program, not to the echoing of text typed by the user. Neither limitation applies to the text portion of splitscreen mode, which is actually drawn as graphics internally. @xref{STANDOUT} . @node ARITHMETIC, LOGICAL OPERATIONS, COMMUNICATION, Top @chapter Arithmetic @menu * NUMERIC OPERATIONS:: * NUMERIC PREDICATES:: * RANDOM NUMBERS:: * PRINT FORMATTING:: * BITWISE OPERATIONS:: @end menu @node NUMERIC OPERATIONS, NUMERIC PREDICATES, ARITHMETIC, ARITHMETIC @section Numeric Operations @menu * SUM:: * DIFFERENCE:: * MINUS:: * PRODUCT:: * QUOTIENT:: * REMAINDER:: * MODULO:: * INT:: * ROUND:: * SQRT:: * POWER:: * EXP:: * LOG10:: * LN:: * SIN:: * RADSIN:: * COS:: * RADCOS:: * ARCTAN:: * RADARCTAN:: * ISEQ:: * RSEQ:: @end menu @node SUM, DIFFERENCE, NUMERIC OPERATIONS, NUMERIC OPERATIONS @unnumberedsubsec sum @cindex sum @cindex + @example SUM num1 num2 (SUM num1 num2 num3 ...) num1 + num2 @end example outputs the sum of its inputs. @node DIFFERENCE, MINUS, SUM, NUMERIC OPERATIONS @unnumberedsubsec difference @cindex difference @cindex - @example DIFFERENCE num1 num2 num1 - num2 @end example outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.) @node MINUS, PRODUCT, DIFFERENCE, NUMERIC OPERATIONS @unnumberedsubsec minus @cindex minus @example MINUS num - num @end example outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms: @example MINUS 3 + 4 means -(3+4) - 3 + 4 means (-3)+4 @end example @node PRODUCT, QUOTIENT, MINUS, NUMERIC OPERATIONS @unnumberedsubsec product @cindex product @cindex * @example PRODUCT num1 num2 (PRODUCT num1 num2 num3 ...) num1 * num2 @end example outputs the product of its inputs. @node QUOTIENT, REMAINDER, PRODUCT, NUMERIC OPERATIONS @unnumberedsubsec quotient @cindex quotient @cindex / @example QUOTIENT num1 num2 (QUOTIENT num) num1 / num2 @end example outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, @w{@t{QUOTIENT 5 2}} is 2.5, not 2, but @w{@t{QUOTIENT 4 2}} is 2, not 2.0 --- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input. @node REMAINDER, MODULO, QUOTIENT, NUMERIC OPERATIONS @unnumberedsubsec remainder @cindex remainder @example REMAINDER num1 num2 @end example outputs the remainder on dividing @code{num1} by @code{num2}; both must be integers and the result is an integer with the same sign as num1. @node MODULO, INT, REMAINDER, NUMERIC OPERATIONS @unnumberedsubsec modulo @cindex modulo @example MODULO num1 num2 @end example outputs the remainder on dividing @code{num1} by @code{num2}; both must be integers and the result is an integer with the same sign as num2. @node INT, ROUND, MODULO, NUMERIC OPERATIONS @unnumberedsubsec int @cindex int @example INT num @end example outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input. @node ROUND, SQRT, INT, NUMERIC OPERATIONS @unnumberedsubsec round @cindex round @example ROUND num @end example outputs the nearest integer to the input. @node SQRT, POWER, ROUND, NUMERIC OPERATIONS @unnumberedsubsec sqrt @cindex sqrt @example SQRT num @end example outputs the square root of the input, which must be nonnegative. @node POWER, EXP, SQRT, NUMERIC OPERATIONS @unnumberedsubsec power @cindex power @example POWER num1 num2 @end example outputs @code{num1} to the @code{num2} power. If num1 is negative, then num2 must be an integer. @node EXP, LOG10, POWER, NUMERIC OPERATIONS @unnumberedsubsec exp @cindex exp @example EXP num @end example outputs e (2.718281828+) to the input power. @node LOG10, LN, EXP, NUMERIC OPERATIONS @unnumberedsubsec log10 @cindex log10 @example LOG10 num @end example outputs the common logarithm of the input. @node LN, SIN, LOG10, NUMERIC OPERATIONS @unnumberedsubsec ln @cindex ln @example LN num @end example outputs the natural logarithm of the input. @node SIN, RADSIN, LN, NUMERIC OPERATIONS @unnumberedsubsec sin @cindex sin @example SIN degrees @end example outputs the sine of its input, which is taken in degrees. @node RADSIN, COS, SIN, NUMERIC OPERATIONS @unnumberedsubsec radsin @cindex radsin @example RADSIN radians @end example outputs the sine of its input, which is taken in radians. @node COS, RADCOS, RADSIN, NUMERIC OPERATIONS @unnumberedsubsec cos @cindex cos @example COS degrees @end example outputs the cosine of its input, which is taken in degrees. @node RADCOS, ARCTAN, COS, NUMERIC OPERATIONS @unnumberedsubsec radcos @cindex radcos @example RADCOS radians @end example outputs the cosine of its input, which is taken in radians. @node ARCTAN, RADARCTAN, RADCOS, NUMERIC OPERATIONS @unnumberedsubsec arctan @cindex arctan @example ARCTAN num (ARCTAN x y) @end example outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or --90 depending on the sign of y, if x is zero. @node RADARCTAN, ISEQ, ARCTAN, NUMERIC OPERATIONS @unnumberedsubsec radarctan @cindex radarctan @example RADARCTAN num (RADARCTAN x y) @end example outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or --pi/2 depending on the sign of y, if x is zero. The expression @w{@t{2*(RADARCTAN 0 1)}} can be used to get the value of pi. @node ISEQ, RSEQ, RADARCTAN, NUMERIC OPERATIONS @unnumberedsubsec iseq @cindex iseq @example ISEQ from to (library procedure) @end example outputs a list of the integers from FROM to TO, inclusive. @example ? show iseq 3 7 [3 4 5 6 7] ? show iseq 7 3 [7 6 5 4 3] @end example @node RSEQ, , ISEQ, NUMERIC OPERATIONS @unnumberedsubsec rseq @cindex rseq @example RSEQ from to count (library procedure) @end example outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive. @example ? show rseq 3 5 9 [3 3.25 3.5 3.75 4 4.25 4.5 4.75 5] ? show rseq 3 5 5 [3 3.5 4 4.5 5] @end example @node NUMERIC PREDICATES, RANDOM NUMBERS, NUMERIC OPERATIONS, ARITHMETIC @section Numeric Predicates @menu * LESSP:: * GREATERP:: * LESSEQUALP:: * GREATEREQUALP:: @end menu @node LESSP, GREATERP, NUMERIC PREDICATES, NUMERIC PREDICATES @unnumberedsubsec lessp @cindex lessp @cindex less? @cindex < @example LESSP num1 num2 LESS? num1 num2 num1 < num2 @end example outputs TRUE if its first input is strictly less than its second. @node GREATERP, LESSEQUALP, LESSP, NUMERIC PREDICATES @unnumberedsubsec greaterp @cindex greaterp @cindex greater? @cindex > @example GREATERP num1 num2 GREATER? num1 num2 num1 > num2 @end example outputs TRUE if its first input is strictly greater than its second. @node LESSEQUALP, GREATEREQUALP, GREATERP, NUMERIC PREDICATES @unnumberedsubsec lessequalp @cindex lessequalp @cindex lessequal? @cindex <= @example LESSEQUALP num1 num2 LESSEQUAL? num1 num2 num1 <= num2 @end example outputs TRUE if its first input is less than or equal to its second. @node GREATEREQUALP, , LESSEQUALP, NUMERIC PREDICATES @unnumberedsubsec greaterequalp @cindex greaterequalp @cindex greaterequal? @cindex >= @example GREATEREQUALP num1 num2 GREATEREQUAL? num1 num2 num1 >= num2 @end example outputs TRUE if its first input is greater than or equal to its second. @node RANDOM NUMBERS, PRINT FORMATTING, NUMERIC PREDICATES, ARITHMETIC @section Random Numbers @menu * RANDOM:: * RERANDOM:: @end menu @node RANDOM, RERANDOM, RANDOM NUMBERS, RANDOM NUMBERS @unnumberedsubsec random @cindex random @example RANDOM num (RANDOM start end) @end example with one input, outputs a random nonnegative integer less than its input, which must be a positive integer. With two inputs, RANDOM outputs a random integer greater than or equal to the first input, and less than or equal to the second input. Both inputs must be integers, and the first must be less than the second. @w{@t{(RANDOM 0 9)}} is equivalent to @w{@t{RANDOM 10}}; @w{@t{(RANDOM 3 8)}} is equivalent to @w{@t{(RANDOM 6)+3}}. @node RERANDOM, , RANDOM, RANDOM NUMBERS @unnumberedsubsec rerandom @cindex rerandom @example RERANDOM (RERANDOM seed) @end example command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers. @node PRINT FORMATTING, BITWISE OPERATIONS, RANDOM NUMBERS, ARITHMETIC @section Print Formatting @menu * FORM:: @end menu @node FORM, , PRINT FORMATTING, PRINT FORMATTING @unnumberedsubsec form @cindex form @example FORM num width precision @end example outputs a word containing a printable representation of @code{num}, possibly preceded by spaces (and therefore not a number for purposes of performing arithmetic operations), with at least @code{width} characters, including exactly @code{precision} digits after the decimal point. (If @code{precision} is 0 then there will be no decimal point in the output.) As a debugging feature, (@w{@t{FORM num -1 format}}) will print the floating point @code{num} according to the C printf @code{format}, to allow @example to hex :num op form :num -1 "|%08X %08X| end @end example to allow finding out the exact result of floating point operations. The precise format needed may be machine-dependent. @node BITWISE OPERATIONS, , PRINT FORMATTING, ARITHMETIC @section Bitwise Operations @menu * BITAND:: * BITOR:: * BITXOR:: * BITNOT:: * ASHIFT:: * LSHIFT:: @end menu @node BITAND, BITOR, BITWISE OPERATIONS, BITWISE OPERATIONS @unnumberedsubsec bitand @cindex bitand @example BITAND num1 num2 (BITAND num1 num2 num3 ...) @end example outputs the bitwise AND of its inputs, which must be integers. @xref{AND} . @node BITOR, BITXOR, BITAND, BITWISE OPERATIONS @unnumberedsubsec bitor @cindex bitor @example BITOR num1 num2 (BITOR num1 num2 num3 ...) @end example outputs the bitwise OR of its inputs, which must be integers. @xref{OR} . @node BITXOR, BITNOT, BITOR, BITWISE OPERATIONS @unnumberedsubsec bitxor @cindex bitxor @example BITXOR num1 num2 (BITXOR num1 num2 num3 ...) @end example outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers. @xref{OR} . @node BITNOT, ASHIFT, BITXOR, BITWISE OPERATIONS @unnumberedsubsec bitnot @cindex bitnot @example BITNOT num @end example outputs the bitwise NOT of its input, which must be an integer. @xref{NOT} . @node ASHIFT, LSHIFT, BITNOT, BITWISE OPERATIONS @unnumberedsubsec ashift @cindex ashift @example ASHIFT num1 num2 @end example outputs @code{num1} arithmetic-shifted to the left by @code{num2} bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers. @node LSHIFT, , ASHIFT, BITWISE OPERATIONS @unnumberedsubsec lshift @cindex lshift @example LSHIFT num1 num2 @end example outputs @code{num1} logical-shifted to the left by @code{num2} bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers. @node LOGICAL OPERATIONS, GRAPHICS, ARITHMETIC, Top @chapter Logical Operations @menu * AND:: * OR:: * NOT:: @end menu @node AND, OR, LOGICAL OPERATIONS, LOGICAL OPERATIONS @unnumberedsubsec and @cindex and @example AND tf1 tf2 (AND tf1 tf2 tf3 ...) @end example outputs TRUE if all inputs are TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, @code{true} or @code{True} or @code{TRUE} are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example: @example MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5] @end example to avoid the division by zero if the first part is false. @xref{CASEIGNOREDP} . @node OR, NOT, AND, LOGICAL OPERATIONS @unnumberedsubsec or @cindex or @example OR tf1 tf2 (OR tf1 tf2 tf3 ...) @end example outputs TRUE if any input is TRUE, otherwise FALSE. All inputs must be TRUE or FALSE. (Comparison is case-insensitive regardless of the value of CASEIGNOREDP. That is, @code{true} or @code{True} or @code{TRUE} are all the same.) An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example: @example IF OR :X=0 [some.long.computation] [...] @end example to avoid the long computation if the first condition is met. @xref{CASEIGNOREDP} . @node NOT, , OR, LOGICAL OPERATIONS @unnumberedsubsec not @cindex not @example NOT tf @end example outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. @node GRAPHICS, WORKSPACE MANAGEMENT, LOGICAL OPERATIONS, Top @chapter Graphics Berkeley Logo provides traditional Logo turtle graphics with one turtle. Multiple turtles, dynamic turtles, and collision detection are not supported. This is the most hardware-dependent part of Logo; some features may exist on some machines but not others. Nevertheless, the goal has been to make Logo programs as portable as possible, rather than to take fullest advantage of the capabilities of each machine. In particular, Logo attempts to scale the screen so that turtle coordinates [--100 --100] and [100 100] fit on the graphics window, and so that the aspect ratio is 1:1. The center of the graphics window (which may or may not be the entire screen, depending on the machine used) is turtle location [0 0]. Positive X is to the right; positive Y is up. Headings (angles) are measured in degrees clockwise from the positive Y axis. (This differs from the common mathematical convention of measuring angles counterclockwise from the positive X axis.) The turtle is represented as an isoceles triangle; the actual turtle position is at the midpoint of the base (the short side). However, the turtle is drawn one step behind its actual position, so that the display of the base of the turtle's triangle does not obscure a line drawn perpendicular to it (as would happen after drawing a square). Colors are, of course, hardware-dependent. However, Logo provides partial hardware independence by interpreting color numbers 0 through 7 uniformly on all computers: @example 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white @end example Where possible, Logo provides additional user-settable colors; how many are available depends on the hardware and operating system environment. If at least 16 colors are available, Logo tries to provide uniform initial settings for the colors 8-15: @example 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey @end example Logo begins with a black background and white pen. @menu * TURTLE MOTION:: * TURTLE MOTION QUERIES:: * TURTLE AND WINDOW CONTROL:: * TURTLE AND WINDOW QUERIES:: * PEN AND BACKGROUND CONTROL:: * PEN QUERIES:: * SAVING AND LOADING PICTURES:: * MOUSE QUERIES:: @end menu @node TURTLE MOTION, TURTLE MOTION QUERIES, GRAPHICS, GRAPHICS @section Turtle Motion @menu * FORWARD:: * BACK:: * LEFT:: * RIGHT:: * SETPOS:: * SETXY:: * SETX:: * SETY:: * SETHEADING:: * HOME:: * ARC:: @end menu @node FORWARD, BACK, TURTLE MOTION, TURTLE MOTION @unnumberedsubsec forward @cindex forward @cindex fd @example FORWARD dist FD dist @end example moves the turtle forward, in the direction that it's facing, by the specified distance (measured in turtle steps). @node BACK, LEFT, FORWARD, TURTLE MOTION @unnumberedsubsec back @cindex back @cindex bk @example BACK dist BK dist @end example moves the turtle backward, i.e., exactly opposite to the direction that it's facing, by the specified distance. (The heading of the turtle does not change.) @node LEFT, RIGHT, BACK, TURTLE MOTION @unnumberedsubsec left @cindex left @cindex lt @example LEFT degrees LT degrees @end example turns the turtle counterclockwise by the specified angle, measured in degrees (1/360 of a circle). @node RIGHT, SETPOS, LEFT, TURTLE MOTION @unnumberedsubsec right @cindex right @cindex rt @example RIGHT degrees RT degrees @end example turns the turtle clockwise by the specified angle, measured in degrees (1/360 of a circle). @node SETPOS, SETXY, RIGHT, TURTLE MOTION @unnumberedsubsec setpos @cindex setpos @example SETPOS pos @end example moves the turtle to an absolute screen position. The input is a list of two numbers, the X and Y coordinates. @node SETXY, SETX, SETPOS, TURTLE MOTION @unnumberedsubsec setxy @cindex setxy @example SETXY xcor ycor @end example moves the turtle to an absolute screen position. The two inputs are numbers, the X and Y coordinates. @node SETX, SETY, SETXY, TURTLE MOTION @unnumberedsubsec setx @cindex setx @example SETX xcor @end example moves the turtle horizontally from its old position to a new absolute horizontal coordinate. The input is the new X coordinate. @node SETY, SETHEADING, SETX, TURTLE MOTION @unnumberedsubsec sety @cindex sety @example SETY ycor @end example moves the turtle vertically from its old position to a new absolute vertical coordinate. The input is the new Y coordinate. @node SETHEADING, HOME, SETY, TURTLE MOTION @unnumberedsubsec setheading @cindex setheading @cindex seth @example SETHEADING degrees SETH degrees @end example turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive Y axis. @node HOME, ARC, SETHEADING, TURTLE MOTION @unnumberedsubsec home @cindex home @example HOME @end example moves the turtle to the center of the screen. Equivalent to @w{@t{SETPOS [0 0] SETHEADING 0.}} @xref{SETPOS} , @xref{SETHEADING} . @node ARC, , HOME, TURTLE MOTION @unnumberedsubsec arc @cindex arc @example ARC angle radius @end example draws an arc of a circle, with the turtle at the center, with the specified radius, starting at the turtle's heading and extending clockwise through the specified angle. The turtle does not move. @node TURTLE MOTION QUERIES, TURTLE AND WINDOW CONTROL, TURTLE MOTION, GRAPHICS @section Turtle Motion Queries @menu * POS:: * XCOR:: * YCOR:: * HEADING:: * TOWARDS:: * SCRUNCH:: @end menu @node POS, XCOR, TURTLE MOTION QUERIES, TURTLE MOTION QUERIES @unnumberedsubsec pos @cindex pos @example POS @end example outputs the turtle's current position, as a list of two numbers, the X and Y coordinates. @node XCOR, YCOR, POS, TURTLE MOTION QUERIES @unnumberedsubsec xcor @cindex xcor @example XCOR (library procedure) @end example outputs a number, the turtle's X coordinate. @node YCOR, HEADING, XCOR, TURTLE MOTION QUERIES @unnumberedsubsec ycor @cindex ycor @example YCOR (library procedure) @end example outputs a number, the turtle's Y coordinate. @node HEADING, TOWARDS, YCOR, TURTLE MOTION QUERIES @unnumberedsubsec heading @cindex heading @example HEADING @end example outputs a number, the turtle's heading in degrees. @node TOWARDS, SCRUNCH, HEADING, TURTLE MOTION QUERIES @unnumberedsubsec towards @cindex towards @example TOWARDS pos @end example outputs a number, the heading at which the turtle should be facing so that it would point from its current position to the position given as the input. @node SCRUNCH, , TOWARDS, TURTLE MOTION QUERIES @unnumberedsubsec scrunch @cindex scrunch @example SCRUNCH @end example outputs a list containing two numbers, the X and Y scrunch factors, as used by SETSCRUNCH. (But note that SETSCRUNCH takes two numbers as inputs, not one list of numbers.) @xref{SETSCRUNCH} . @node TURTLE AND WINDOW CONTROL, TURTLE AND WINDOW QUERIES, TURTLE MOTION QUERIES, GRAPHICS @section Turtle and Window Control @menu * SHOWTURTLE:: * HIDETURTLE:: * CLEAN:: * CLEARSCREEN:: * WRAP:: * WINDOW:: * FENCE:: * FILL:: * LABEL:: * TEXTSCREEN:: * FULLSCREEN:: * SPLITSCREEN:: * SETSCRUNCH:: * REFRESH:: * NOREFRESH:: @end menu @node SHOWTURTLE, HIDETURTLE, TURTLE AND WINDOW CONTROL, TURTLE AND WINDOW CONTROL @unnumberedsubsec showturtle @cindex showturtle @cindex st @example SHOWTURTLE ST @end example makes the turtle visible. @node HIDETURTLE, CLEAN, SHOWTURTLE, TURTLE AND WINDOW CONTROL @unnumberedsubsec hideturtle @cindex hideturtle @cindex ht @example HIDETURTLE HT @end example makes the turtle invisible. It's a good idea to do this while you're in the middle of a complicated drawing, because hiding the turtle speeds up the drawing substantially. @node CLEAN, CLEARSCREEN, HIDETURTLE, TURTLE AND WINDOW CONTROL @unnumberedsubsec clean @cindex clean @example CLEAN @end example erases all lines that the turtle has drawn on the graphics window. The turtle's state (position, heading, pen mode, etc.) is not changed. @node CLEARSCREEN, WRAP, CLEAN, TURTLE AND WINDOW CONTROL @unnumberedsubsec clearscreen @cindex clearscreen @cindex cs @example CLEARSCREEN CS @end example erases the graphics window and sends the turtle to its initial position and heading. Like HOME and CLEAN together. @xref{HOME} . @node WRAP, WINDOW, CLEARSCREEN, TURTLE AND WINDOW CONTROL @unnumberedsubsec wrap @cindex wrap @example WRAP @end example tells the turtle to enter wrap mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will "wrap around" and reappear at the opposite edge of the window. The top edge wraps to the bottom edge, while the left edge wraps to the right edge. (So the window is topologically equivalent to a torus.) This is the turtle's initial mode. Compare WINDOW and FENCE. @xref{FENCE} . @node WINDOW, FENCE, WRAP, TURTLE AND WINDOW CONTROL @unnumberedsubsec window @cindex window @example WINDOW @end example tells the turtle to enter window mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move offscreen. The visible graphics window is considered as just part of an infinite graphics plane; the turtle can be anywhere on the plane. (If you lose the turtle, HOME will bring it back to the center of the window.) Compare WRAP and FENCE. @xref{HOME} . @node FENCE, FILL, WINDOW, TURTLE AND WINDOW CONTROL @unnumberedsubsec fence @cindex fence @example FENCE @end example tells the turtle to enter fence mode: From now on, if the turtle is asked to move past the boundary of the graphics window, it will move as far as it can and then stop at the edge with an "out of bounds" error message. Compare WRAP and WINDOW. @xref{WRAP} . @node FILL, LABEL, FENCE, TURTLE AND WINDOW CONTROL @unnumberedsubsec fill @cindex fill @example FILL @end example fills in a region of the graphics window containing the turtle and bounded by lines that have been drawn earlier. This is not portable; it doesn't work for all machines, and may not work exactly the same way on different machines. @node LABEL, TEXTSCREEN, FILL, TURTLE AND WINDOW CONTROL @unnumberedsubsec label @cindex label @example LABEL text @end example takes a word or list as input, and prints the input on the graphics window, starting at the turtle's position. @node TEXTSCREEN, FULLSCREEN, LABEL, TURTLE AND WINDOW CONTROL @unnumberedsubsec textscreen @cindex textscreen @cindex ts @example TEXTSCREEN TS @end example rearranges the size and position of windows to maximize the space available in the text window (the window used for interaction with Logo). The details differ among machines. Compare SPLITSCREEN and FULLSCREEN. @xref{SPLITSCREEN} . @node FULLSCREEN, SPLITSCREEN, TEXTSCREEN, TURTLE AND WINDOW CONTROL @unnumberedsubsec fullscreen @cindex fullscreen @cindex fs @example FULLSCREEN FS @end example rearranges the size and position of windows to maximize the space available in the graphics window. The details differ among machines. Compare SPLITSCREEN and TEXTSCREEN. In the DOS version, switching from fullscreen to splitscreen loses the part of the picture that's hidden by the text window. Also, since there must be a text window to allow printing (including the printing of the Logo prompt), Logo automatically switches from fullscreen to splitscreen whenever anything is printed. [This design decision follows from the scarcity of memory, so that the extra memory to remember an invisible part of a drawing seems too expensive.] @node SPLITSCREEN, SETSCRUNCH, FULLSCREEN, TURTLE AND WINDOW CONTROL @unnumberedsubsec splitscreen @cindex splitscreen @cindex ss @example SPLITSCREEN SS @end example rearranges the size and position of windows to allow some room for text interaction while also keeping most of the graphics window visible. The details differ among machines. Compare TEXTSCREEN and FULLSCREEN. @xref{TEXTSCREEN} . @node SETSCRUNCH, REFRESH, SPLITSCREEN, TURTLE AND WINDOW CONTROL @unnumberedsubsec setscrunch @cindex setscrunch @cindex scrunch.dat @example SETSCRUNCH xscale yscale @end example adjusts the aspect ratio and scaling of the graphics display. After this command is used, all further turtle motion will be adjusted by multiplying the horizontal and vertical extent of the motion by the two numbers given as inputs. For example, after the instruction @w{@code{SETSCRUNCH 2 1}} motion at a heading of 45 degrees will move twice as far horizontally as vertically. If your squares don't come out square, try this. (Alternatively, you can deliberately misadjust the aspect ratio to draw an ellipse.) For Unix machines and Macintoshes, both scale factors are initially 1. For DOS machines, the scale factors are initially set according to what the hardware claims the aspect ratio is, but the hardware sometimes lies. The values set by SETSCRUNCH are remembered in a file (called SCRUNCH.DAT) and are automatically put into effect when a Logo session begins. @node REFRESH, NOREFRESH, SETSCRUNCH, TURTLE AND WINDOW CONTROL @unnumberedsubsec refresh @cindex refresh @example REFRESH @end example tells Logo to remember the turtle's motions so that they can be reconstructed in case the graphics window is overlayed. The effectiveness of this command may depend on the machine used. @node NOREFRESH, , REFRESH, TURTLE AND WINDOW CONTROL @unnumberedsubsec norefresh @cindex norefresh @example NOREFRESH @end example tells Logo not to remember the turtle's motions. This will make drawing faster, but prevents recovery if the window is overlayed. @node TURTLE AND WINDOW QUERIES, PEN AND BACKGROUND CONTROL, TURTLE AND WINDOW CONTROL, GRAPHICS @section Turtle and Window Queries @menu * SHOWNP:: * SCREENMODE:: * TURTLEMODE:: @end menu @node SHOWNP, SCREENMODE, TURTLE AND WINDOW QUERIES, TURTLE AND WINDOW QUERIES @unnumberedsubsec shownp @cindex shownp @cindex shown? @example SHOWNP SHOWN? @end example outputs TRUE if the turtle is shown (visible), FALSE if the turtle is hidden. See SHOWTURTLE and HIDETURTLE. @xref{SHOWTURTLE} , @ref{HIDETURTLE} . @node SCREENMODE, TURTLEMODE, SHOWNP, TURTLE AND WINDOW QUERIES @unnumberedsubsec screenmode @cindex screenmode @example SCREENMODE @end example outputs the word TEXTSCREEN, SPLITSCREEN, or FULLSCREEN depending on the current screen mode. @node TURTLEMODE, , SCREENMODE, TURTLE AND WINDOW QUERIES @unnumberedsubsec turtlemode @cindex turtlemode @example TURTLEMODE @end example outputs the word WRAP, FENCE, or WINDOW depending on the current turtle mode. @node PEN AND BACKGROUND CONTROL, PEN QUERIES, TURTLE AND WINDOW QUERIES, GRAPHICS @section Pen and Background Control The turtle carries a pen that can draw pictures. At any time the pen can be UP (in which case moving the turtle does not change what's on the graphics screen) or DOWN (in which case the turtle leaves a trace). If the pen is down, it can operate in one of three modes: PAINT (so that it draws lines when the turtle moves), ERASE (so that it erases any lines that might have been drawn on or through that path earlier), or REVERSE (so that it inverts the status of each point along the turtle's path). @menu * PENDOWN:: * PENUP:: * PENPAINT:: * PENERASE:: * PENREVERSE:: * SETPENCOLOR:: * SETPALETTE:: * SETPENSIZE:: * SETPENPATTERN:: * SETPEN:: * SETBACKGROUND:: @end menu @node PENDOWN, PENUP, PEN AND BACKGROUND CONTROL, PEN AND BACKGROUND CONTROL @unnumberedsubsec pendown @cindex pendown @cindex pd @example PENDOWN PD @end example sets the pen's position to DOWN, without changing its mode. @node PENUP, PENPAINT, PENDOWN, PEN AND BACKGROUND CONTROL @unnumberedsubsec penup @cindex penup @cindex pu @example PENUP PU @end example sets the pen's position to UP, without changing its mode. @node PENPAINT, PENERASE, PENUP, PEN AND BACKGROUND CONTROL @unnumberedsubsec penpaint @cindex penpaint @cindex ppt @example PENPAINT PPT @end example sets the pen's position to DOWN and mode to PAINT. @node PENERASE, PENREVERSE, PENPAINT, PEN AND BACKGROUND CONTROL @unnumberedsubsec penerase @cindex penerase @cindex pe @example PENERASE PE @end example sets the pen's position to DOWN and mode to ERASE. @xref{ERASE} . @node PENREVERSE, SETPENCOLOR, PENERASE, PEN AND BACKGROUND CONTROL @unnumberedsubsec penreverse @cindex penreverse @cindex px @example PENREVERSE PX @end example sets the pen's position to DOWN and mode to REVERSE. (This may interact in hardware-dependent ways with use of color.) @xref{REVERSE} . @node SETPENCOLOR, SETPALETTE, PENREVERSE, PEN AND BACKGROUND CONTROL @unnumberedsubsec setpencolor @cindex setpencolor @cindex setpc @example SETPENCOLOR colornumber.or.rgblist SETPC colornumber.or.rgblist @end example sets the pen color to the given number, which must be a nonnegative integer. There are initial assignments for the first 16 colors: @example 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey @end example but other colors can be assigned to numbers by the PALETTE command. Alternatively, sets the pen color to the given RGB values (a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color). @node SETPALETTE, SETPENSIZE, SETPENCOLOR, PEN AND BACKGROUND CONTROL @unnumberedsubsec setpalette @cindex setpalette @example SETPALETTE colornumber rgblist @end example sets the actual color corresponding to a given number, if allowed by the hardware and operating system. Colornumber must be an integer greater than or equal to 8. (Logo tries to keep the first 8 colors constant.) The second input is a list of three nonnegative integers less than 64K (65536) specifying the amount of red, green, and blue in the desired color. The actual color resolution on any screen is probably less than 64K, but Logo scales as needed. @node SETPENSIZE, SETPENPATTERN, SETPALETTE, PEN AND BACKGROUND CONTROL @unnumberedsubsec setpensize @cindex setpensize @example SETPENSIZE size @end example sets the thickness of the pen. The input is either a single positive integer or a list of two positive integers (for horizontal and vertical thickness). Some versions pay no attention to the second number, but always have a square pen. @example SETPENPATTERN pattern @end example sets hardware-dependent pen characteristics. This command is not guaranteed compatible between implementations on different machines. @node SETPENPATTERN, SETPEN, SETPENSIZE, PEN AND BACKGROUND CONTROL @unnumberedsubsec setpenpattern @cindex setpenpattern @example SETPENSIZE size SETPENPATTERN pattern @end example set hardware-dependent pen characteristics. These commands are not guaranteed compatible between implementations on different machines. @node SETPEN, SETBACKGROUND, SETPENPATTERN, PEN AND BACKGROUND CONTROL @unnumberedsubsec setpen @cindex setpen @example SETPEN list (library procedure) @end example sets the pen's position, mode, thickness, and hardware-dependent characteristics according to the information in the input list, which should be taken from an earlier invocation of PEN. @xref{PEN} . @node SETBACKGROUND, , SETPEN, PEN AND BACKGROUND CONTROL @unnumberedsubsec setbackground @cindex setbackground @cindex setbg @example SETBACKGROUND colornumber.or.rgblist SETBG colornumber.or.rgblist @end example set the screen background color by slot number or RGB values. See SETPENCOLOR for details. @xref{SETPENCOLOR} . @node PEN QUERIES, SAVING AND LOADING PICTURES, PEN AND BACKGROUND CONTROL, GRAPHICS @section Pen Queries @menu * PENDOWNP:: * PENMODE:: * PENCOLOR:: * PALETTE:: * PENSIZE:: * PEN:: * BACKGROUND:: @end menu @node PENDOWNP, PENMODE, PEN QUERIES, PEN QUERIES @unnumberedsubsec pendownp @cindex pendownp @cindex pendown? @example PENDOWNP PENDOWN? @end example outputs TRUE if the pen is down, FALSE if it's up. @node PENMODE, PENCOLOR, PENDOWNP, PEN QUERIES @unnumberedsubsec penmode @cindex penmode @example PENMODE @end example outputs one of the words PAINT, ERASE, or REVERSE according to the current pen mode. @xref{ERASE} , @ref{REVERSE} . @node PENCOLOR, PALETTE, PENMODE, PEN QUERIES @unnumberedsubsec pencolor @cindex pencolor @cindex pc @example PENCOLOR PC @end example outputs a color number, a nonnegative integer that is associated with a particular color, or a list of RGB values if such a list was used as the most recent input to SETPENCOLOR. There are initial assignments for the first 16 colors: @example 0 black 1 blue 2 green 3 cyan 4 red 5 magenta 6 yellow 7 white 8 brown 9 tan 10 forest 11 aqua 12 salmon 13 purple 14 orange 15 grey @end example but other colors can be assigned to numbers by the PALETTE command. @node PALETTE, PENSIZE, PENCOLOR, PEN QUERIES @unnumberedsubsec palette @cindex palette @example PALETTE colornumber @end example outputs a list of three integers, each in the range 0-65535, representing the amount of red, green, and blue in the color associated with the given number. @node PENSIZE, PEN, PALETTE, PEN QUERIES @unnumberedsubsec pensize @cindex pensize @cindex penpattern @example PENSIZE @end example outputs a list of two positive integers, specifying the horizontal and vertical thickness of the turtle pen. (In some implementations the two numbers may always be equal.) @example PENPATTERN @end example outputs hardware-specific pen information. @node PEN, BACKGROUND, PENSIZE, PEN QUERIES @unnumberedsubsec pen @cindex pen @example PEN (library procedure) @end example outputs a list containing the pen's position, mode, thickness, and hardware-specific characteristics, for use by SETPEN. @xref{SETPEN} . @node BACKGROUND, , PEN, PEN QUERIES @unnumberedsubsec background @cindex background @cindex bg @example BACKGROUND BG @end example outputs the graphics background color, either as a slot number or as an RGB list, whichever way it was set. (See PENCOLOR.) @node SAVING AND LOADING PICTURES, MOUSE QUERIES, PEN QUERIES, GRAPHICS @comment node-name, next, previous, up @section saving and loading pictures @menu * SAVEPICT:: * LOADPICT:: * EPSPICT:: @end menu @node SAVEPICT, LOADPICT, SAVING AND LOADING PICTURES, SAVING AND LOADING PICTURES @comment node-name, next, previous, up @unnumberedsubsec savepict @cindex savepict @example SAVEPICT filename @end example command. Writes a file with the specified name containing the state of the graphics window, including any nonstandard color palette settings, in Logo's internal format. This picture can be restored to the screen using LOADPICT. The format is not portable between platforms, nor is it readable by other programs. @ref{EPSPICT} to export Logo graphics for other programs. @node LOADPICT, EPSPICT, SAVEPICT, SAVING AND LOADING PICTURES @comment node-name, next, previous, up @unnumberedsubsec loadpict @cindex loadpict @example LOADPICT filename @end example command. Reads the specified file, which must have been written by a SAVEPICT command, and restores the graphics window and color palette settings to the values stored in the file. Any drawing previously on the screen is cleared. @xref{SAVEPICT} . @node EPSPICT, , LOADPICT, SAVING AND LOADING PICTURES @comment node-name, next, previous, up @unnumberedsubsec epspict @cindex epspict @example EPSPICT filename @end example command. Writes a file with the specified name, containing an Encapsulated Postscript (EPS) representation of the state of the graphics window. This file can be imported into other programs that understand EPS format. Restrictions: the drawing cannot use ARC, FILL, PENERASE, or PENREVERSE; any such instructions will be ignored in the translation to Postscript form. @xref{ARC} , @xref{FILL} , @xref{PENERASE} , @xref{PENREVERSE} . @node MOUSE QUERIES, , SAVING AND LOADING PICTURES, GRAPHICS @comment node-name, next, previous, up @section Mouse Queries @menu * MOUSEPOS:: * BUTTONP:: * BUTTON:: @end menu @node MOUSEPOS, BUTTONP, MOUSE QUERIES, MOUSE QUERIES @comment node-name, next, previous, up @unnumberedsubsec mousepos @cindex mousepos @example MOUSEPOS @end example outputs the coordinates of the mouse, provided that it's within the graphics window, in turtle coordinates. If the mouse is outside the graphics window, then the last position within the window is returned. Exception: If a mouse button is pressed within the graphics window and held while the mouse is dragged outside the window, the mouse's position is returned as if the window were big enough to include it. @node BUTTONP, BUTTON, MOUSEPOS, MOUSE QUERIES @comment node-name, next, previous, up @unnumberedsubsec buttonp @cindex buttonp @cindex button? @example BUTTONP BUTTON? @end example outputs TRUE if a mouse button is down and the mouse is over the graphics window. Once the button is down, BUTTONP remains true until the button is released, even if the mouse is dragged out of the graphics window. @node BUTTON, , BUTTONP, MOUSE QUERIES @comment node-name, next, previous, up @unnumberedsubsec buttonp @cindex button @example BUTTON @end example outputs 0 if BUTTONP would output FALSE; otherwise, it outputs an integer between 1 and 3 indicating which button was pressed. Ordinarily 1 means left, 2 means right, and 3 means center, but operating systems may reconfigure these. @node WORKSPACE MANAGEMENT, CONTROL STRUCTURES, GRAPHICS, Top @chapter Workspace Management @menu * PROCEDURE DEFINITION:: * VARIABLE DEFINITION:: * PROPERTY LISTS:: * WORKSPACE PREDICATES:: * WORKSPACE QUERIES:: * WORKSPACE INSPECTION:: * WORKSPACE CONTROL:: @end menu @node PROCEDURE DEFINITION, VARIABLE DEFINITION, WORKSPACE MANAGEMENT, WORKSPACE MANAGEMENT @section Procedure Definition @menu * TO:: * DEFINE:: * TEXT:: * FULLTEXT:: * COPYDEF:: @end menu @node TO, DEFINE, PROCEDURE DEFINITION, PROCEDURE DEFINITION @unnumberedsubsec to @cindex to @example TO procname :input1 :input2 ... (special form) @end example command. Prepares Logo to accept a procedure definition. The procedure will be named @code{procname} and there must not already be a procedure by that name. The inputs will be called @code{input1} etc. Any number of inputs are allowed, including none. Names of procedures and inputs are case-insensitive. Unlike every other Logo procedure, TO takes as its inputs the actual words typed in the instruction line, as if they were all quoted, rather than the results of evaluating expressions to provide the inputs. (That's what @b{"special form"} means.) This version of Logo allows variable numbers of inputs to a procedure. After the procedure name come four kinds of things, *in this order*: @example 1. 0 or more REQUIRED inputs :FOO :FROBOZZ 2. 0 or more OPTIONAL inputs [:BAZ 87] [:THINGO 5+9] 3. 0 or 1 REST input [:GARPLY] 4. 0 or 1 DEFAULT number 5 @end example Every procedure has a MINIMUM, DEFAULT, and MAXIMUM number of inputs. (The latter can be infinite.) The MINIMUM number of inputs is the number of required inputs, which must come first. A required input is indicated by the @example :inputname @end example notation. After all the required inputs can be zero or more optional inputs, each of which is represented by the following notation: @example [:inputname default.value.expression] @end example When the procedure is invoked, if actual inputs are not supplied for these optional inputs, the default value expressions are evaluated to set values for the corresponding input names. The inputs are processed from left to right, so a default value expression can be based on earlier inputs. Example: @example to proc :inlist [:startvalue first :inlist] @end example If the procedure is invoked by saying @example proc [a b c] @end example then the variable @code{inlist} will have the value @w{[A B C]} and the variable @code{startvalue} will have the value A. If the procedure is invoked by saying @example (proc [a b c] "x) @end example then @code{inlist} will have the value @w{[A B C]} and @code{startvalue} will have the value X. After all the required and optional input can come a single @code{rest} input, represented by the following notation: @example [:inputname] @end example This is a rest input rather than an optional input because there is no default value expression. There can be at most one rest input. When the procedure is invoked, the value of this input will be a list containing all of the actual inputs provided that were not used for required or optional inputs. Example: @example to proc :in1 [:in2 "foo] [:in3 "baz] [:in4] @end example If this procedure is invoked by saying @example proc "x @end example then @code{in1} has the value X, @code{in2} has the value FOO, @code{in3} has the value BAZ,and @code{in4} has the value @t{[]} (the empty list). If it's invoked by saying @example (proc "a "b "c "d "e) @end example then @code{in1} has the value A, @code{in2} has the value B, @code{in3} has the value C, and @code{in4} has the value @w{[D E]}. The MAXIMUM number of inputs for a procedure is infinite if a rest input is given; otherwise, it is the number of required inputs plus the number of optional inputs. The DEFAULT number of inputs for a procedure, which is the number of inputs that it will accept if its invocation is not enclosed in parentheses, is ordinarily equal to the minimum number. If you want a different default number you can indicate that by putting the desired default number as the last thing on the TO line. example: @example to proc :in1 [:in2 "foo] [:in3] 3 @end example This procedure has a minimum of one input, a default of three inputs, and an infinite maximum. Logo responds to the TO command by entering procedure definition mode. The prompt character changes from @code{?} to @code{>} and whatever instructions you type become part of the definition until you type a line containing only the word END. @node DEFINE, TEXT, TO, PROCEDURE DEFINITION @unnumberedsubsec define @cindex define @example DEFINE procname text @end example command. Defines a procedure with name @code{procname} and text @code{text}. If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.) It is an error to redefine a primitive procedure unless the variable @var{REDEFP} has the value TRUE. @xref{REDEFP} . @node TEXT, FULLTEXT, DEFINE, PROCEDURE DEFINITION @unnumberedsubsec text @cindex text @example TEXT procname @end example outputs the text of the procedure named @code{procname} in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces. @node FULLTEXT, COPYDEF, TEXT, PROCEDURE DEFINITION @unnumberedsubsec fulltext @cindex fulltext @example FULLTEXT procname @end example outputs a representation of the procedure @code{procname} in which formatting information is preserved. If the procedure was defined with TO, EDIT, or LOAD, then the output is a list of words. Each word represents one entire line of the definition in the form output by READWORD, including extra spaces and continuation lines. The last member of the output represents the END line. If the procedure was defined with DEFINE, then the output is a list of lists. If these lists are printed, one per line, the result will look like a definition using TO. Note: the output from FULLTEXT is not suitable for use as input to DEFINE! @xref{TO} , @ref{EDIT} , @ref{LOAD} , @ref{DEFINE} . @node COPYDEF, , FULLTEXT, PROCEDURE DEFINITION @unnumberedsubsec copydef @cindex copydef @example COPYDEF newname oldname @end example command. Makes @code{newname} a procedure identical to @code{oldname}. The latter may be a primitive. If @code{newname} was already defined, its previous definition is lost. If @code{newname} was already a primitive, the redefinition is not permitted unless the variable @var{REDEFP} has the value TRUE. Note: dialects of Logo differ as to the order of inputs to COPYDEF. This dialect uses "MAKE order," not "NAME order." @xref{REDEFP} , @ref{SAVE} , @ref{PO} , @ref{POT} . @node VARIABLE DEFINITION, PROPERTY LISTS, PROCEDURE DEFINITION, WORKSPACE MANAGEMENT @section Variable Definition @menu * MAKE:: * NAME:: * LOCAL:: * LOCALMAKE:: * THING:: * GLOBAL:: @end menu @node MAKE, NAME, VARIABLE DEFINITION, VARIABLE DEFINITION @unnumberedsubsec make @cindex make @example MAKE varname value @end example command. Assigns the value @code{value} to the variable named @code{varname}, which must be a word. Variable names are case-insensitive. If a variable with the same name already exists, the value of that variable is changed. If not, a new global variable is created. @node NAME, LOCAL, MAKE, VARIABLE DEFINITION @unnumberedsubsec name @cindex name @example NAME value varname (library procedure) @end example command. Same as MAKE but with the inputs in reverse order. @node LOCAL, LOCALMAKE, NAME, VARIABLE DEFINITION @unnumberedsubsec local @cindex local @example LOCAL varname LOCAL varnamelist (LOCAL varname1 varname2 ...) @end example command. Accepts as inputs one or more words, or a list of words. A variable is created for each of these words, with that word as its name. The variables are local to the currently running procedure. Logo variables follow dynamic scope rules; a variable that is local to a procedure is available to any subprocedure invoked by that procedure. The variables created by LOCAL have no initial value; they must be assigned a value (e.g., with MAKE) before the procedure attempts to read their value. @xref{MAKE} . @node LOCALMAKE, THING, LOCAL, VARIABLE DEFINITION @comment node-name, next, previous, up @unnumberedsubsec localmake @cindex localmake @example LOCALMAKE varname value (library procedure) @end example command. Makes the named variable local, like LOCAL, and assigns it the given value, like MAKE. @xref{LOCAL} , @xref{MAKE} . @node THING, GLOBAL, LOCALMAKE, VARIABLE DEFINITION @unnumberedsubsec thing @cindex thing @example THING varname :quoted.varname @end example outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination @example thing " @end example so that @w{@t{:FOO}} means @w{@t{THING "FOO}}. @node GLOBAL, , THING, VARIABLE DEFINITION @unnumberedsubsec global @cindex global @example GLOBAL varname GLOBAL varnamelist (GLOBAL varname1 varname2 ...) @end example command. Accepts as inputs one or more words, or a list of words. A global variable is created for each of these words, with that word as its name. The only reason this is necessary is that you might want to use the "setter" notation SETXYZ for a variable XYZ that does not already have a value; GLOBAL "XYZ makes that legal. Note: If there is currently a local variable of the same name, this command does *not* make Logo use the global value instead of the local one. @node PROPERTY LISTS, WORKSPACE PREDICATES, VARIABLE DEFINITION, WORKSPACE MANAGEMENT @section Property Lists Note: Names of property lists are always case-insensitive. Names of individual properties are case-sensitive or case-insensitive depending on the value of @var{CASEIGNOREDP}, which is TRUE by default. @xref{CASEIGNOREDP} . In principle, every possible name is the name of a property list, which is initially empty. So Logo never gives a "no such property list" error, as it would for undefined procedure or variable names. But the primitive procedures that deal with "all" property lists (CONTENTS, PLISTS, etc.) list only nonempty ones. To "erase" a property list @ref{ERASE} means to make it empty, removing all properties from it. @menu * PPROP:: * GPROP:: * REMPROP:: * PLIST:: @end menu @node PPROP, GPROP, PROPERTY LISTS, PROPERTY LISTS @unnumberedsubsec pprop @cindex pprop @example PPROP plistname propname value @end example command. Adds a property to the @code{plistname} property list with name @code{propname} and value @code{value}. @node GPROP, REMPROP, PPROP, PROPERTY LISTS @unnumberedsubsec gprop @cindex gprop @example GPROP plistname propname @end example outputs the value of the @code{propname} property in the @code{plistname} property list, or the empty list if there is no such property. @node REMPROP, PLIST, GPROP, PROPERTY LISTS @unnumberedsubsec remprop @cindex remprop @example REMPROP plistname propname @end example command. Removes the property named @code{propname} from the property list named @code{plistname}. @node PLIST, , REMPROP, PROPERTY LISTS @unnumberedsubsec plist @cindex plist @example PLIST plistname @end example outputs a list whose odd-numbered members are the names, and whose even-numbered members are the values, of the properties in the property list named @code{plistname}. The output is a copy of the actual property list; changing properties later will not magically change a list output earlier by PLIST. @node WORKSPACE PREDICATES, WORKSPACE QUERIES, PROPERTY LISTS, WORKSPACE MANAGEMENT @section Workspace Predicates @menu * PROCEDUREP:: * PRIMITIVEP:: * DEFINEDP:: * NAMEP:: * PLISTP:: @end menu @node PROCEDUREP, PRIMITIVEP, WORKSPACE PREDICATES, WORKSPACE PREDICATES @unnumberedsubsec procedurep @cindex procedurep @cindex procedure? @example PROCEDUREP name PROCEDURE? name @end example outputs TRUE if the input is the name of a procedure. @node PRIMITIVEP, DEFINEDP, PROCEDUREP, WORKSPACE PREDICATES @unnumberedsubsec primitivep @cindex primitivep @cindex primitive? @example PRIMITIVEP name PRIMITIVE? name @end example outputs TRUE if the input is the name of a primitive procedure (one built into Logo). Note that some of the procedures described in this document are library procedures, not primitives. @node DEFINEDP, NAMEP, PRIMITIVEP, WORKSPACE PREDICATES @unnumberedsubsec definedp @cindex definedp @cindex defined? @example DEFINEDP name DEFINED? name @end example outputs TRUE if the input is the name of a user-defined procedure, including a library procedure. (However, Logo does not know about a library procedure until that procedure has been invoked.) @node NAMEP, PLISTP, DEFINEDP, WORKSPACE PREDICATES @unnumberedsubsec namep @cindex namep @cindex name? @example NAMEP name NAME? name @end example outputs TRUE if the input is the name of a variable. @node PLISTP, , NAMEP, WORKSPACE PREDICATES @comment node-name, next, previous, up @unnumberedsubsec plistp @cindex plistp @cindex plist? @example PLISTP name PLIST? name @end example outputs TRUE if the input is the name of a *nonempty* property list. (In principle every word is the name of a property list; if you haven't put any properties in it, PLIST of that name outputs an empty list, rather than giving an error message.) @node WORKSPACE QUERIES, WORKSPACE INSPECTION, WORKSPACE PREDICATES, WORKSPACE MANAGEMENT @section Workspace Queries @menu * CONTENTS:: * BURIED:: * TRACED:: * STEPPED:: * PROCEDURES:: * PRIMITIVES:: * NAMES:: * PLISTS:: * NAMELIST:: * PLLIST:: * ARITY:: * NODES:: @end menu @node CONTENTS, BURIED, WORKSPACE QUERIES, WORKSPACE QUERIES @unnumberedsubsec contents @cindex contents @example CONTENTS @end example outputs a "contents list," i.e., a list of three lists containing names of defined procedures, variables, and property lists respectively. This list includes all unburied named items in the workspace. @node BURIED, TRACED, CONTENTS, WORKSPACE QUERIES @unnumberedsubsec buried @cindex buried @example BURIED @end example outputs a contents list including all buried named items in the workspace. @node TRACED, STEPPED, BURIED, WORKSPACE QUERIES @comment node-name, next, previous, up @unnumberedsubsec traced @cindex traced @example TRACED @end example outputs a contents list including all traced named items in the workspace. @node STEPPED, PROCEDURES, TRACED, WORKSPACE QUERIES @comment node-name, next, previous, up @unnumberedsubsec stepped @cindex stepped @example STEPPED @end example outputs a contents list including all stepped named items in the workspace. @node PROCEDURES, PRIMITIVES, STEPPED, WORKSPACE QUERIES @unnumberedsubsec procedures @cindex procedures @example PROCEDURES @end example outputs a list of the names of all unburied user-defined procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.) @node PRIMITIVES, NAMES, PROCEDURES, WORKSPACE QUERIES @unnumberedsubsec primitives @cindex primitives @example PRIMITIVES @end example outputs a list of the names of all primitive procedures in the workspace. Note that this is a list of names, not a contents list. (However, procedures that require a contents list as input will accept this list.) @node NAMES, PLISTS, PRIMITIVES, WORKSPACE QUERIES @unnumberedsubsec names @cindex names @example NAMES @end example outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace. @node PLISTS, NAMELIST, NAMES, WORKSPACE QUERIES @unnumberedsubsec plists @cindex plists @example PLISTS @end example outputs a contents list consisting of two empty lists (indicating no procedures or variables) followed by a list of all unburied nonempty property lists in the workspace. @node NAMELIST, PLLIST, PLISTS, WORKSPACE QUERIES @unnumberedsubsec namelist @cindex namelist @example NAMELIST varname (library procedure) NAMELIST varnamelist @end example outputs a contents list consisting of an empty list followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. @node PLLIST, ARITY, NAMELIST, WORKSPACE QUERIES @unnumberedsubsec pllist @cindex pllist @example PLLIST plname (library procedure) PLLIST plnamelist @end example outputs a contents list consisting of two empty lists followed by a list of the name or names given as input. This is useful in conjunction with workspace control procedures that require a contents list as input. Note: All procedures whose input is indicated as @code{contentslist} will accept a single word (taken as a procedure name), a list of words (taken as names of procedures), or a list of three lists as described under the CONTENTS command above. @xref{CONTENTS} . @node ARITY, NODES, PLLIST, WORKSPACE QUERIES @unnumberedsubsec arity @cindex arity @example ARITY procedurename @end example outputs a list of three numbers: the minimum, default, and maximum number of inputs for the procedure whose name is the input. It is an error if there is no such procedure. A maximum of -1 means that the number of inputs is unlimited. @node NODES, , ARITY, WORKSPACE QUERIES @unnumberedsubsec nodes @cindex nodes @example NODES @end example outputs a list of two numbers. The first represents the number of nodes of memory currently in use. The second shows the maximum number of nodes that have been in use at any time since the last invocation of NODES. (A node is a small block of computer memory as used by Logo. Each number uses one node. Each non-numeric word uses one node, plus some non-node memory for the characters in the word. Each array takes one node, plus some non-node memory, as well as the memory required by its elements. Each list requires one node per element, as well as the memory within the elements.) If you want to track the memory use of an algorithm, it is best if you invoke GC at the beginning of each iteration, since otherwise the maximum will include storage that is unused but not yet collected. @node WORKSPACE INSPECTION, WORKSPACE CONTROL, WORKSPACE QUERIES, WORKSPACE MANAGEMENT @section Workspace Inspection @menu * PO:: * POALL:: * POPS:: * PONS:: * POPLS:: * PON:: * POPL:: * POT:: * POTS:: @end menu @node PO, POALL, WORKSPACE INSPECTION, WORKSPACE INSPECTION @unnumberedsubsec po @cindex printout @cindex po @example PRINTOUT contentslist PO contentslist @end example command. Prints to the write stream the definitions of all procedures, variables, and property lists named in the input contents list. @node POALL, POPS, PO, WORKSPACE INSPECTION @unnumberedsubsec poall @cindex poall @example POALL (library procedure) @end example command. Prints all unburied definitions in the workspace. Abbreviates @w{@t{PO CONTENTS}}. @xref{CONTENTS} . @node POPS, PONS, POALL, WORKSPACE INSPECTION @unnumberedsubsec pops @cindex pops @example POPS (library procedure) @end example command. Prints the definitions of all unburied procedures in the workspace. Abbreviates @w{@t{PO PROCEDURES}}. @xref{PO} , @ref{PROCEDURES} . @node PONS, POPLS, POPS, WORKSPACE INSPECTION @unnumberedsubsec pons @cindex pons @example PONS (library procedure) @end example command. Prints the definitions of all unburied variables in the workspace. Abbreviates @w{@t{PO NAMES}}. @xref{PO} , @ref{NAMES} . @node POPLS, PON, PONS, WORKSPACE INSPECTION @unnumberedsubsec popls @cindex popls @example POPLS (library procedure) @end example command. Prints the contents of all unburied nonempty property lists in the workspace. Abbreviates @w{@t{PO PLISTS}}. @xref{PO} , @ref{PLISTS} . @node PON, POPL, POPLS, WORKSPACE INSPECTION @unnumberedsubsec pon @cindex pon @example PON varname (library procedure) PON varnamelist @end example command. Prints the definitions of the named variable(s). @* Abbreviates @w{@t{PO NAMELIST varname(list)}}. @xref{PO} , @ref{NAMELIST} . @node POPL, POT, PON, WORKSPACE INSPECTION @unnumberedsubsec popl @cindex popl @example POPL plname (library procedure) POPL plnamelist @end example command. Prints the definitions of the named property list(s). @* Abbreviates @w{@t{PO PLLIST plname(list)}}. @xref{PO} , @ref{PLLIST} . @node POT, POTS, POPL, WORKSPACE INSPECTION @unnumberedsubsec pot @cindex pot @example POT contentslist @end example command. Prints the title lines of the named procedures and the definitions of the named variables and property lists. For property lists, the entire list is shown on one line instead of as a series of PPROP instructions as in PO. @xref{PPROP} , @ref{PO} . @node POTS, , POT, WORKSPACE INSPECTION @unnumberedsubsec pots @cindex pots @example POTS (library procedure) @end example command. Prints the title lines of all unburied procedures in the workspace. Abbreviates @w{@t{POT PROCEDURES}}. @xref{PROCEDURES} . @node WORKSPACE CONTROL, , WORKSPACE INSPECTION, WORKSPACE MANAGEMENT @section Workspace Control @menu * ERASE:: * ERALL:: * ERPS:: * ERNS:: * ERPLS:: * ERN:: * ERPL:: * BURY:: * BURYALL:: * BURYNAME:: * UNBURY:: * UNBURYALL:: * UNBURYNAME:: * BURIEDP:: * TRACE:: * UNTRACE:: * TRACEDP:: * STEP:: * UNSTEP:: * STEPPEDP:: * EDIT:: * EDITFILE:: * EDALL:: * EDPS:: * EDNS:: * EDPLS:: * EDN:: * EDPL:: * SAVE:: * SAVEL:: * LOAD:: * CSLSLOAD:: * HELP:: * SETEDITOR:: * SETLIBLOC:: * SETHELPLOC:: * SETCSLSLOC:: * SETTEMPLOC:: * GC:: * .SETSEGMENTSIZE:: @end menu @node ERASE, ERALL, WORKSPACE CONTROL, WORKSPACE CONTROL @unnumberedsubsec erase @cindex erase @cindex er @example ERASE contentslist ER contentslist @end example command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable @var{REDEFP} has the value TRUE. @xref{REDEFP} . @node ERALL, ERPS, ERASE, WORKSPACE CONTROL @unnumberedsubsec erall @cindex erall @example ERALL @end example command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates @w{@t{ERASE CONTENTS}}. @xref{CONTENTS} . @node ERPS, ERNS, ERALL, WORKSPACE CONTROL @unnumberedsubsec erps @cindex erps @example ERPS @end example command. Erases all unburied procedures from the workspace. @* Abbreviates @w{@t{ERASE PROCEDURES}}. @xref{ERASE} , @ref{PROCEDURES} . @node ERNS, ERPLS, ERPS, WORKSPACE CONTROL @unnumberedsubsec erns @cindex erns @example ERNS @end example command. Erases all unburied variables from the workspace. Abbreviates @w{@t{ERASE NAMES}}. @xref{ERASE} , @ref{NAMES} . @node ERPLS, ERN, ERNS, WORKSPACE CONTROL @unnumberedsubsec erpls @cindex erpls @example ERPLS @end example command. Erases all unburied property lists from the workspace. @* Abbreviates @w{@t{ERASE PLISTS}}. @xref{ERASE} , @ref{PLISTS} . @node ERN, ERPL, ERPLS, WORKSPACE CONTROL @unnumberedsubsec ern @cindex ern @example ERN varname (library procedure) ERN varnamelist @end example command. Erases from the workspace the variable(s) named in the input. Abbreviates @w{@t{ERASE NAMELIST varname(list)}}. @xref{ERASE} , @ref{NAMELIST} . @node ERPL, BURY, ERN, WORKSPACE CONTROL @unnumberedsubsec erpl @cindex erpl @example ERPL plname (library procedure) ERPL plnamelist @end example command. Erases from the workspace the property list(s) named in the input. Abbreviates @w{@t{ERASE PLLIST plname(list)}}. @xref{ERASE} , @ref{PLLIST} . @node BURY, BURYALL, ERPL, WORKSPACE CONTROL @unnumberedsubsec bury @cindex bury @example BURY contentslist @end example command. Buries the procedures, variables, and property lists named in the input. A buried item is not included in the lists output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is included in the list output by BURIED. By implication, buried things are not printed by POALL or saved by SAVE. @xref{CONTENTS} , @ref{PROCEDURES} , @ref{PONS} , @ref{PLISTS} , @ref{POALL} , @ref{SAVE} . @node BURYALL, BURYNAME, BURY, WORKSPACE CONTROL @unnumberedsubsec buryall @cindex buryall @example BURYALL (library procedure) @end example command. Abbreviates @t{BURY CONTENTS}. @xref{CONTENTS} . @node BURYNAME, UNBURY, BURYALL, WORKSPACE CONTROL @unnumberedsubsec buryname @cindex buryname @example BURYNAME varname (library procedure) BURYNAME varnamelist @end example command. Abbreviates @t{BURY NAMELIST varname(list)}. @xref{BURY} , @ref{NAMELIST} . @node UNBURY, UNBURYALL, BURYNAME, WORKSPACE CONTROL @unnumberedsubsec unbury @cindex unbury @example UNBURY contentslist @end example command. Unburies the procedures, variables, and property lists named in the input. That is, the named items will be returned to view in CONTENTS, etc. @xref{CONTENTS} . @node UNBURYALL, UNBURYNAME, UNBURY, WORKSPACE CONTROL @unnumberedsubsec unburyall @cindex unburyall @example UNBURYALL (library procedure) @end example command. Abbreviates @t{UNBURY BURIED}. @xref{BURIED} . @node UNBURYNAME, BURIEDP, UNBURYALL, WORKSPACE CONTROL @unnumberedsubsec unburyname @cindex unburyname @example UNBURYNAME varname (library procedure) UNBURYNAME varnamelist @end example command. Abbreviates @t{UNBURY NAMELIST varname(list)}. @xref{UNBURY} , @ref{NAMELIST} . @node BURIEDP, TRACE, UNBURYNAME, WORKSPACE CONTROL @comment node-name, next, previous, up @unnumberedsubsec buriedp @cindex buriedp @cindex buried? @example BURIEDP contentslist BURIED? contentslist @end example outputs TRUE if the first procedure, variable, or property list named in the contents list is buried, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can @code{BURIEDP [[] [VARIABLE]]} or @code{BURIEDP [[] [] [PROPLIST]]}. @node TRACE, UNTRACE, BURIEDP, WORKSPACE CONTROL @unnumberedsubsec trace @cindex trace @example TRACE contentslist @end example command. Marks the named items for tracing. A message is printed whenever a traced procedure is invoked, giving the actual input values, and whenever a traced procedure STOPs or OUTPUTs. A message is printed whenever a new value is assigned to a traced variable using MAKE. A message is printed whenever a new property is given to a traced property list using PPROP. @xref{STOP} , @ref{OUTPUT} , @ref{MAKE} , @ref{PPROP} . @node UNTRACE, TRACEDP, TRACE, WORKSPACE CONTROL @unnumberedsubsec untrace @cindex untrace @example UNTRACE contentslist @end example command. Turns off tracing for the named items. @node TRACEDP, STEP, UNTRACE, WORKSPACE CONTROL @comment node-name, next, previous, up @unnumberedsubsec tracedp @cindex tracedp @cindex traced? @example TRACEDP contentslist TRACED? contentslist @end example outputs TRUE if the first procedure, variable, or property list named in the contents list is traced, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can @code{TRACEDP [[] [VARIABLE]]} or @code{TRACEDP [[] [] [PROPLIST]]}. @node STEP, UNSTEP, TRACEDP, WORKSPACE CONTROL @unnumberedsubsec step @cindex step @example STEP contentslist @end example command. Marks the named items for stepping. Whenever a stepped procedure is invoked, each instruction line in the procedure body is printed before being executed, and Logo waits for the user to type a newline at the terminal. A message is printed whenever a stepped variable name is @samp{shadowed} because a local variable of the same name is created either as a procedure input or by the LOCAL command. @xref{LOCAL} . @node UNSTEP, STEPPEDP, STEP, WORKSPACE CONTROL @unnumberedsubsec unstep @cindex unstep @example UNSTEP contentslist @end example command. Turns off stepping for the named items. @node STEPPEDP, EDIT, UNSTEP, WORKSPACE CONTROL @comment node-name, next, previous, up @unnumberedsubsec steppedp @cindex steppedp @cindex stepped? @example STEPPEDP contentslist STEPPED? contentslist @end example outputs TRUE if the first procedure, variable, or property list named in the contents list is stepped, FALSE if not. Only the first thing in the list is tested; the most common use will be with a word as input, naming a procedure, but a contents list is allowed so that you can @code{STEPPEDP [[] [VARIABLE]]} or @code{STEPPEDP [[] [] [PROPLIST]]}. @node EDIT, EDITFILE, STEPPEDP, WORKSPACE CONTROL @unnumberedsubsec edit @cindex editor @cindex temp @cindex edit @cindex ed @example EDIT contentslist ED contentslist (EDIT) (ED) @end example command. If invoked with an input, EDIT writes the definitions of the named items into a temporary file and edits that file, using your favorite editor as determined by the @var{EDITOR} environment variable. If you don't have an @var{EDITOR} variable, edits the definitions using jove. If invoked without an input, EDIT edits the same file left over from a previous EDIT or EDITFILE instruction. When you leave the editor, Logo reads the revised definitions and modifies the workspace accordingly. It is not an error if the input includes names for which there is no previous definition. If there is a variable @var{LOADNOISILY} whose value is TRUE, then, after leaving the editor, TO commands in the temporary file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if @var{LOADNOISILY} is FALSE or undefined, TO commands in the file are carried out silently. If there is an environment variable called @var{TEMP}, then Logo uses its value as the directory in which to write the temporary file used for editing. Exceptionally, the EDIT command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. @xref{LOADNOISILY} , @xref{EDITFILE} . @node EDITFILE, EDALL, EDIT, WORKSPACE CONTROL @comment node-name, next, previous, up @unnumberedsubsec editfile @cindex editfile @example EDITFILE filename @end example command. Starts the Logo editor, like EDIT, but instead of editing a temporary file it edits the file specified by the input. When you leave the editor, Logo reads the revised file, as for EDIT. EDITFILE also remembers the filename, so that a subsequent EDIT command with no input will re-edit the same file. EDITFILE is intended as an alternative to LOAD and SAVE. You can maintain a workspace file yourself, controlling the order in which definitions appear, maintaining comments in the file, and so on. @node EDALL, EDPS, EDITFILE, WORKSPACE CONTROL @unnumberedsubsec edall @cindex edall @example EDALL (library procedure) @end example command. Abbreviates @t{EDIT CONTENTS}. @xref{CONTENTS} . @node EDPS, EDNS, EDALL, WORKSPACE CONTROL @unnumberedsubsec edps @cindex edps @example EDPS (library procedure) @end example command. Abbreviates @t{EDIT PROCEDURES}. @xref{EDIT} , @ref{PROCEDURES} . @node EDNS, EDPLS, EDPS, WORKSPACE CONTROL @unnumberedsubsec edns @cindex edns @example EDNS (library procedure) @end example command. Abbreviates @t{EDIT NAMES}. @xref{EDIT} , @ref{NAMES} . @node EDPLS, EDN, EDNS, WORKSPACE CONTROL @unnumberedsubsec edpls @cindex edpls @example EDPLS (library procedure) @end example command. Abbreviates @t{EDIT PLISTS}. @xref{EDIT} , @ref{PLISTS} . @node EDN, EDPL, EDPLS, WORKSPACE CONTROL @unnumberedsubsec edn @cindex edn @example EDN varname (library procedure) EDN varnamelist @end example command. Abbreviates @t{EDIT NAMELIST varname(list)}. @xref{EDIT} , @ref{NAMELIST} . @node EDPL, SAVE, EDN, WORKSPACE CONTROL @unnumberedsubsec edpl @cindex edpl @example EDPL plname (library procedure) EDPL plnamelist @end example command. Abbreviates @t{EDIT PLLIST plname(list)}. @xref{EDIT} , @ref{PLLIST} . @node SAVE, SAVEL, EDPL, WORKSPACE CONTROL @unnumberedsubsec save @cindex save @example SAVE filename @end example command. Saves the definitions of all unburied procedures, variables, and nonempty property lists in the named file. Equivalent to @example to save :filename local "oldwriter make "oldwriter writer openwrite :filename setwrite :filename poall setwrite :oldwriter close :filename end @end example @node SAVEL, LOAD, SAVE, WORKSPACE CONTROL @unnumberedsubsec savel @cindex savel @example SAVEL contentslist filename (library procedure) @end example command. Saves the definitions of the procedures, variables, and property lists specified by @code{contentslist} to the file named @code{filename}. @node LOAD, CSLSLOAD, SAVEL, WORKSPACE CONTROL @unnumberedsubsec load @cindex load @example LOAD filename @end example command. Reads instructions from the named file and executes them. The file can include procedure definitions with TO, and these are accepted even if a procedure by the same name already exists. If the file assigns a list value to a variable named @var{STARTUP}, then that list is run as an instructionlist after the file is loaded. If there is a variable @var{LOADNOISILY} whose value is TRUE, then TO commands in the file print "PROCNAME defined" (where PROCNAME is the name of the procedure being defined); if @var{LOADNOISILY} is FALSE or undefined, TO commands in the file are carried out silently. @xref{STARTUP} , @xref{LOADNOISILY} . @node CSLSLOAD, HELP, LOAD, WORKSPACE CONTROL @unnumberedsubsec cslsload @cindex cslsload @example CSLSLOAD name @end example command. Loads the named file, like LOAD, but from the directory containing the Computer Science Logo Style programs instead of the current user's directory. @xref{LOAD} . @node HELP, SETEDITOR, CSLSLOAD, WORKSPACE CONTROL @unnumberedsubsec help @cindex logohelp @cindex help @example HELP name (HELP) @end example command. Prints information from the reference manual about the primitive procedure named by the input. With no input, lists all the primitives about which help is available. If there is an environment variable @var{LOGOHELP}, then its value is taken as the directory in which to look for help files, instead of the default help directory. If HELP is called with the name of a defined procedure for which there is no help file, it will print the title line of the procedure followed by lines from the procedure body that start with semicolon, stopping when a non-semicolon line is seen. Exceptionally, the HELP command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. @node SETEDITOR, SETLIBLOC, HELP, WORKSPACE CONTROL @unnumberedsubsec seteditor @cindex seteditor @example SETEDITOR path @end example command. Tells Logo to use the specified program as its editor instead of the default editor. The format of a path depends on your operating system. @node SETLIBLOC, SETCSLSLOC, SETEDITOR, WORKSPACE CONTROL @unnumberedsubsec setlibloc @cindex setlibloc @example SETLIBLOC path @end example command. Tells Logo to use the specified directory as its library instead of the default. (Note that many Logo "primitive" procedures are actually found in the library, so they may become unavailable if your new library does not include them!) The format of a path depends on your operating system. @node SETCSLSLOC, SETHELPLOC, SETLIBLOC, WORKSPACE CONTROL @unnumberedsubsec setcslsloc @cindex setcslsloc @example SETCSLSLOC path @end example command. Tells Logo to use the specified directory for the CSLSLOAD command, instead of the default directory. The format of a path depends on your operating system. @xref{CSLSLOAD} . @node SETHELPLOC, SETTEMPLOC, SETCSLSLOC, WORKSPACE CONTROL @unnumberedsubsec sethelploc @cindex sethelploc @example SETHELPLOC path @end example command. Tells Logo to look in the specified directory for the information provided by the HELP command, instead of the default directory. The format of a path depends on your operating system. @node SETTEMPLOC, GC, SETHELPLOC, WORKSPACE CONTROL @unnumberedsubsec settemploc @cindex settemploc @example SETTEMPLOC path @end example command. Tells Logo to write editor temporary files in the specified directory rather than in the default directory. You must have write permission for this directory. The format of a path depends on your operating system. @node GC, .SETSEGMENTSIZE, SETTEMPLOC, WORKSPACE CONTROL @unnumberedsubsec gc @cindex gc @example GC (GC anything) @end example command. Runs the garbage collector, reclaiming unused nodes. Logo does this when necessary anyway, but you may want to use this command to control exactly when Logo does it. In particular, the numbers output by the NODES operation will not be very meaningful unless garbage has been collected. Another reason to use GC is that a garbage collection takes a noticeable fraction of a second, and you may want to schedule collections for times before or after some time-critical animation. If invoked with an argument (of any value), GC runs a full garbage collection, including GCTWA (Garbage Collect Truly Worthless Atoms, which means that it removes from Logo's memory words that used to be procedure or variable names but aren't any more); without an argument, GC does a generational garbage collection, which means that only recently created nodes are examined. (The latter is usually good enough.) @node .SETSEGMENTSIZE, , GC, WORKSPACE CONTROL @unnumberedsubsec .setsegmentsize @cindex .setsegmentsize @example .SETSEGMENTSIZE num @end example command. Sets the number of nodes that Logo allocates from the operating system at once to num, which mush be a positive integer. The name is dotted because bad things will happen if you use a number that's too small or too large for your computer. The initial value is 16,000 for most systems, but is smaller for 68000-based Macs. Making it larger will speed up computations (by reducing the number of garbage collections) at the cost of allocating more memory than necessary. @node CONTROL STRUCTURES, MACROS, WORKSPACE MANAGEMENT, Top @chapter Control Structures @menu * CONTROL:: * TEMPLATE-BASED ITERATION:: @end menu @node CONTROL, TEMPLATE-BASED ITERATION, CONTROL STRUCTURES, CONTROL STRUCTURES @section Control Note: in the following descriptions, an @code{instructionlist} can be a list or a word. In the latter case, the word is parsed into list form before it is run. Thus, @t{RUN READWORD} or @t{RUN READLIST} will work. The former is slightly preferable because it allows for a continued line (with ~) that includes a comment (with ;) on the first line. A @code{tf} input must be the word TRUE, the word FALSE, or a list. If it's a list, then it must be a Logo expression, which will be evaluated to produce a value that must be TRUE or FALSE. The comparisons with TRUE and FALSE are always case-insensitive. @menu * RUN:: * RUNRESULT:: * REPEAT:: * FOREVER:: * REPCOUNT:: * IF:: * IFELSE:: * TEST:: * IFTRUE:: * IFFALSE:: * STOP:: * OUTPUT:: * CATCH:: * THROW:: * ERROR:: * PAUSE:: * CONTINUE:: * WAIT:: * BYE:: * dMAYBEOUTPUT:: MAYBEOUTPUT * GOTO:: * TAG:: * IGNORE:: * back-quote:: * FOR:: * DOdWHILE:: DO.WHILE * WHILE:: * DOdUNTIL:: DO.UNTIL * UNTIL:: * CASE:: * COND:: @end menu @node RUN, RUNRESULT, CONTROL, CONTROL @unnumberedsubsec run @cindex run @example RUN instructionlist @end example command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs. @xref{READWORD} , @ref{READLIST} . @node RUNRESULT, REPEAT, RUN, CONTROL @unnumberedsubsec runresult @cindex runresult @example RUNRESULT instructionlist @end example runs the instructions in the input; outputs an empty list if those instructions produce no output, or a list whose only member is the output from running the input instructionlist. Useful for inventing command-or-operation control structures: @example local "result make "result runresult [something] if emptyp :result [stop] output first :result @end example @node REPEAT, FOREVER, RUNRESULT, CONTROL @unnumberedsubsec repeat @cindex repeat @example REPEAT num instructionlist @end example command. Runs the @code{instructionlist} repeatedly, @code{num} times. @node FOREVER, REPCOUNT, REPEAT, CONTROL @comment node-name, next, previous, up @unnumberedsubsec forever @cindex forever @example FOREVER instructionlist @end example command. Runs the "instructionlist" repeatedly, until something inside the instructionlist (such as STOP or THROW) makes it stop. @xref{STOP} , @xref{THROW} . @node REPCOUNT, IF, FOREVER, CONTROL @unnumberedsubsec repcount @cindex repcount @example REPCOUNT @end example outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs --1. @node IF, IFELSE, REPCOUNT, CONTROL @unnumberedsubsec if @cindex if @example IF tf instructionlist (IF tf instructionlist1 instructionlist2) @end example command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE. For compatibility with earlier versions of Logo, if an IF instruction is not enclosed in parentheses, but the first thing on the instruction line after the second input expression is a literal list (i.e., a list in square brackets), the IF is treated as if it were IFELSE, but a warning message is given. If this aberrant IF appears in a procedure body, the warning is given only the first time the procedure is invoked in each Logo session. @node IFELSE, TEST, IF, CONTROL @unnumberedsubsec ifelse @cindex ifelse @example IFELSE tf instructionlist1 instructionlist2 @end example command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value. @node TEST, IFTRUE, IFELSE, CONTROL @unnumberedsubsec test @cindex test @example TEST tf @end example command. Remembers its input, which must be TRUE or FALSE, for use by later IFTRUE or IFFALSE instructions. The effect of TEST is local to the procedure in which it is used; any corresponding IFTRUE or IFFALSE must be in the same procedure or a subprocedure. @xref{IFFALSE} . @node IFTRUE, IFFALSE, TEST, CONTROL @unnumberedsubsec iftrue @cindex iftrue @cindex ift @example IFTRUE instructionlist IFT instructionlist @end example command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure. @node IFFALSE, STOP, IFTRUE, CONTROL @unnumberedsubsec iffalse @cindex iffalse @cindex iff @example IFFALSE instructionlist IFF instructionlist @end example command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure. @xref{TEST} . @node STOP, OUTPUT, IFFALSE, CONTROL @unnumberedsubsec stop @cindex stop @example STOP @end example command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value. @node OUTPUT, CATCH, STOP, CONTROL @unnumberedsubsec output @cindex output @cindex op @example OUTPUT value OP value @end example command. Ends the running of the procedure in which it appears. That procedure outputs the value @code{value} to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation. @node CATCH, THROW, OUTPUT, CONTROL @unnumberedsubsec catch @cindex catch @example CATCH tag instructionlist @end example command or operation. Runs its second input. Outputs if that instructionlist outputs. If, while running the instructionlist, a THROW instruction is executed with a tag equal to the first input (case-insensitive comparison), then the running of the instructionlist is terminated immediately. In this case the CATCH outputs if a value input is given to THROW. The @code{tag} must be a word. If the tag is the word ERROR, then any error condition that arises during the running of the instructionlist has the effect of THROW "ERROR instead of printing an error message and returning to toplevel. The CATCH does not output if an error is caught. Also, during the running of the instructionlist, the variable @var{ERRACT} is temporarily unbound. (If there is an error while @var{ERRACT} has a value, that value is taken as an instructionlist to be run after printing the error message. Typically the value of @var{ERRACT}, if any, is the list [PAUSE].) @xref{ERROR} , @ref{ERRACT} , @ref{PAUSE} . @node THROW, ERROR, CATCH, CONTROL @unnumberedsubsec throw @cindex throw @example THROW tag (THROW tag value) @end example command. Must be used within the scope of a CATCH with an equal tag. Ends the running of the instructionlist of the CATCH. If THROW is used with only one input, the corresponding CATCH does not output a value. If THROW is used with two inputs, the second provides an output for the CATCH. @w{@t{THROW "TOPLEVEL}} can be used to terminate all running procedures and interactive pauses, and return to the toplevel instruction prompt. Typing the system interrupt character (normally @key{control-C} for Unix, @key{control-Q} for DOS, or @key{command-period} for Mac) has the same effect. @w{@t{THROW "ERROR}} can be used to generate an error condition. If the error is not caught, it prints a message (THROW "ERROR) with the usual indication of where the error (in this case the THROW) occurred. If a second input is used along with a tag of ERROR, that second input is used as the text of the error message instead of the standard message. Also, in this case, the location indicated for the error will be, not the location of the THROW, but the location where the procedure containing the THROW was invoked. This allows user-defined procedures to generate error messages as if they were primitives. Note: in this case the corresponding @w{@t{CATCH "ERROR}}, if any, does not output, since the second input to THROW is not considered a return value. @w{@t{THROW "SYSTEM}} immediately leaves Logo, returning to the operating system, without printing the usual parting message and without deleting any editor temporary file written by EDIT. @xref{EDIT} . @node ERROR, PAUSE, THROW, CONTROL @unnumberedsubsec error @cindex error @example ERROR @end example outputs a list describing the error just caught, if any. If there was not an error caught since the last use of ERROR, the empty list will be output. The error list contains four members: an integer code corresponding to the type of error, the text of the error message, the name of the procedure in which the error occurred, and the instruction line on which the error occurred. @node PAUSE, CONTINUE, ERROR, CONTROL @unnumberedsubsec pause @cindex pause @example PAUSE @end example command or operation. Enters an interactive pause. The user is prompted for instructions, as at toplevel, but with a prompt that includes the name of the procedure in which PAUSE was invoked. Local variables of that procedure are available during the pause. PAUSE outputs if the pause is ended by a CONTINUE with an input. If the variable @var{ERRACT} exists, and an error condition occurs, the contents of that variable are run as an instructionlist. Typically @var{ERRACT} is given the value [PAUSE] so that an interactive pause will be entered on the event of an error. This allows the user to check values of local variables at the time of the error. Typing the system quit character (normally @key{control-\} for Unix, @key{control-W} for DOS, or @key{command-comma} for Mac) will also enter a pause. @xref{ERRACT} . @node CONTINUE, WAIT, PAUSE, CONTROL @unnumberedsubsec continue @cindex continue @cindex co @example CONTINUE value CO value (CONTINUE) (CO) @end example command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output. Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line. @node WAIT, BYE, CONTINUE, CONTROL @unnumberedsubsec wait @cindex wait @example WAIT time @end example command. Delays further execution for @code{time} 60ths of a second. Also causes any buffered characters destined for the terminal to be printed immediately. @w{@t{WAIT 0}} can be used to achieve this buffer flushing without actually waiting. @node BYE, dMAYBEOUTPUT, WAIT, CONTROL @unnumberedsubsec bye @cindex bye @example BYE @end example command. Exits from Logo; returns to the operating system. @node dMAYBEOUTPUT, GOTO, BYE, CONTROL @unnumberedsubsec .maybeoutput @cindex .maybeoutput @example .MAYBEOUTPUT value (special form) @end example works like OUTPUT except that the expression that provides the input value might not, in fact, output a value, in which case the effect is like STOP. This is intended for use in control structure definitions, for cases in which you don't know whether or not some expression produces a value. Example: @example to invoke :function [:inputs] 2 .maybeoutput apply :function :inputs end ? (invoke "print "a "b "c) a b c ? print (invoke "word "a "b "c) abc @end example This is an alternative to RUNRESULT. It's fast and easy to use, at the cost of being an exception to Logo's evaluation rules. (Ordinarily, it should be an error if the expression that's supposed to provide an input to something doesn't have a value.) @xref{OUTPUT} , @ref{STOP} , @ref{RUNRESULT} . @node GOTO, TAG, dMAYBEOUTPUT, CONTROL @unnumberedsubsec goto @cindex goto @example GOTO word @end example command. Looks for a TAG command with the same input in the same procedure, and continues running the procedure from the location of that TAG. It is meaningless to use GOTO outside of a procedure. @node TAG, IGNORE, GOTO, CONTROL @unnumberedsubsec tag @cindex tag @example TAG quoted.word @end example command. Does nothing. The input must be a literal word following a quotation mark ("), not the result of a computation. Tags are used by the GOTO command. @node IGNORE, back-quote, TAG, CONTROL @unnumberedsubsec ignore @cindex ignore @example IGNORE value (library procedure) @end example command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant. @node back-quote, FOR, IGNORE, CONTROL @unnumberedsubsec ` @cindex ` @example ` list (library procedure) @end example outputs a list equal to its input but with certain substitutions. If a member of the input list is the word @samp{,} (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word @samp{,@@} (comma atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the @samp{,@@} and the instructionlist. Example: @example show `[foo baz ,[bf [a b c]] garply ,@@[bf [a b c]]] @end example will print @example [foo baz [b c] garply b c] @end example A word starting with @samp{,} or @samp{,@@} is treated as if the rest of the word were a one-word list, e.g., @samp{,:foo} is equivalent to @samp{,[:Foo]}. A word starting with @samp{",} (quote comma) or @samp{:,} (colon comma) becomes a word starting with @samp{"} or @samp{:} but with the result of running the substitution (or its first word, if the result is a list) replacing what comes after the comma. Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found: @example ? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f] [a ` [b , [1+2] , [foo 4 d] e] f] ?make "name1 "x ?make "name2 "y ? show `[a `[b ,:,:name1 ,",:name2 d] e] [a ` [b , [:x] , ["y] d] e] @end example @node FOR, DOdWHILE, back-quote, CONTROL @unnumberedsubsec for @cindex for @example FOR forcontrol instructionlist (library procedure) @end example command. The first input must be a list containing three or four members: (1) a word, which will be used as the name of a local variable; (2) a word or list that will be evaluated as by RUN to determine a number, the starting value of the variable; (3) a word or list that will be evaluated to determine a number, the limit value of the variable; (4) an optional word or list that will be evaluated to determine the step size. If the fourth member is missing, the step size will be 1 or --1 depending on whether the limit value is greater than or less than the starting value, respectively. The second input is an instructionlist. The effect of FOR is to run that instructionlist repeatedly, assigning a new value to the control variable (the one named by the first member of the forcontrol list) each time. First the starting value is assigned to the control variable. Then the value is compared to the limit value. FOR is complete when the sign of (current-limit) is the same as the sign of the step size. (If no explicit step size is provided, the instructionlist is always run at least once. An explicit step size can lead to a zero-trip FOR, e.g., @w{@t{FOR [I 1 0 1] ...})}. Otherwise, the instructionlist is run, then the step is added to the current value of the control variable and FOR returns to the comparison step. @example ? for [i 2 7 1.5] [print :i] 2 3.5 5 6.5 ? @end example @xref{RUN} . @node DOdWHILE, WHILE, FOR, CONTROL @unnumberedsubsec do.while @cindex do.while @example DO.WHILE instructionlist tfexpression (library procedure) @end example command. Repeatedly evaluates the @code{instructionlist} as long as the evaluated @ifinfo @code{tfexpression} @end ifinfo @tex @code{tfexpres-sion} @end tex remains TRUE. Evaluates the first input first, so the @code{instructionlist} is always run at least once. The @code{tfexpression} must be an expressionlist whose value when evaluated is TRUE or FALSE. @node WHILE, DOdUNTIL, DOdWHILE, CONTROL @unnumberedsubsec while @cindex while @example WHILE tfexpression instructionlist (library procedure) @end example command. Repeatedly evaluates the @code{instructionlist} as long as the evaluated @ifinfo @code{tfexpression} @end ifinfo @tex @code{tfexpres-sion} @end tex remains TRUE. Evaluates the first input first, so the @code{instructionlist} may never be run at all. The @code{tfexpression} must be an expressionlist whose value when evaluated is TRUE or FALSE. @node DOdUNTIL, UNTIL, WHILE, CONTROL @unnumberedsubsec do.until @cindex do.until @example DO.UNTIL instructionlist tfexpression (library procedure) @end example command. Repeatedly evaluates the @code{instructionlist} as long as the evaluated @ifinfo @code{tfexpression} @end ifinfo @tex @code{tfexpres-sion} @end tex remains FALSE. Evaluates the first input first, so the @code{instructionlist} is always run at least once. The @code{tfexpression} must be an expressionlist whose value when evaluated is TRUE or FALSE. @node UNTIL, CASE, DOdUNTIL, CONTROL @unnumberedsubsec until @cindex until @example UNTIL tfexpression instructionlist (library procedure) @end example command. Repeatedly evaluates the @code{instructionlist} as long as the evaluated @ifinfo @code{tfexpression} @end ifinfo @tex @code{tfexpres-sion} @end tex remains FALSE. Evaluates the first input first, so the @code{instructionlist} may never be run at all. The @code{tfexpression} must be an expressionlist whose value when evaluated is TRUE or FALSE. @node CASE, COND, UNTIL, CONTROL @unnumberedsubsec case @cindex case @example CASE value clauses (library procedure) @end example command or operation. The second input is a list of lists (clauses); each clause is a list whose first element is either a list of values or the word ELSE and whose butfirst is a Logo expression or instruction. CASE examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. If the first input to CASE is a member of the first element of a clause, then the butfirst of that clause is evaluated and CASE outputs its value, if any. If neither of these conditions is met, then CASE goes on to the next clause. If no clause is satisfied, CASE does nothing. Example: @example to vowelp :letter output case :letter [ [[a e i o u] "true] [else "false] ] end @end example @node COND, , CASE, CONTROL @unnumberedsubsec cond @cindex cond @example COND clauses (library procedure) @end example command or operation. The input is a list of lists (clauses); each clause is a list whose first element is either an expression whose value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo expression or instruction. COND examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. Otherwise, the first element of the clause is evaluated; the resulting value must be TRUE or FALSE. If it's TRUE, then the butfirst of that clause is evaluated and COND outputs its value, if any. If the value is FALSE, then COND goes on to the next clause. If no clause is satisfied, COND does nothing. Example: @example to evens :numbers ; select even numbers from a list op cond [ [[emptyp :numbers] []] [[evenp first :numbers] ; assuming EVENP is defined fput first :numbers evens butfirst :numbers] [else evens butfirst :numbers] ] end @end example @node TEMPLATE-BASED ITERATION, , CONTROL, CONTROL STRUCTURES @section Template-based Iteration @cindex template The procedures in this section are iteration tools based on the idea of a @code{template.} This is a generalization of an instruction list or an expression list in which @code{slots} are provided for the tool to insert varying data. Four different forms of template can be used. The most commonly used form for a template is @samp{explicit-slot} form, or @samp{question mark} form. Example: @example ? show map [? * ?] [2 3 4 5] [4 9 16 25] ? @end example In this example, the MAP tool evaluated the template [? * ?] repeatedly, with each of the members of the data list [2 3 4 5] substituted in turn for the question marks. The same value was used for every question mark in a given evaluation. Some tools allow for more than one datum to be substituted in parallel; in these cases the slots are indicated by ?1 for the first datum, ?2 for the second, and so on: @example ? show (map [(word ?1 ?2 ?1)] [a b c] [d e f]) [ada beb cfc] ? @end example If the template wishes to compute the datum number, the form (? 1) is equivalent to ?1, so (? ?1) means the datum whose number is given in datum number 1. Some tools allow additional slot designations, as shown in the individual descriptions. The second form of template is the @samp{named-procedure} form. If the template is a word rather than a list, it is taken as the name of a procedure. That procedure must accept a number of inputs equal to the number of parallel data slots provided by the tool; the procedure is applied to all of the available data in order. That is, if data ?1 through ?3 are available, the template "PROC is equivalent to @w{@t{[PROC ?1 ?2 ?3]}}. @example ? show (map "word [a b c] [d e f]) [ad be cf] ? to dotprod :a :b ; vector dot product op apply "sum (map "product :a :b) end @end example The third form of template is @samp{named-slot} or @samp{lambda} form. This form is indicated by a template list containing more than one member, whose first member is itself a list. The first member is taken as a list of names; local variables are created with those names and given the available data in order as their values. The number of names must equal the number of available data. This form is needed primarily when one iteration tool must be used within the template list of another, and the ? notation would be ambiguous in the inner template. Example: @example to matmul :m1 :m2 [:tm2 transpose :m2] ; multiply two matrices output map [[row] map [[col] dotprod :row :col] :tm2] :m1 end @end example The fourth form is @samp{procedure text} form, a variant of lambda form. In this form, the template list contains at least two members, all of which are lists. This is the form used by the DEFINE and TEXT primitives, and APPLY accepts it so that the text of a defined procedure can be used as a template. Note: The fourth form of template is interpreted differently from the others, in that Logo considers it to be an independent defined procedure for the purposes of OUTPUT and STOP. For example, the following two instructions are identical: @example ? print apply [[x] :x+3] [5] 8 ? print apply [[x] [output :x+3]] [5] 8 @end example although the first instruction is in named-slot form and the second is in procedure-text form. The named-slot form can be understood as telling Logo to evaluate the expression @w{@t{:x+3}} in place of the entire invocation of apply, with the variable x temporarily given the value 5. The procedure-text form can be understood as invoking the procedure @example to foo :x output :x+3 end @end example with input 5, but without actually giving the procedure a name. If the use of OUTPUT were interchanged in these two examples, we'd get errors: @example ? print apply [[x] output :x+3] [5] Can only use output inside a procedure ? print apply [[x] [:x+3]] [5] You don't say what to do with 8 @end example The named-slot form can be used with STOP or OUTPUT inside a procedure, to stop the enclosing procedure. The following iteration tools are extended versions of the ones in Appendix B of the book @b{_Computer_Science_Logo_Style,_Volume_3: _Advanced_Topics_ by Brian Harvey [MIT Press, 1987]}. The extensions are primarily to allow for variable numbers of inputs. @menu * APPLY:: * INVOKE:: * FOREACH:: * MAP:: * MAPdSE:: MAP.SE * FILTER:: * FIND:: * REDUCE:: * CROSSMAP:: * CASCADE:: * CASCADEd2:: CASCADE.2 * TRANSFER:: @end menu @node APPLY, INVOKE, TEMPLATE-BASED ITERATION, TEMPLATE-BASED ITERATION @unnumberedsubsec apply @cindex apply @example APPLY template inputlist @end example command or operation. Runs the "template," filling its slots with the members of @code{inputlist.} The number of members in @code{inputlist} must be an acceptable number of slots for @code{template.} It is illegal to apply the primitive TO as a template, but anything else is okay. APPLY outputs what @code{template} outputs, if anything. @xref{TO} . @node INVOKE, FOREACH, APPLY, TEMPLATE-BASED ITERATION @unnumberedsubsec invoke @cindex invoke @example INVOKE template input (library procedure) (INVOKE template input1 input2 ...) @end example command or operation. Exactly like APPLY except that the inputs are provided as separate expressions rather than in a list. @node FOREACH, MAP, INVOKE, TEMPLATE-BASED ITERATION @unnumberedsubsec foreach @cindex foreach @example FOREACH data template (library procedure) (FOREACH data1 data2 ... template) @end example command. Evaluates the template list repeatedly, once for each member of the data list. If more than one data list are given, each of them must be the same length. (The data inputs can be words, in which case the template is evaluated once for each character. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then ?REST would be replaced by @w{[C D E]}. If multiple parallel slots are used, then @w{@t{(?REST 1)}} goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then # would be replaced by 2. @node MAP, MAPdSE, FOREACH, TEMPLATE-BASED ITERATION @unnumberedsubsec map @cindex map @example MAP template data (library procedure) (MAP template data1 data2 ...) @end example outputs a word or list, depending on the type of the data input, of the same length as that data input. (If more than one data input are given, the output is of the same type as data1.) Each member of the output is the result of evaluating the template list, filling the slots with the corresponding member(s) of the data input(s). (All data inputs must be the same length.) In the case of a word output, the results of the template evaluation must be words, and they are concatenated with WORD. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then ?REST would be replaced by @w{[C D E]}. If multiple parallel slots are used, then @w{@t{(?REST 1)}} goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then # would be replaced by 2. @xref{WORD} . @node MAPdSE, FILTER, MAP, TEMPLATE-BASED ITERATION @unnumberedsubsec map.se @cindex map.se @example MAP.SE template data (library procedure) (MAP.SE template data1 data2 ...) @end example outputs a list formed by evaluating the template list repeatedly and concatenating the results using SENTENCE. That is, the members of the output are the members of the results of the evaluations. The output list might, therefore, be of a different length from that of the data input(s). (If the result of an evaluation is the empty list, it contributes nothing to the final output.) The data inputs may be words or lists. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then ?REST would be replaced by @w{[C D E]}. If multiple parallel slots are used, then @w{@t{(?REST 1)}} goes with ?1, etc. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then # would be replaced by 2. @xref{SENTENCE} . @node FILTER, FIND, MAPdSE, TEMPLATE-BASED ITERATION @unnumberedsubsec filter @cindex filter @example FILTER tftemplate data (library procedure) @end example outputs a word or list, depending on the type of the data input, containing a subset of the members (for a list) or characters (for a word) of the input. The template is evaluated once for each member or character of the data, and it must produce a TRUE or FALSE value. If the value is TRUE, then the corresponding input constituent is included in the output. @example ? print filter "vowelp "elephant eea ? @end example In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then ?REST would be replaced by @w{[C D E]}. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then # would be replaced by 2. @node FIND, REDUCE, FILTER, TEMPLATE-BASED ITERATION @unnumberedsubsec find @cindex find @example FIND tftemplate data (library procedure) @end example outputs the first constituent of the data input (the first member of a list, or the first character of a word) for which the value produced by evaluating the template with that consituent in its slot is TRUE. If there is no such constituent, the empty list is output. In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then ?REST would be replaced by @w{[C D E]}. In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is @w{[A B C D E]} and the template is being evaluated with ? replaced by B, then # would be replaced by 2. @node REDUCE, CROSSMAP, FIND, TEMPLATE-BASED ITERATION @unnumberedsubsec reduce @cindex reduce @example REDUCE template data (library procedure) @end example outputs the result of applying the template to accumulate the members of the data input. The template must be a two-slot function. Typically it is an associative function name like "SUM. If the data input has only one constituent (member in a list or character in a word), the output is that consituent. Otherwise, the template is first applied with ?1 filled with the next-to-last consitient and ?2 with the last constituent. Then, if there are more constituents, the template is applied with ?1 filled with the next constituent to the left and ?2 with the result from the previous evaluation. This process continues until all constituents have been used. The data input may not be empty. Note: If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs: @example to max :a :b output ifelse :a > :b [:a] [:b] end @end example @example print reduce "max [...] @end example Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does: @example to max [:inputs] 2 if emptyp :inputs ~ [(throw "error [not enough inputs to max])] output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs end @end example @xref{SUM} , @ref{APPLY} . @node CROSSMAP, CASCADE, REDUCE, TEMPLATE-BASED ITERATION @unnumberedsubsec crossmap @cindex crossmap @example CROSSMAP template listlist (library procedure) (CROSSMAP template data1 data2 ...) @end example outputs a list containing the results of template evaluations. Each data list contributes to a slot in the template; the number of slots is equal to the number of data list inputs. As a special case, if only one data list input is given, that list is taken as a list of data lists, and each of its members contributes values to a slot. CROSSMAP differs from MAP in that instead of taking members from the data inputs in parallel, it takes all possible combinations of members of data inputs, which need not be the same length. @example ? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4]) [a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4] ? @end example For compatibility with the version in the first edition of CSLS @footnote{Computer Science Logo Style}, CROSSMAP templates may use the notation :1 instead of ?1 to indicate slots. @xref{MAP} . @node CASCADE, CASCADEd2, CROSSMAP, TEMPLATE-BASED ITERATION @unnumberedsubsec cascade @cindex cascade @example CASCADE endtest template startvalue (library procedure) (CASCADE endtest tmp1 sv1 tmp2 sv2 ...) (CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate) @end example outputs the result of applying a template (or several templates, as explained below) repeatedly, with a given value filling the slot the first time, and the result of each application filling the slot for the following application. In the simplest case, CASCADE has three inputs. The second input is a one-slot expression template. That template is evaluated some number of times (perhaps zero). On the first evaluation, the slot is filled with the third input; on subsequent evaluations, the slot is filled with the result of the previous evaluation. The number of evaluations is determined by the first input. This can be either a nonnegative integer, in which case the template is evaluated that many times, or a predicate expression template, in which case it is evaluated (with the same slot filler that will be used for the evaluation of the second input) repeatedly, and the CASCADE evaluation continues as long as the predicate value is FALSE. (In other words, the predicate template indicates the condition for stopping.) If the template is evaluated zero times, the output from CASCADE is the third (startvalue) input. Otherwise, the output is the value produced by the last template evaluation. CASCADE templates may include the symbol # to represent the number of times the template has been evaluated. This slot is filled with 1 for the first evaluation, 2 for the second, and so on. @example ? show cascade 5 [lput # ?] [] [1 2 3 4 5] ? show cascade [vowelp first ?] [bf ?] "spring ing ? show cascade 5 [# * ?] 1 120 ? @end example Several cascaded results can be computed in parallel by providing additional template-startvalue pairs as inputs to CASCADE. In this case, all templates (including the endtest template, if used) are multi-slot, with the number of slots equal to the number of pairs of inputs. In each round of evaluations, ?2 represents the result of evaluating the second template in the previous round. If the total number of inputs (including the first endtest input) is odd, then the output from CASCADE is the final value of the first template. If the total number of inputs is even, then the last input is a template that is evaluated once, after the end test is satisfied, to determine the output from CASCADE. @example to fibonacci :n output (cascade :n [?1 + ?2] 1 [?1] 0) end to piglatin :word output (cascade [vowelp first ?] ~ [word bf ? first ?] ~ :word ~ [word ? "ay]) end @end example @node CASCADEd2, TRANSFER, CASCADE, TEMPLATE-BASED ITERATION @unnumberedsubsec cascade.2 @cindex cascade.2 @example CASCADE.2 endtest temp1 startval1 temp2 startval2 (library procedure) @end example outputs the result of invoking CASCADE with the same inputs. The only difference is that the default number of inputs is five instead of three. @node TRANSFER, , CASCADEd2, TEMPLATE-BASED ITERATION @unnumberedsubsec transfer @cindex transfer @example TRANSFER endtest template inbasket (library procedure) @end example outputs the result of repeated evaluation of the template. The template is evaluated once for each member of the list @code{inbasket.} TRANSFER maintains an @code{outbasket} that is initially the empty list. After each evaluation of the template, the resulting value becomes the new outbasket. In the template, the symbol ?IN represents the current member from the inbasket; the symbol ?OUT represents the entire current outbasket. Other slot symbols should not be used. If the first (endtest) input is an empty list, evaluation continues until all inbasket members have been used. If not, the first input must be a predicate expression template, and evaluation continues until either that template's value is TRUE or the inbasket is used up. @node MACROS, ERROR PROCESSING, CONTROL STRUCTURES, Top @chapter Macros @menu * dMACRO:: MACRO * dDEFMACRO:: DEFMACRO * MACROP:: * MACROEXPAND:: @end menu @node dMACRO, dDEFMACRO, MACROS, MACROS @unnumberedsubsec .macro @cindex .macro @cindex .defmacro @example .MACRO procname :input1 :input2 ... (special form) .DEFMACRO procname text @end example A macro is a special kind of procedure whose output is evaluated as Logo instructions in the context of the macro's caller. .MACRO is exactly like TO except that the new procedure becomes a macro; .DEFMACRO is exactly like DEFINE with the same exception. Macros are useful for inventing new control structures comparable to REPEAT, IF, and so on. Such control structures can almost, but not quite, be duplicated by ordinary Logo procedures. For example, here is an ordinary procedure version of REPEAT: @example to my.repeat :num :instructions if :num=0 [stop] run :instructions my.repeat :num-1 :instructions end @end example This version works fine for most purposes, e.g., @example my.repeat 5 [print "hello] @end example But it doesn't work if the instructions to be carried out include OUTPUT, STOP, or LOCAL. For example, consider this procedure: @example to example print [Guess my secret word. You get three guesses.] repeat 3 [type "|?? | ~ if readword = "secret [pr "Right! stop]] print [Sorry, the word was "secret"!] end @end example This procedure works as written, but if MY.REPEAT is used instead of REPEAT, it won't work because the STOP will stop MY.REPEAT instead of stopping EXAMPLE as desired. The solution is to make MY.REPEAT a macro. Instead of actually carrying out the computation, a macro must return a list containing Logo instructions. The contents of that list are evaluated as if they appeared in place of the call to the macro. Here's a macro version of REPEAT: @example .macro my.repeat :num :instructions if :num=0 [output []] output sentence :instructions ~ (list "my.repeat :num-1 :instructions) end @end example Every macro is an operation --- it must always output something. Even in the base case, MY.REPEAT outputs an empty instruction list. To show how MY.REPEAT works, let's take the example @example my.repeat 5 [print "hello] @end example For this example, MY.REPEAT will output the instruction list @example [print "hello my.repeat 4 [print "hello]] @end example Logo then executes these instructions in place of the original invocation of MY.REPEAT; this prints @code{hello} once and invokes another repetition. The technique just shown, although fairly easy to understand, has the defect of slowness because each repetition has to construct an instruction list for evaluation. Another approach is to make my.repeat a macro that works just like the non-macro version unless the instructions to be repeated include OUTPUT or STOP: @example .macro my.repeat :num :instructions catch "repeat.catchtag ~ [op repeat.done runresult [repeat1 :num :instructions]] op [] end to repeat1 :num :instructions if :num=0 [throw "repeat.catchtag] run :instructions .maybeoutput repeat1 :num-1 :instructions end to repeat.done :repeat.result if emptyp :repeat.result [op [stop]] op list "output quoted first :repeat.result end @end example If the instructions do not include STOP or OUTPUT, then REPEAT1 will reach its base case and invoke THROW. As a result, my.repeat's last instruction line will output an empty list, so the second evaluation of the macro result will do nothing. But if a STOP or OUTPUT happens, then REPEAT.DONE will output a STOP or OUTPUT instruction that will be re-executed in the caller's context. The macro-defining commands have names starting with a dot because macros are an advanced feature of Logo; it's easy to get in trouble by defining a macro that doesn't terminate, or by failing to construct the instruction list properly. Lisp users should note that Logo macros are NOT special forms. That is, the inputs to the macro are evaluated normally, as they would be for any other Logo procedure. It's only the output from the macro that's handled unusually. Here's another example: @example .macro localmake :name :value output (list "local~ word "" :name ~ "apply ~ ""make ~ (list :name :value)) end @end example It's used this way: @example to try localmake "garply "hello print :garply end @end example LOCALMAKE outputs the list @display [local "garply apply "make [garply hello]] @end display The reason for the use of APPLY is to avoid having to decide whether or not the second input to MAKE requires a quotation mark before it. (In this case it would --- MAKE "GARPLY "HELLO --- but the quotation mark would be wrong if the value were a list.) It's often convenient to use the @t{`} function to construct the instruction list: @example .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end @end example On the other hand, @t{`} is pretty slow, since it's tree recursive and written in Logo. @xref{TO} , @ref{DEFINE} , @ref{APPLY} , @ref{STOP} , @ref{OUTPUT} . @node dDEFMACRO, MACROP, dMACRO, MACROS @unnumberedsubsec .defmacro @xref{dMACRO} . @node MACROP, MACROEXPAND, dDEFMACRO, MACROS @unnumberedsubsec macrop @cindex macrop @cindex macro? @example MACROP name MACRO? name @end example outputs TRUE if its input is the name of a macro. @node MACROEXPAND, , MACROP, MACROS @unnumberedsubsec macroexpand @cindex macroexpand @example MACROEXPAND expr (library procedure) @end example takes as its input a Logo expression that invokes a macro (that is, one that begins with the name of a macro) and outputs the the Logo expression into which the macro would translate the input expression. @example .macro localmake :name :value op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]] end ? show macroexpand [localmake "pi 3.14159] [local "pi apply "make [pi 3.14159]] @end example @node ERROR PROCESSING, SPECIAL VARIABLES, MACROS, Top @chapter Error Processing @menu * ERROR CODES:: @end menu If an error occurs, Logo takes the following steps. First, if there is an available variable named @var{ERRACT}, Logo takes its value as an instructionlist and runs the instructions. The operation ERROR may be used within the instructions (once) to examine the error condition. If the instructionlist invokes PAUSE, the error message is printed before the pause happens. Certain errors are "recoverable"; for one of those errors, if the instructionlist outputs a value, that value is used in place of the expression that caused the error. (If @var{ERRACT} invokes PAUSE and the user then invokes CONTINUE with an input, that input becomes the output from PAUSE and therefore the output from the @var{ERRACT} instructionlist.) It is possible for an @var{ERRACT} instructionlist to produce an inappropriate value or no value where one is needed. As a result, the same error condition could recur forever because of this mechanism. To avoid that danger, if the same error condition occurs twice in a row from an @var{ERRACT} instructionlist without user interaction, the message "Erract loop" is printed and control returns to toplevel. "Without user interaction" means that if @var{ERRACT} invokes PAUSE and the user provides an incorrect value, this loop prevention mechanism does not take effect and the user gets to try again. During the running of the @var{ERRACT} instructionlist, @var{ERRACT} is locally unbound, so an error in the @var{ERRACT} instructions themselves will not cause a loop. In particular, an error during a pause will not cause a pause-within-a-pause unless the user reassigns the value [PAUSE] to @var{ERRACT} during the pause. But such an error will not return to toplevel; it will remain within the original pause loop. If there is no available @var{ERRACT} value, Logo handles the error by generating an internal @w{@t{THROW "ERROR}}. (A user program can also generate an error condition deliberately by invoking THROW.) If this throw is not caught by a @w{@t{CATCH "ERROR}} in the user program, it is eventually caught either by the toplevel instruction loop or by a pause loop, which prints the error message. An invocation of @w{@t{CATCH "ERROR}} in a user program locally unbinds @var{ERRACT}, so the effect is that whichever of @var{ERRACT} and @w{@t{CATCH "ERROR}} is more local will take precedence. If a floating point overflow occurs during an arithmetic operation, or a two-input mathematical function (like POWER) is invoked with an illegal combination of inputs, the @samp{doesn't like} message refers to the second operand, but should be taken as meaning the combination. @xref{ERRACT} , @ref{THROW} , @ref{ERROR} , @ref{CATCH} , @ref{PAUSE} , @ref{CONTINUE} . @node ERROR CODES, , ERROR PROCESSING, ERROR PROCESSING @section Error Codes @cindex errors Here are the numeric codes that appear as the first member of the list output by ERROR when an error is caught, with the corresponding messages. Some messages may have two different codes depending on whether or not the error is recoverable (that is, a substitute value can be provided through the @var{ERRACT} mechanism) in the specific context. Some messages are warnings rather than errors; these will not be caught. Errors 0 and 32 are so bad that Logo exits immediately. @display 0 Fatal internal error (can't be caught) 1 Out of memory 2 Stack overflow 3 Turtle out of bounds 4 PROC doesn't like DATUM as input (not recoverable) 5 PROC didn't output to PROC 6 Not enough inputs to PROC 7 PROC doesn't like DATUM as input (recoverable) 8 Too much inside ()'s 9 You don't say what to do with DATUM 10 ')' not found 11 VAR has no value 12 Unexpected ')' 13 I don't know how to PROC (recoverable) 14 Can't find catch tag for THROWTAG 15 PROC is already defined 16 Stopped 17 Already dribbling 18 File system error 19 Assuming you mean IFELSE, not IF (warning only) 20 VAR shadowed by local in procedure call (warning only) 21 Throw "Error 22 PROC is a primitive 23 Can't use TO inside a procedure 24 I don't know how to PROC (not recoverable) 25 IFTRUE/IFFALSE without TEST 26 Unexpected ']' 27 Unexpected '@}' 28 Couldn't initialize graphics 29 Macro returned VALUE instead of a list 30 You don't say what to do with VALUE 31 Can only use STOP or OUTPUT inside a procedure 32 APPLY doesn't like BADTHING as input 33 END inside multi-line instruction 34 Really out of memory (can't be caught) @end display @node SPECIAL VARIABLES, INTERNATIONALIZATION, ERROR PROCESSING, Top @chapter Special Variables Logo takes special action if any of the following variable names exists. They follow the normal scoping rules, so a procedure can locally set one of them to limit the scope of its effect. Initially, no variables exist except for @var{ALLOWGETSET}, @var{CASEIGNOREDP}, and @var{UNBURYONEDIT}, which are TRUE and buried. @menu * ALLOWGETSET:: * CASEIGNOREDP:: * ERRACT:: * FULLPRINTP:: * LOADNOISILY:: * PRINTDEPTHLIMIT:: * PRINTWIDTHLIMIT:: * REDEFP:: * STARTUP:: * UNBURYONEDIT:: * USEALTERNATENAMES:: @end menu @node ALLOWGETSET, CASEIGNOREDP, SPECIAL VARIABLES, SPECIAL VARIABLES @comment node-name, next, previous, up @unnumberedsubsec allowgetset @cindex allowgetset @example ALLOWGETSET (variable) @end example if TRUE, indicates that an attempt to use a procedure that doesn't exist should be taken as an implicit getter or setter procedure (setter if the first three letters of the name are SET) for a variable of the same name (without the SET if appropriate). @node CASEIGNOREDP, ERRACT, ALLOWGETSET, SPECIAL VARIABLES @unnumberedsubsec caseignoredp @cindex caseignoredp @example CASEIGNOREDP (variable) @end example if TRUE, indicates that lower case and upper case letters should be considered equal by EQUALP, BEFOREP, MEMBERP, etc. Logo initially makes this variable TRUE, and buries it. @xref{EQUALP} , @ref{BEFOREP} , @ref{MEMBERP} . @node ERRACT, FULLPRINTP, CASEIGNOREDP, SPECIAL VARIABLES @unnumberedsubsec erract @cindex erract @example ERRACT (variable) @end example an instructionlist that will be run in the event of an error. Typically has the value [PAUSE] to allow interactive debugging. @xref{PAUSE} . @node FULLPRINTP, LOADNOISILY, ERRACT, SPECIAL VARIABLES @comment node-name, next, previous, up @unnumberedsubsec fullprintp @cindex fullprintp @example FULLPRINTP @end example if TRUE, then words that were created using backslash or vertical bar (to include characters that would otherwise not be treated as part of a word) are printed with the backslashes or vertical bars shown, so that the printed result could be re-read by Logo to produce the same value. If FULLPRINTP is TRUE then the empty word (however it was created) prints as @code{||}. (Otherwise it prints as nothing at all.) @node LOADNOISILY, PRINTDEPTHLIMIT, FULLPRINTP, SPECIAL VARIABLES @unnumberedsubsec loadnoisily @cindex loadnoisily @example LOADNOISILY (variable) @end example if TRUE, prints the names of procedures defined when loading from a file (including the temporary file made by EDIT). @xref{EDIT} . @node PRINTDEPTHLIMIT, PRINTWIDTHLIMIT, LOADNOISILY, SPECIAL VARIABLES @unnumberedsubsec printdepthlimit @cindex printdepthlimit @example PRINTDEPTHLIMIT (variable) @end example if a nonnegative integer, indicates the maximum depth of sublist structure that will be printed by PRINT, etc. @xref{PRINT} . @node PRINTWIDTHLIMIT, REDEFP, PRINTDEPTHLIMIT, SPECIAL VARIABLES @unnumberedsubsec printwidthlimit @cindex printwidthlimit @example PRINTWIDTHLIMIT (variable) @end example if a nonnegative integer, indicates the maximum number of members in any one list that will be printed by PRINT, etc. @xref{PRINT} . @node REDEFP, STARTUP, PRINTWIDTHLIMIT, SPECIAL VARIABLES @unnumberedsubsec redefp @cindex redefp @example REDEFP (variable) @end example if TRUE, allows primitives to be erased (ERASE) or redefined (COPYDEF). @xref{ERASE} , @ref{COPYDEF} . @node STARTUP, UNBURYONEDIT, REDEFP, SPECIAL VARIABLES @unnumberedsubsec startup @cindex startup @example STARTUP (variable) @end example if assigned a list value in a file loaded by LOAD, that value is run as an instructionlist after the loading. @xref{LOAD} . @node UNBURYONEDIT, USEALTERNATENAMES, STARTUP, SPECIAL VARIABLES @comment node-name, next, previous, up @unnumberedsubsec unburyonedit @cindex unburyonedit @example UNBURYONEDIT (variable) @end example if TRUE, causes any procedure defined during EDIT or LOAD to be unburied, so that it will be saved by a later SAVE. Files that want to define and bury procedures must do it in that order. @xref{EDIT} , @xref{LOAD} , @xref{SAVE} . @node USEALTERNATENAMES, , UNBURYONEDIT, SPECIAL VARIABLES @unnumberedsubsec usealternatenames @cindex usealternatenames @example USEALTERNATENAMES (variable) @end example if TRUE, causes Logo to generate non-English words (from the Messages file) instead of TRUE, FALSE, END, etc. @node INTERNATIONALIZATION, INDEX, SPECIAL VARIABLES, Top @chapter Internationalization Berkeley Logo has limited support for non-English-speaking users. Alas, there is no Unicode support, and high-bit-on ASCII codes work in some contexts but not others. If you want to translate Berkeley Logo for use with another language, there are three main things you have to do: @example 1. Primitive names 2. Error (and other) messages 3. Documentation @end example For primitive names, the easiest thing is to provide a startup file that defines aliases for the English primitive names, using COPYDEF: @example COPYDEF "AVANT "FORWARD @end example This should take care of it, unless your language's name for one primitive is spelled like the English name of a different primitive. In that case you have to turn REDEFP on and be sure to copy the non-conflicting name before overwriting the conflicting one! "Primitives" that are actually in the Logo library, of course, can just be replaced or augmented with native-language-named Logo procedures and filenames. Of course Logo programs will still not look like your native language if the word order is dramatically different, especially if you don't put verbs before their objects. For error messages, there is a file named Messages in the logolib directory with texts of messages, one per line. You can replace this with a file for your own language. Do not add, delete, or reorder lines; Logo finds messages by line number. The sequences @code{%p}, @code{%s}, and @code{%t} in these messages represent variable parts of the message and should not be translated. (%p @code{PRINT}s the variable part, while %s @code{SHOW}s it -- that is, the difference is about whether or not brackets are shown surrounding a list. %t means that the variable part is a C text string rather than a Logo object.) If you want to change the order of two variable parts (no reorderable message has more than two), you would for example replace the line @example %p doesn't like %s as input @end example with @example %+s is a lousy input to %p @end example The plus sign tells the message printer to reverse the order; you must reverse the order of %p and %s, if both are used, to match. The plus sign goes just after the first percent sign in the message, which might not be at the beginning of the line. The sequence @code{\n} in a message represents a newline; don't be fooled into thinking that the "n" is part of the following word. Some messages appear twice in the file; this isn't a mistake. The two spaces before "to" in "I don't know how to" aren't a mistake either. The message containing just "%p" is for user-provided error messages in THROW "ERROR. The message " in %s\n%s" is the part of all error messages that indicates where the error occurred if it was inside a procedure; you might want to change the word "in" to your language. "%s defined\n" is what LOAD prints for each procedure defined if the variable LOADNOISILY is TRUE. "to %p\nend\n\n" is what EDIT puts in the temporary file if you ask to edit a procedure that isn't already defined. Also in the Messages file are lines containing only one word each; the first of these is the word "true". Some of these words are recognized by Logo in user input; some are generated by Logo; some are both. For example, the words TRUE and FALSE are recognized as Boolean values by IF and IFELSE, and are also generated by Logo as outputs from the primitive predicates such as EQUALP. The word END is recognized as the end of a procedure definition, and may be generated when Logo reconstructs a procedure body for PO or EDIT. I've used capital letters in this paragraph for easier reading, but the words in the Messages file should be in lower case. If you replace these with non-English words, Logo will *recognize* both the English names and your alternate names. For example, if you replace the word "true" with "vrai" then Logo will understand both of these: @example IF "TRUE [PRINT "YES] IF "VRAI [PRINT "YES] @end example The variable UseAlternateNames determines whether Logo will *generate* other-language names -- for example, whether predicate functions return the other-language alternates for TRUE and FALSE. This variable is FALSE by default, meaning that the English words will be generated. You might wish to have English-named predicate functions generate English TRUE and FALSE, while other-language-named predicates generate the alternate words. This can be done by leaving UseAlternateNames false, and instead of defining the other-language predicates with COPYDEF, do it this way: @example to french.boolean :bool if equalp :bool "true [output "vrai] if equalp :bool "false [output "faux] output :bool ; shouldn't happen end to make.french.predicate :french :english :arity define :french `[[[inputs] ,[:arity]] [output french.boolean apply ,[word "" :english] :inputs]] end ? make.french.predicate "egal? "equal? 2 ? pr egal? 3 4 faux ? pr egal? 4 4 vrai ? pr equal? 3 4 false ? pr equal? 4 4 true @end example The third input to make.french.predicate is the number of inputs that the predicate expects. This solution isn't quite perfect because the infix predicates (=, <, >) will still output in English. If you want them to generate alternate-language words, set UseAlternateNames to TRUE instead. Some of the words in this section of the Messages file are names of Logo primitives (OUTPUT, STOP, GOTO, TAG, IF, IFELSE, TO, .MACRO). To translate these names, you must use COPYDEF as described earlier, in addition to changing the names in Messages. You should be consistent in these two steps. Don't forget the period in ".macro"! For documentation, there are two kinds: this manual and the help files. The latter are generated automatically from this manual if you have a Unix system, so in that case you need only translate this manual, maintaining the format. (The automatic helpfile generator notices things like capital letters, tabs, hyphens, and equal signs at the beginnings of lines.) The program makefile.c may require modification because a few of the primitive names are special cases (e.g., LOG10 is the only name with digits included). If you don't have Unix tools, you can just translate each helpfile individually. A period in a primitive name is represented as a D in the filename; there are no files for question marks because the HELP command looks for the file named after the corresponding primitive that ends in P. @node INDEX, , INTERNATIONALIZATION, Top @unnumbered INDEX @printindex cp @shortcontents @contents @bye ucblogo-5.5/docs/ucblogo.info-50100644000161300001330000006662510276035443014354 0ustar bhdoeThis is ucblogo.info, produced by makeinfo version 4.5 from usermanual.texi.  File: ucblogo.info, Node: INTERNATIONALIZATION, Next: INDEX, Prev: SPECIAL VARIABLES, Up: Top Internationalization ******************** Berkeley Logo has limited support for non-English-speaking users. Alas, there is no Unicode support, and high-bit-on ASCII codes work in some contexts but not others. If you want to translate Berkeley Logo for use with another language, there are three main things you have to do: 1. Primitive names 2. Error (and other) messages 3. Documentation For primitive names, the easiest thing is to provide a startup file that defines aliases for the English primitive names, using COPYDEF: COPYDEF "AVANT "FORWARD This should take care of it, unless your language's name for one primitive is spelled like the English name of a different primitive. In that case you have to turn REDEFP on and be sure to copy the non-conflicting name before overwriting the conflicting one! "Primitives" that are actually in the Logo library, of course, can just be replaced or augmented with native-language-named Logo procedures and filenames. Of course Logo programs will still not look like your native language if the word order is dramatically different, especially if you don't put verbs before their objects. For error messages, there is a file named Messages in the logolib directory with texts of messages, one per line. You can replace this with a file for your own language. Do not add, delete, or reorder lines; Logo finds messages by line number. The sequences `%p', `%s', and `%t' in these messages represent variable parts of the message and should not be translated. (%p `PRINT's the variable part, while %s `SHOW's it - that is, the difference is about whether or not brackets are shown surrounding a list. %t means that the variable part is a C text string rather than a Logo object.) If you want to change the order of two variable parts (no reorderable message has more than two), you would for example replace the line %p doesn't like %s as input with %+s is a lousy input to %p The plus sign tells the message printer to reverse the order; you must reverse the order of %p and %s, if both are used, to match. The plus sign goes just after the first percent sign in the message, which might not be at the beginning of the line. The sequence `\n' in a message represents a newline; don't be fooled into thinking that the "n" is part of the following word. Some messages appear twice in the file; this isn't a mistake. The two spaces before "to" in "I don't know how to" aren't a mistake either. The message containing just "%p" is for user-provided error messages in THROW "ERROR. The message " in %s\n%s" is the part of all error messages that indicates where the error occurred if it was inside a procedure; you might want to change the word "in" to your language. "%s defined\n" is what LOAD prints for each procedure defined if the variable LOADNOISILY is TRUE. "to %p\nend\n\n" is what EDIT puts in the temporary file if you ask to edit a procedure that isn't already defined. Also in the Messages file are lines containing only one word each; the first of these is the word "true". Some of these words are recognized by Logo in user input; some are generated by Logo; some are both. For example, the words TRUE and FALSE are recognized as Boolean values by IF and IFELSE, and are also generated by Logo as outputs from the primitive predicates such as EQUALP. The word END is recognized as the end of a procedure definition, and may be generated when Logo reconstructs a procedure body for PO or EDIT. I've used capital letters in this paragraph for easier reading, but the words in the Messages file should be in lower case. If you replace these with non-English words, Logo will *recognize* both the English names and your alternate names. For example, if you replace the word "true" with "vrai" then Logo will understand both of these: IF "TRUE [PRINT "YES] IF "VRAI [PRINT "YES] The variable UseAlternateNames determines whether Logo will *generate* other-language names - for example, whether predicate functions return the other-language alternates for TRUE and FALSE. This variable is FALSE by default, meaning that the English words will be generated. You might wish to have English-named predicate functions generate English TRUE and FALSE, while other-language-named predicates generate the alternate words. This can be done by leaving UseAlternateNames false, and instead of defining the other-language predicates with COPYDEF, do it this way: to french.boolean :bool if equalp :bool "true [output "vrai] if equalp :bool "false [output "faux] output :bool ; shouldn't happen end to make.french.predicate :french :english :arity define :french `[[[inputs] ,[:arity]] [output french.boolean apply ,[word "" :english] :inputs]] end ? make.french.predicate "egal? "equal? 2 ? pr egal? 3 4 faux ? pr egal? 4 4 vrai ? pr equal? 3 4 false ? pr equal? 4 4 true The third input to make.french.predicate is the number of inputs that the predicate expects. This solution isn't quite perfect because the infix predicates (=, <, >) will still output in English. If you want them to generate alternate-language words, set UseAlternateNames to TRUE instead. Some of the words in this section of the Messages file are names of Logo primitives (OUTPUT, STOP, GOTO, TAG, IF, IFELSE, TO, .MACRO). To translate these names, you must use COPYDEF as described earlier, in addition to changing the names in Messages. You should be consistent in these two steps. Don't forget the period in ".macro"! For documentation, there are two kinds: this manual and the help files. The latter are generated automatically from this manual if you have a Unix system, so in that case you need only translate this manual, maintaining the format. (The automatic helpfile generator notices things like capital letters, tabs, hyphens, and equal signs at the beginnings of lines.) The program makefile.c may require modification because a few of the primitive names are special cases (e.g., LOG10 is the only name with digits included). If you don't have Unix tools, you can just translate each helpfile individually. A period in a primitive name is represented as a D in the filename; there are no files for question marks because the HELP command looks for the file named after the corresponding primitive that ends in P.  File: ucblogo.info, Node: INDEX, Prev: INTERNATIONALIZATION, Up: Top INDEX ***** * Menu: * *: PRODUCT. * +: SUM. * -: DIFFERENCE. * .defmacro: dMACRO. * .eq: dEQ. * .macro: dMACRO. * .maybeoutput: dMAYBEOUTPUT. * .setbf: dSETBF. * .setfirst: dSETFIRST. * .setitem: dSETITEM. * .setsegmentsize: .SETSEGMENTSIZE. * /: QUOTIENT. * <: LESSP. * <=: LESSEQUALP. * <>: NOTEQUALP. * =: EQUALP. * >: GREATERP. * >=: GREATEREQUALP. * `: back-quote. * allopen: ALLOPEN. * allowgetset: ALLOWGETSET. * AllowGetSet: GETTER/SETTER VARIBLE SYNTAX. * and: AND. * apply: APPLY. * arc: ARC. * arctan: ARCTAN. * arity: ARITY. * array: ARRAY. * array?: ARRAYP. * arrayp: ARRAYP. * arraytolist: ARRAYTOLIST. * ascii: ASCII. * ashift: ASHIFT. * back: BACK. * background: BACKGROUND. * backslashed?: BACKSLASHEDP. * backslashedp: BACKSLASHEDP. * before?: BEFOREP. * beforep: BEFOREP. * bf: BUTFIRST. * bfs: BUTFIRSTS. * bg: BACKGROUND. * bitand: BITAND. * bitnot: BITNOT. * bitor: BITOR. * bitxor: BITXOR. * bk: BACK. * bl: BUTLAST. * buried: BURIED. * buried?: BURIEDP. * buriedp: BURIEDP. * bury: BURY. * buryall: BURYALL. * buryname: BURYNAME. * butfirst: BUTFIRST. * butfirsts: BUTFIRSTS. * butlast: BUTLAST. * button: BUTTON. * button?: BUTTONP. * buttonp: BUTTONP. * bye: BYE. * cascade: CASCADE. * cascade.2: CASCADEd2. * case: CASE. * case-insensitive: TOKENIZATION. * caseignoredp: CASEIGNOREDP. * catch: CATCH. * char: CHAR. * clean: CLEAN. * clearscreen: CLEARSCREEN. * cleartext: CLEARTEXT. * close: CLOSE. * closeall: CLOSEALL. * co: CONTINUE. * combine: COMBINE. * comments: TOKENIZATION. * Computer_Science_Logo_Style: OVERVIEW. * cond: COND. * contents: CONTENTS. * continue: CONTINUE. * copydef: COPYDEF. * Copyright: OVERVIEW. * cos: COS. * count: COUNT. * crossmap: CROSSMAP. * cs: CLEARSCREEN. * cslsload: CSLSLOAD. * ct: CLEARTEXT. * cursor: CURSOR. * define: DEFINE. * defined?: DEFINEDP. * definedp: DEFINEDP. * delimiters: TOKENIZATION. * dequeue: DEQUEUE. * difference: DIFFERENCE. * do.until: DOdUNTIL. * do.while: DOdWHILE. * dribble: DRIBBLE. * ed: EDIT. * edall: EDALL. * edit: EDIT. * editfile: EDITFILE. * editor: EDIT. * edn: EDN. * edns: EDNS. * edpl: EDPL. * edpls: EDPLS. * edps: EDPS. * empty?: EMPTYP. * emptyp: EMPTYP. * eof?: EOFP. * eofp: EOFP. * epspict: EPSPICT. * equal?: EQUALP. * equalp: EQUALP. * er: ERASE. * erall: ERALL. * erase: ERASE. * erasefile: ERASEFILE. * erf: ERASEFILE. * ern: ERN. * erns: ERNS. * erpl: ERPL. * erpls: ERPLS. * erps: ERPS. * erract: ERRACT. * error: ERROR. * errors: ERROR CODES. * exp: EXP. * fd: FORWARD. * fence: FENCE. * file?: FILEP. * filep: FILEP. * fill: FILL. * filter: FILTER. * find: FIND. * first: FIRST. * firsts: FIRSTS. * for: FOR. * foreach: FOREACH. * forever: FOREVER. * form: FORM. * forward: FORWARD. * fput: FPUT. * fs: FULLSCREEN. * fullprintp: FULLPRINTP. * fullscreen: FULLSCREEN. * fulltext: FULLTEXT. * gc: GC. * gensym: GENSYM. * getter: GETTER/SETTER VARIBLE SYNTAX. * global: GLOBAL. * goto: GOTO. * gprop: GPROP. * greater?: GREATERP. * greaterequal?: GREATEREQUALP. * greaterequalp: GREATEREQUALP. * greaterp: GREATERP. * heading: HEADING. * help: HELP. * hideturtle: HIDETURTLE. * home: HOME. * ht: HIDETURTLE. * if: IF. * ifelse: IFELSE. * iff: IFFALSE. * iffalse: IFFALSE. * ift: IFTRUE. * iftrue: IFTRUE. * ignore: IGNORE. * int: INT. * invoke: INVOKE. * iseq: ISEQ. * item: ITEM. * key?: KEYP. * keyp: KEYP. * label: LABEL. * last: LAST. * leaving ucblogo: ENTERING AND LEAVING LOGO. * left: LEFT. * less?: LESSP. * lessequal?: LESSEQUALP. * lessequalp: LESSEQUALP. * lessp: LESSP. * line-continuation: TOKENIZATION. * list: LIST. * list?: LISTP. * listp: LISTP. * listtoarray: LISTTOARRAY. * ln: LN. * load: LOAD. * loadnoisily: LOADNOISILY. * loadpict: LOADPICT. * local: LOCAL. * localmake: LOCALMAKE. * log10: LOG10. * logohelp: HELP. * lowercase: LOWERCASE. * lput: LPUT. * lshift: LSHIFT. * lt: LEFT. * macro?: MACROP. * macroexpand: MACROEXPAND. * macrop: MACROP. * make: MAKE. * map: MAP. * map.se: MAPdSE. * mdarray: MDARRAY. * mditem: MDITEM. * mdsetitem: MDSETITEM. * member: MEMBER. * member?: MEMBERP. * memberp: MEMBERP. * minus: MINUS. * modulo: MODULO. * mousepos: MOUSEPOS. * name: NAME. * name?: NAMEP. * namelist: NAMELIST. * namep: NAMEP. * names: NAMES. * nodes: NODES. * nodribble: NODRIBBLE. * norefresh: NOREFRESH. * not: NOT. * notequal?: NOTEQUALP. * notequalp: NOTEQUALP. * number?: NUMBERP. * numberp: NUMBERP. * op: OUTPUT. * openappend: OPENAPPEND. * openread: OPENREAD. * openupdate: OPENUPDATE. * openwrite: OPENWRITE. * or: OR. * output: OUTPUT. * palette: PALETTE. * parse: PARSE. * pause: PAUSE. * pc: PENCOLOR. * pd: PENDOWN. * pe: PENERASE. * pen: PEN. * pencolor: PENCOLOR. * pendown: PENDOWN. * pendown?: PENDOWNP. * pendownp: PENDOWNP. * penerase: PENERASE. * penmode: PENMODE. * penpaint: PENPAINT. * penpattern: PENSIZE. * penreverse: PENREVERSE. * pensize: PENSIZE. * penup: PENUP. * pick: PICK. * plist: PLIST. * plist?: PLISTP. * plistp: PLISTP. * plists: PLISTS. * pllist: PLLIST. * po: PO. * poall: POALL. * pon: PON. * pons: PONS. * pop: POP. * popl: POPL. * popls: POPLS. * pops: POPS. * pos: POS. * pot: POT. * pots: POTS. * power: POWER. * pprop: PPROP. * ppt: PENPAINT. * pr: PRINT. * prefix: PREFIX. * primitive?: PRIMITIVEP. * primitivep: PRIMITIVEP. * primitives: PRIMITIVES. * print: PRINT. * printdepthlimit: PRINTDEPTHLIMIT. * printout: PO. * printwidthlimit: PRINTWIDTHLIMIT. * procedure?: PROCEDUREP. * procedurep: PROCEDUREP. * procedures: PROCEDURES. * product: PRODUCT. * pu: PENUP. * push: PUSH. * px: PENREVERSE. * queue: QUEUE. * quoted: QUOTED. * quotient: QUOTIENT. * radarctan: RADARCTAN. * radcos: RADCOS. * radsin: RADSIN. * random: RANDOM. * rawascii: RAWASCII. * rc: READCHAR. * rcs: READCHARS. * readchar: READCHAR. * readchars: READCHARS. * reader: READER. * readlist: READLIST. * readpos: READPOS. * readrawline: READRAWLINE. * readword: READWORD. * redefp: REDEFP. * reduce: REDUCE. * refresh: REFRESH. * remainder: REMAINDER. * remdup: REMDUP. * remove: REMOVE. * remprop: REMPROP. * repcount: REPCOUNT. * repeat: REPEAT. * rerandom: RERANDOM. * reverse: REVERSE. * right: RIGHT. * rl: READLIST. * round: ROUND. * rseq: RSEQ. * rt: RIGHT. * run: RUN. * runparse: RUNPARSE. * runparsing: TOKENIZATION. * runresult: RUNRESULT. * rw: READWORD. * save: SAVE. * savel: SAVEL. * savepict: SAVEPICT. * screenmode: SCREENMODE. * scrunch: SCRUNCH. * scrunch.dat: SETSCRUNCH. * se: SENTENCE. * sentence: SENTENCE. * setbackground: SETBACKGROUND. * setbg: SETBACKGROUND. * setcslsloc: SETCSLSLOC. * setcursor: SETCURSOR. * seteditor: SETEDITOR. * seth: SETHEADING. * setheading: SETHEADING. * sethelploc: SETHELPLOC. * setitem: SETITEM. * setlibloc: SETLIBLOC. * setmargins: SETMARGINS. * setpalette: SETPALETTE. * setpc: SETPENCOLOR. * setpen: SETPEN. * setpencolor: SETPENCOLOR. * setpenpattern: SETPENPATTERN. * setpensize: SETPENSIZE. * setpos: SETPOS. * setprefix: SETPREFIX. * setread: SETREAD. * setreadpos: SETREADPOS. * setscrunch: SETSCRUNCH. * settc: SETTEXTCOLOR. * settemploc: SETTEMPLOC. * setter: GETTER/SETTER VARIBLE SYNTAX. * settextcolor: SETTEXTCOLOR. * setwrite: SETWRITE. * setwritepos: SETWRITEPOS. * setx: SETX. * setxy: SETXY. * sety: SETY. * shell: SHELL. * show: SHOW. * shown?: SHOWNP. * shownp: SHOWNP. * showturtle: SHOWTURTLE. * sin: SIN. * splitscreen: SPLITSCREEN. * sqrt: SQRT. * ss: SPLITSCREEN. * st: SHOWTURTLE. * standout: STANDOUT. * starting ucblogo: ENTERING AND LEAVING LOGO. * startup: STARTUP. * step: STEP. * stepped: STEPPED. * stepped?: STEPPEDP. * steppedp: STEPPEDP. * stop: STOP. * substring?: SUBSTRINGP. * substringp: SUBSTRINGP. * sum: SUM. * tag: TAG. * temp: EDIT. * template: TEMPLATE-BASED ITERATION. * test: TEST. * text: TEXT. * textscreen: TEXTSCREEN. * thing: THING. * throw: THROW. * to: TO. * towards: TOWARDS. * trace: TRACE. * traced: TRACED. * traced?: TRACEDP. * tracedp: TRACEDP. * transfer: TRANSFER. * ts: TEXTSCREEN. * turtlemode: TURTLEMODE. * type: TYPE. * unbury: UNBURY. * unburyall: UNBURYALL. * unburyname: UNBURYNAME. * unburyonedit: UNBURYONEDIT. * unstep: UNSTEP. * until: UNTIL. * untrace: UNTRACE. * uppercase: UPPERCASE. * usealternatenames: USEALTERNATENAMES. * wait: WAIT. * while: WHILE. * window: WINDOW. * word: WORD. * wordp: WORDP. * wrap: WRAP. * writepos: WRITEPOS. * writer: WRITER. * xcor: XCOR. * ycor: YCOR. ucblogo-5.5/docs/ucblogo.info0100644000161300001330000002012010276035443014166 0ustar bhdoeThis is ucblogo.info, produced by makeinfo version 4.5 from usermanual.texi.  Indirect: ucblogo.info-1: 78 ucblogo.info-2: 48924 ucblogo.info-3: 98836 ucblogo.info-4: 147616 ucblogo.info-5: 193492  Tag Table: (Indirect) Node: Top78 Node: INTRODUCTION513 Node: OVERVIEW742 Node: GETTER/SETTER VARIBLE SYNTAX2892 Node: ENTERING AND LEAVING LOGO10615 Node: TOKENIZATION13315 Node: DATA STRUCTURE PRIMITIVES19128 Node: CONSTRUCTORS19371 Node: WORD19673 Node: LIST19881 Node: SENTENCE20136 Node: FPUT20500 Node: LPUT20829 Node: ARRAY21184 Node: MDARRAY21896 Node: LISTTOARRAY22381 Node: ARRAYTOLIST22660 Node: COMBINE22972 Node: REVERSE23262 Node: GENSYM23493 Node: SELECTORS23705 Node: FIRST23987 Node: FIRSTS24346 Node: LAST25017 Node: BUTFIRST25260 Node: BUTFIRSTS25593 Node: BUTLAST26192 Node: ITEM26519 Node: MDITEM26959 Node: PICK27202 Node: REMOVE27387 Node: REMDUP27600 Node: QUOTED27916 Node: MUTATORS28135 Node: SETITEM28466 Node: MDSETITEM28791 Node: dSETFIRST29047 Node: dSETBF29627 Node: dSETITEM30265 Node: PUSH30815 Node: POP31196 Node: QUEUE31479 Node: DEQUEUE31862 Node: PREDICATES32148 Node: WORDP32457 Node: LISTP32646 Node: ARRAYP32831 Node: EMPTYP33023 Node: EQUALP33240 Node: NOTEQUALP34261 Node: BEFOREP34573 Node: dEQ35090 Node: MEMBERP35593 Node: SUBSTRINGP36007 Node: NUMBERP36366 Node: BACKSLASHEDP36574 Node: QUERIES37024 Node: COUNT37257 Node: ASCII37615 Node: RAWASCII38009 Node: CHAR38355 Node: MEMBER38590 Node: LOWERCASE39039 Node: UPPERCASE39281 Node: STANDOUT39525 Node: PARSE40674 Node: RUNPARSE41015 Node: COMMUNICATION41383 Node: TRANSMITTERS41596 Node: PRINT43204 Node: TYPE43730 Node: SHOW44917 Node: RECEIVERS45181 Node: READLIST45392 Node: READWORD46080 Node: READRAWLINE47081 Node: READCHAR47677 Node: READCHARS48288 Node: SHELL48924 Node: FILE ACCESS50167 Node: SETPREFIX50585 Node: PREFIX51271 Node: OPENREAD51473 Node: OPENWRITE51713 Node: OPENAPPEND52763 Node: OPENUPDATE53097 Node: CLOSE53808 Node: ALLOPEN54125 Node: CLOSEALL54369 Node: ERASEFILE54624 Node: DRIBBLE54868 Node: NODRIBBLE55390 Node: SETREAD55598 Node: SETWRITE56137 Node: READER57602 Node: WRITER57822 Node: SETREADPOS58046 Node: SETWRITEPOS58501 Node: READPOS58957 Node: WRITEPOS59141 Node: EOFP59322 Node: FILEP59548 Node: TERMINAL ACCESS59791 Node: KEYP60000 Node: CLEARTEXT60697 Node: SETCURSOR60886 Node: CURSOR61316 Node: SETMARGINS61702 Node: SETTEXTCOLOR62594 Node: ARITHMETIC63439 Node: NUMERIC OPERATIONS63681 Node: SUM64068 Node: DIFFERENCE64281 Node: MINUS64658 Node: PRODUCT65120 Node: QUOTIENT65342 Node: REMAINDER65834 Node: MODULO66110 Node: INT66372 Node: ROUND66681 Node: SQRT66839 Node: POWER67019 Node: EXP67229 Node: LOG1067385 Node: LN67542 Node: SIN67691 Node: RADSIN67862 Node: COS68043 Node: RADCOS68220 Node: ARCTAN68406 Node: RADARCTAN68723 Node: ISEQ69124 Node: RSEQ69406 Node: NUMERIC PREDICATES69736 Node: LESSP69957 Node: GREATERP70202 Node: LESSEQUALP70454 Node: GREATEREQUALP70723 Node: RANDOM NUMBERS70990 Node: RANDOM71169 Node: RERANDOM71728 Node: PRINT FORMATTING72282 Node: FORM72450 Node: BITWISE OPERATIONS73226 Node: BITAND73431 Node: BITOR73684 Node: BITXOR73919 Node: BITNOT74168 Node: ASHIFT74372 Node: LSHIFT74664 Node: LOGICAL OPERATIONS74933 Node: AND75100 Node: OR75871 Node: NOT76616 Node: GRAPHICS76890 Node: TURTLE MOTION79254 Node: FORWARD79510 Node: BACK79768 Node: LEFT80051 Node: RIGHT80279 Node: SETPOS80505 Node: SETXY80734 Node: SETX80957 Node: SETY81196 Node: SETHEADING81436 Node: HOME81717 Node: ARC81953 Node: TURTLE MOTION QUERIES82250 Node: POS82490 Node: XCOR82705 Node: YCOR82886 Node: HEADING83071 Node: TOWARDS83249 Node: SCRUNCH83535 Node: TURTLE AND WINDOW CONTROL83844 Node: SHOWTURTLE84234 Node: HIDETURTLE84435 Node: CLEAN84763 Node: CLEARSCREEN85035 Node: WRAP85320 Node: WINDOW85861 Node: FENCE86385 Node: FILL86769 Node: LABEL87119 Node: TEXTSCREEN87361 Node: FULLSCREEN87752 Node: SPLITSCREEN88554 Node: SETSCRUNCH88952 Node: REFRESH89984 Node: NOREFRESH90310 Node: TURTLE AND WINDOW QUERIES90567 Node: SHOWNP90811 Node: SCREENMODE91127 Node: TURTLEMODE91369 Node: PEN AND BACKGROUND CONTROL91580 Node: PENDOWN92430 Node: PENUP92650 Node: PENPAINT92844 Node: PENERASE93042 Node: PENREVERSE93261 Node: SETPENCOLOR93560 Node: SETPALETTE94344 Node: SETPENSIZE94977 Node: SETPENPATTERN95540 Node: SETPEN95867 Node: SETBACKGROUND96240 Node: PEN QUERIES96554 Node: PENDOWNP96802 Node: PENMODE96995 Node: PENCOLOR97237 Node: PALETTE97926 Node: PENSIZE98215 Node: PEN98565 Node: BACKGROUND98836 Node: SAVING AND LOADING PICTURES99081 Node: SAVEPICT99301 Node: LOADPICT99847 Node: EPSPICT100249 Node: MOUSE QUERIES100820 Node: MOUSEPOS100990 Node: BUTTONP101535 Node: BUTTON101886 Node: WORKSPACE MANAGEMENT102222 Node: PROCEDURE DEFINITION102542 Node: TO102782 Node: DEFINE106656 Node: TEXT107600 Node: FULLTEXT108064 Node: COPYDEF108891 Node: VARIABLE DEFINITION109482 Node: MAKE109725 Node: NAME110125 Node: LOCAL110334 Node: LOCALMAKE111035 Node: THING111333 Node: GLOBAL111760 Node: PROPERTY LISTS112408 Node: PPROP113259 Node: GPROP113503 Node: REMPROP113762 Node: PLIST113990 Node: WORKSPACE PREDICATES114397 Node: PROCEDUREP114641 Node: PRIMITIVEP114878 Node: DEFINEDP115236 Node: NAMEP115588 Node: PLISTP115783 Node: WORKSPACE QUERIES116159 Node: CONTENTS116481 Node: BURIED116822 Node: TRACED117019 Node: STEPPED117215 Node: PROCEDURES117419 Node: PRIMITIVES117786 Node: NAMES118139 Node: PLISTS118411 Node: NAMELIST118703 Node: PLLIST119100 Node: ARITY119750 Node: NODES120116 Node: WORKSPACE INSPECTION121012 Node: PO121274 Node: POALL121570 Node: POPS121814 Node: PONS122092 Node: POPLS122359 Node: PON122641 Node: POPL122933 Node: POT123225 Node: POTS123608 Node: WORKSPACE CONTROL123859 Node: ERASE124455 Node: ERALL124822 Node: ERPS125076 Node: ERNS125314 Node: ERPLS125542 Node: ERN125778 Node: ERPL126086 Node: BURY126396 Node: BURYALL126926 Node: BURYNAME127167 Node: UNBURY127439 Node: UNBURYALL127751 Node: UNBURYNAME127966 Node: BURIEDP128255 Node: TRACE128758 Node: UNTRACE129324 Node: TRACEDP129510 Node: STEP130009 Node: UNSTEP130556 Node: STEPPEDP130739 Node: EDIT131245 Node: EDITFILE132635 Node: EDALL133280 Node: EDPS133478 Node: EDNS133688 Node: EDPLS133888 Node: EDN134092 Node: EDPL134336 Node: SAVE134576 Node: SAVEL135016 Node: LOAD135311 Node: CSLSLOAD136063 Node: HELP136367 Node: SETEDITOR137239 Node: SETLIBLOC137528 Node: SETCSLSLOC137974 Node: SETHELPLOC138310 Node: SETTEMPLOC138655 Node: GC139022 Node: .SETSEGMENTSIZE140065 Node: CONTROL STRUCTURES140688 Node: CONTROL140881 Node: RUN142036 Node: RUNRESULT142319 Node: REPEAT142814 Node: FOREVER143010 Node: REPCOUNT143305 Node: IF143558 Node: IFELSE144438 Node: TEST144843 Node: IFTRUE145228 Node: IFFALSE145525 Node: STOP145842 Node: OUTPUT146129 Node: CATCH146506 Node: THROW147616 Node: ERROR149264 Node: PAUSE149750 Node: CONTINUE150665 Node: WAIT151210 Node: BYE151549 Node: dMAYBEOUTPUT151711 Node: GOTO152658 Node: TAG152967 Node: IGNORE153234 Node: back-quote153492 Node: FOR154929 Node: DOdWHILE156498 Node: WHILE156948 Node: DOdUNTIL157390 Node: UNTIL157843 Node: CASE158282 Node: COND159198 Node: TEMPLATE-BASED ITERATION160328 Node: APPLY164822 Node: INVOKE165319 Node: FOREACH165650 Node: MAP166734 Node: MAPdSE168055 Node: FILTER169318 Node: FIND170444 Node: REDUCE171416 Node: CROSSMAP172947 Ref: CROSSMAP-Footnote-1173993 Node: CASCADE174026 Node: CASCADEd2176813 Node: TRANSFER177161 Node: MACROS178070 Node: dMACRO178300 Node: dDEFMACRO183251 Node: MACROP183373 Node: MACROEXPAND183562 Node: ERROR PROCESSING184117 Node: ERROR CODES186890 Node: SPECIAL VARIABLES188810 Node: ALLOWGETSET189449 Node: CASEIGNOREDP189896 Node: ERRACT190317 Node: FULLPRINTP190639 Node: LOADNOISILY191189 Node: PRINTDEPTHLIMIT191519 Node: PRINTWIDTHLIMIT191856 Node: REDEFP192195 Node: STARTUP192480 Node: UNBURYONEDIT192783 Node: USEALTERNATENAMES193212 Node: INTERNATIONALIZATION193492 Node: INDEX200058  End Tag Table ucblogo-5.5/docs/loops.info-1.gz0100644000161300001330000003774607270062710014470 0ustar bhdoe‹b:loops.info-1¬[ûsÛF’þ}þ‰›Ëý Ç‘°ìm.rm¹h ´¹K‘Z’ŠâÊ¥lŠƒ%î__wÏ %YÎÕ©ü yôôóëîÑle ?I–mŠÀ¦Ë¬£7yW ëùN¯£;COõÖä…ÍRý—àµ^æÙZ½ªŠüU’-¢äU‘/^½¿ /ðý6뮳ؼâ»·•MPš(õoªos¶·—að™žeúlÊ3=Í&ã‹ëóÙ`<ÂëÜlÏôqló|»Þ¸ÏJ͈ôu”VQ¢ãlQ­MZº\=¯¦ýÞäw&1;=Uz<ÿÝ,J=Î-Æ™X]åÙm­×6½ÕÓ]QšuGßç¶,Mª1Âæ&Ùi›òd¼YÙÅJçUZèTQÍ ž¤«46ùþ^Ö3áh•±Ý‚1–+3¢P-³$ÉîiëÅ*Ú”àí™R§úÒ¤hóàì Î?öF©žõtÖ]ô&8懱¾šŒÏËëI8åq½‹‹Mâ‘4àé§z8x?éM>ñÛñû¿‡ç3=ž ÂÑ,¼ %?Lz——ƒÑ~?»žá]o(K¦7áD6c>ëóñEÈ_£‹ð|úš „+ÿ†ÃÕŠ šBj€OJ Ò’µµ„nªÓÖÏ;Ç?‡“Ÿá “I‡œàl8 ¶ {?Óg>Ê ´ûUjºŸ_©&÷à¼Dwû‘RcÖÖš{õ7÷£Ôy¶ÙåövUêãóýýëׯÉ?æÛìw£ß'Ñ¿ÌÖ.œþoD‹IÉ–¹1ºÈ–å}”›·z—Uz¥:7±-ÊÜΫÒh[ê(_e¹†‘ÚåNá(0Ù ôp]èlÉ_>Œ®õ“š*|UÍ»ÐC»0iaÈ6ô¤X±“P4¼O»OÝaÕˆ„òV‹÷yí@¾÷¸Õ:ÔG¥Á¹Î64éTît•ͼàñ›s‘eñš«lƒc¬¢’Nzo“DÏ® ³¬’ŽÆHu3˜}_Ï ±Oú¦7™ôF³Oo1²\eU©ÍÖÈ:v½I,–Åaò(-w Y]†RÔYïý`8˜}‚½èþ`6 §SÝÇçž¾êMfƒóëao¢¯®'Wãiè©1ž›ên.Y`ZlÊÈ&Nú ²+@QëU´5áÂØ-è‰ôÊñ²ˆT”dp.t.ŒlØöVÛ¥N³R\Hcw´/<Õ¯£é"èè¿þø_ú2* ÝÛB^çÑzžÛø/{úõ÷o~ø©£¯§½'DT”"òtιzPây”“Ø IYjä<éÂ4 Õ ¯ú¼7Òc=˜Ñr之©®ŽÕ튼ÂôÛ<»OÁ•´€‡Í£9œvaÓ…!¥ýU“ñ{U@ýõhÔî¾<¶2¢|§ÉdöÙó¨±TT(è +V µH² †E­ Ç?=]¬ÌÚ|MŸ±Õç^^~ΖŸ[Q¥C$äfI¢µˆLN¿Þ”Äó(Ž!©b£—&*«Üô£”“:D„3­ÉÔT¤‹*ßä¶0Dbó ļBÔ¬=JrÅ;}—f÷°„{ZÔÉBÕŒx¸6ÜbS,`?F‚&h²$s¬ì©’Ñxis2¢@ `†™F#éT&Yƒ‰^˜ã¢*jž‘.³Í‘iƒœ(ƪh‹7”h¾M‹Yˆ²AXîü°ZH`G'GÅ”À*ólkTµ?^„½é'"`m`¦´=ÝKr+mIóˆ-êô<[oà+òÏÓ ÀÂ|&†|ž–»z÷s–€™Ÿß|þþóämßç¾óc”oÍîT_f ¦KÞüôÓ'Pu ~|(Ö¾¢d×¹$/Š—à1(Ú@Ï1©yàÕ}Än“HŠ¥Øj#£fœæqäU“,ŠtßæÐäò>Sô”y»ŠÒ[Q£‚ÔöÎcQ*p p®‘¨5W²%L&A€Y¬—p¬ˆ©¬™çãÑl¾7 yî0œMÂóŽw-FAM7ˆ˜9K ÓšÍRÄ+^AÉþªë,Wä„è@îè‡`½´$Ÿ4Ë×Q¥Å¢–éÄ(Ž+œWB‰²|×sX“©Ï=ÇœÅ$;Ž5؈H¸Ž|b Ù?‰cz=sÛì†&vžG´™ÀÂF6ÊÑ^óòæd !îˆJ쬌Ô¤4ÕbNt(·n o\@baŠ·/Z„t÷8‘íÝgù8“é‘ çx û%/É ª{×èÙËØŸHÇtƒ`cÁ!lÈÇtZõØñÒ¾Jœ* ñcm#—S°=GIwG`·Ž ÌÆ¹QlƒÄH§æËÀýÑÀ_jD³·„IŽ`4¥é§ˆ°’ŠÏ&ס6 Ûï §á[` Ø< t… ¢ôh<Ó³p:Ó7ÃPAp"«É¿S»Oüàÿ·ß)Ûi¬ B]ÚÔ Ê9ÃpaA“S£•`È+.C Ž‹ üåj<™ímÈÖÿ›ìMÃc»k?o[ÛÞx"ãØùøò g›ìíã²o¬,¨?¸ìý#œèÿÔ…a&GÕƒM,ÅÄÆipˆÇ!NÂë$ˆApD ¶†fõÙ¾ÉÅ ¼˜‡ÉÙãŠÓ h7 {C-@9ÎXƒiÔ‚‚£Oc=%k/£ä®û߯5…QØi-b–½MÙOÉôLŒTË®£Ü&;¸#l”§„Ýh³ãR7ëé$!È¿7c|ŒrÀvÁþ%Î5†Ñd±;œb ç Øe\[.‡‡’ã_#]ÈË*p%g±[“›& Jlq+o÷µÁ>ƒG©âåö,*€ªgŒ¡U™TŸàŽ6¬áâXA¨w’ŠI¥ÜßKì)†iòœ &¢XÄV=7Œfʬä“Ãc$x„¨QEé‘âÚ‚59v<+x.Ú .X†¬dçx¿f÷¬†ð­ã(Ð;XI1>b‡h9¹.¢%§h+°@ [hØãIÅø3‰{ RÈ“>ç‡hC{½Db㋈q.S`¢Øµýw€ô/5`BÂñ¢0Ý.³AàS|?%ç 6%&þ÷¯f’ß8¶’ÍÇIcH ´€#²C9BÒßžýñ…ìÅAZBàŽyø˜¥ ±Š²îûé¿CŽÑÚ´zìÈr•âýõhð‹O 2>ž#HTXéõÃ'± a2üœ"Q†¢¨;­Š l$¦”@»dÐH´k-pý_.ÆÓ³#ç 9 hû­àÚ˜r rª‘WAêpŒM甸Égÿs}þžª 'R®žï âî¡G3HBsì±6ÈÐvM.*¾{?“*‚ò¿þåõ?œ³â}Á ¼!::ieZ0ü ‹¼qØoÜ» M@A”ž—KÉ$ñkt‡šUŠæx6Ô¨Èá”U–Äž•Èôw|„Â!½ËKù‹3S¶@ÒíR †øf8 "«ì¡bd…¬‡Ü äþå2ZxÉ]dÈVMwŒ•JÑ\·ZÛí|q0ßA <6fG41SŒ+¹}†Ýî€kïñSÖx†©ßÆOYâ ¦ÖüÄ©oÍ~¾vrœñ¦9½­:=¤c‹Byò5­zV¡f¶l«.Ù7APÊPë8,Ús˜+'aàëržmRK*«|»–>RÐŽÓ8(šõu9ØçX^×(ù²‹*AŠZÕ%^^ùïZ)Kã85áZ~‚5°¿Ô§£šM”%N9—8=ˆãdÀ(ÿÂ%§ßÁ=¸¬.®³ç¼J(ò€ƒÃÚ’£P\ÜKšÝ ;^˜ÆÝËñEè2q!zÍηÌ)°×áA8u9½!º]¯.ºÖY—$ÖŠ` V  Õd<]BËq±…ÀÖŽÁm–!ò¦t²…ëÔ>xC˜í6².69 ó’)iøäãÙžr@°¢ íhëv¶iAàÅ85ñiŸÏ 7Q¹ N𱕴rJ>ƒgàž¡H®UàdmÉÉvdcÞ,—Rs!Õ"pN%ÊÅ™D@)ðS²ÂoB§S”&é<ÕÇÛïƒ 8qµóÄ•58Áâ™QUfâºó2²äÒB£®83¤³!”ØD©œ6™¬· <ÖjçÀظ‘Ãÿà‹S3É#!œ³ægfÑ@/÷Ò”:iodË ›ëÀ0sœpø”EÆÜMQËF²X@c Ñ æSNiÃ^8¹êåλ§9Ù5U`âÚõpòµ€Z º¬ˆsQÒíB”¶Dµ ÏdlëòXS5aãùYîí$&JÙž¡Lµ»E¨†(Ú€¼¤*H~­ZÄ×Ðã·µK¤Eñ¨óóµÎwTΛRÒtÏ_Õ~¯ÑòÌBåKuù‹PÃÜ”÷ƃ#â–¤6œÇ`|Sê%ÿBHŽª$óua-LçÚÙ ‘TàDÆ NÒÓ£‚KºLN^ÁuÙBk퀾|G£Ðqgî-•¢—P?.XŽäG”•í¨ÜjƒïÝ.øKI›ÆŠÛ°é¦â¤¶Nñ›Âþ"&±à93ê Æ¥Ô¢}eOY×ç’êª/Ý@¾Ã!ÂÓìz2 /ôϽá5ô¢7 ©x0\„<¥ÒHG…¿œ‡W3=ûê›1¦9ÆMëü\RO³º²@eUWl#·ÆÇ€^Q.P70ŸŒcÆœ„Œ@FFÇ5oŒ¢e |}$ýp8 EÔT’ ð„iÅÿ\ÂéH‘¦ƒ„c6Mò]Ñ |“ÇT³roC‰blâi“¼QawkgI1•„E®¿¦ì\]£jÐ'wÌí5ÁRXÌÐu>? Ω„qNzl_ÒZüeŽ.¸…ö)Iâ×ãÉKE·tmµ—¯ÍöÛŒŸ¬ùFR¯‘¥§ê±Ý„îK[—å$`0…?ÄXïìL?óCe³¯6ûM³ß)?]Í>|SÊ.U·ëCiŸ*H®ð×Ddªʀ㯌xsøàû¥êȯËG¶KÕ•Æv…±#¸»Ñµn‚@~Œò0óùåè™,·¿ŽŠ3ÃŽœJ€s,õ­¥²EDÆ—»u;Ìr… \k+*”ïçPûÆ àC­6¸:*zFÎËPð(Êé?—R1‰s5= ²ˆ©s›Ør'èÏDyb›þlá«ÆÚ!b¾´x­\“1 É\`˜ÐV!öÚÐ%~Uò#ÕZgF@îÎ!éÄF-îLQù´rk”UãØ&èðS>·.þ¨(,-îLYœ°˜jŠ&ríI† Þp*ʳš{ZÔf×èêi4¥ååN$Ì ·Yb› 8V(./5%äyï:®Ó#ëùušåXb¹ÄbT3™*-é6»všh±r ‡p²Ûàr80P>Æ·`ÖÁNqŠ­’õ7ð¡ÿØH)ÂPé§6VZáO˜cm¤®þ“¥Ú4•3)ÞoíüÌSí›çþZ-‹ êsfU‰ï¤{î¸Kv _Nyä‹S›e£¶ŒtyBŠ¼×ž$éÉKÒtâY’oÉÒÉyOžTT-YrÛÄK²í5'fmÖPõ‚ÛÜÎII®FvÊ2RêpöZÖÌwJ®wHÌ'i»¨fqžåêÜð0L÷¬¨¨ `Uúr¢X„O%¥þ[Öä `òâ—~ÛTùM[™c;ÙuË‚:êÂÏë'„âéò"aøð‚@ödळ'€j]- RCØS&×yêÕæõü:KwLµ¬pBÚÿH›åÇ|ÇÿUiiþ” AFgEµhk…‚5Xe¹æáG»¨C¶™6‹ø5x–·×@¥ºõ"ði’¦“'UM"ñ‹™Oõ÷u‚S†Æ“°7ø>Ïù°7úŸ¨4O@ݲVN6@T¤NÀPuó…Çøìƒ» §.”ŸR!…ã³ø}‚þu-MÎÞ¸8©}úˆÛK¢”¬®isÓ‚‰reˆÎžËÚÛWù•»/gÛ(£ Ü+úøÛQS"8ØçlO¥¤hÃÓÓ¿rGÔ4ß–vE¯Ï ­á„ˆºã¯ÿ¨ø®ˆ]Z yjî5ÄÄ_Ï™ŸDÔîßs ý9Tú-¸zèÚ^co<Å¥ÞCCºÝ=W" ‘Ôt|óLL0ƒ‡ý‚—G<âK–‘ƒSì«Èë4(jç2nïÎrn”ÀJ\)Rn”°\ƒGv°Áå5ü+$É€ó¢0 }Ìy!y¾ˆÑ£M±n…/ÆÝ/â }ݮ۲”‚ºì­Ç£á'YX}‘ü“7–Ìô„ƒHâ®óæVHøÞÜiT¼ƒ6¦ÍÕÒˆQ!©¡¬ÛªãÚ3XE$)ð,«t!¥kºÇ…Ü0fQ1þä›5æh›†à„ÖU̵?ª L ¶SiüýžCÐÉ…¼šZêY ç[¹Us¸÷+âdãk^µ˜BÇ=dF­®òÂÕç:ìEñÊåéoÝÑ ; óaæâEEX´‚§iQì ×ö‹;åƒ:Ú0Ûɯ¡rå:P®¨èVY©ÝÒÅ'}:"žÒcöûƒóA8:ÿtvÛïO뉻^j8ò8gœ”Š'R¡²¹ò°¢:ÜÂ7AÜãGû&Ý­³Å&P¼¡díàÅ£)ªÑ8*Ÿ«ê±ËÈ&5|Óƒ{ÏâØ«”÷®«hrxN}}À|æ™»RÆCFÐMÕ‘´v9buè¬G¥«ƒV*c%.†ˆÞ57 ©½øÊ•çR*—7HB3røyà;]Ç‚\t[­¹àcHɤTø oòÓMÎþl£¿‹ê¼o•ê_ùq\ù.ÒoèÕY¤¹zõÛÁ,ã;…{Qpxy³¯nô«Ÿò[³•Ú;‰ÀOWnÙ-ÃñkûÔ²·;5$×Gƹ09&SzØâ¬IÏÑwO1”MT>¾yôdÞ>sž›¨Æó­Íª‚ŠÛP¦pCsðîŽïl=©Eêk¼… ˆè¬ÞÚÂRÃ˃X§u¸Fñ)Sµ¶…o¸B€­…-{ר¹BÈÈߦª¡y¿ÌÇ•-ú ÿ7Ï^(Þ Š,1žÔ áIÄAøáñ VÕà|R”3åKiº\=-=vo=Áß]a“ßdhŸ´æ=:<ñæÙÌá›Æ:€'zìïýC$<™Û®+éÑøÇí«l"6 [Ö5±ÆkGÒ©sÍÂÝiçþ,ù ¿¼PnY ÷[³äxÏ}»Žë·òŽ=§ÍU&•5] ·›'„[$é w öFñ6²™N«îçdø[—àZ@–zNO¤Yu$®A%ïÜF2ˆ´MÂ&!Ö%êœ ‹Ï§•M?Jb||‹¯Haõ5¦¹þ†¤e‰Ð…6¾^&fNB{Ää8/µ8¾cþ¨lþNg[‚åÕÆ$6öœõú=e;uû¦Ó”†{˜Xli\òŠ´óù[…JJÜáæËêk›R¿ i"7@e#«ÖÉ왺ôûá>Ôÿ¼Ïè÷õû°?ž„ïtøÏëÞðþ0 {³pòÎýòÁtúNsQ‡.˜Ü+—ð¬¥e 8 ˜ Znå—A›ûl p–å¯dù+å–¿ª—¿¨@Âa¸ '‰éª—ãén³Iýo |ywÄ¿ƒñ¿½]ksDZý>¿b/ý€ À!çæÒ×qQ±,‰2)Ùq¡Xæ\’ˆ@ÆCSùñwÎéîy,%».“’É}ÌÎôÌôôó´=EÅR$ãB»al¤í71žGÒï•5ùƒâ"Ú«zsÕg Q"{Õ_@ myÇM1‡…é>ò¯šdG/kôNñÄz•1 ðJK¥D”³É).¾,ºÅ“â«]I#âÔ™¯q€"ˆÅÙUín`ù;ÐL(Άþxj}éE½ýâëâÏÅ7m^ÿîoÅÞ7š5e¢*çPг…ÓÆbß tBÔ׋ԓÆi9› £¤ò‚ÞàÉtÉóÍK¤A¢D3ú­{ìDRrøwÚzå%lÐxaÉÁ”M1ã>È–Ž‹e<`™!¤¤#Y…*KèñE«[|ãi°×Þíè‚„ˆD{$Y=úl.¡Æû”PmuñÝ=Éï?ʲø«m©ô{Œ;,ü&W7±¤Ø—pn[SÚĶÀ›ÖÞw‰ÑVýJ©5<±èŽ—p@è¹¼r}Oÿ»¿îÅðÀªÉûDÏîëw¯žò$•_÷ôÒ~o‰äá’m»›ÇíÁD”íétMˆ(TÕ‰ DÍ¿…ŠÆ7\‚v#§_íjzën¯§ÝÞW«ÄÓKû_ÚEþ¶ëV(—±¾ t‹dJÉöc¤[BØ-T»¤¡þ{W£™^¦(¥K/íñßý†‡õÎz2© LOljõoî”Â7õdzO¼’wÂ+Ô;—ëjåOí üÿÛò*ö[iûc$®ð”@ÚHûGQö·ïWÖ£ÝX%îoë©ûÛDÞßC_Ò°tSÊZCø_{¥¡MtM™Q6e ö[({ÃØÙêâµ93­]­3Óu·?‡Ð¡­M¤ŽùÿÕžJ‰žûš"Èç;e”+­“ùxµSf±Bql¶&šÇëk¨ÞðÀï ;Z{åù˜§évÚãIPÿÓ¨o¤Ž„O—y67[ˆ˜I¥»•—rj§—ê„n¼÷94–†6‘WŸØ¼ªí!¯…|:QS2‘AÁdí¦£YYµùÅ&JþAëÕšÚFMY©+ôL¤‰øTGl—&š"Ó×ĬZÑgÁ2¤ý°žÀ¿À.y‰wå€9åN¸g³&È1þ@5»[ Ф ¯aÎ-5.p¤üŠ«°Lm(åàvXê_§Üë甼PŠCK jU½›ž2´ CqNÑhê¦}YÓ>ü€Ö€W˜+TËHq°¢KpÍýídT÷åè'. ÖDh&ƒ¬GŦÐOÖ£©k>\FUÃvUC´Z‰¸±ËB;þ!YjˆÔÉ–ÃÖ¨ë¬ IôuÞh…nX²Xd+×Wí‰u„¼3$‰?Ô hŠÁ€w&\ì!™ïn—&Þ$ÊDœnby ̆£$ÁqªZ W ñ,âfð®¸R³Êç̯*G‹É "ågíâçã—/ë‰éjä  ®–£œÔ~C ªÂ‹ùp!ÜyGB¢˜V%½„åÅo»ÅàVQ&$ÐU#¨.+¸ºY6ƒ‘Ì/»òf콪ÚÁ¯êäûOгãWo/p̼… eö •¾Í›áxŒ”J Žòºyc d¹ûO'Ó¬à²k¹[ëÚz_F†AÄxñÚ ¦$öFö{œ ÷ôŠ—ìí4E‡:Ìbóåà¶ð+u  x0BV5“óR8šù¢šN1õW)ÄØP þÉu\°=–eŒ–̰ ç xŒ‡ ˜Ýh±{{üJMÞ*.žAÁ§¦奅¯yŽ*Y't[•½Ãü¦‡èõ¸îÅåtÒï—Å}ò”9±ÆÌï˜ÀŒˆo(Dˆâ f ¯ 4=LåbÑŸLµÃç–rŒh¬Å¦ŽŠÛÿIºö"ÆC¤…¸jòÐ eÆ/Ë7ø9ü­óI/¯Ó÷jÀÑb- çé%/k~Ó0=(úÎŽë~?õy:ìóä¡Ç 1}¡²1å£8?Oc&Nˆ¶°TF K­$ÜãÉN2ž8ÌÀfàÅ ¿ÐqÂȦYÌ$u:™.}{’\V},±0:I\ïõ¨\|ïÅÿoû øY‰ý†y¸2øøÁ¨¾^äšÐ1 a±¿`–ø> =l†ôÈ&UŽAP«®† XÑSÁ¢[L Ø+: g{ò?ç»Ê¦Í=Št»#’cÀ(3D!ݲØPó¢ù}#íׇê×R6Øóú(­d”‘õÂת 1Öy`Ôð´ÜïíwÜX¡RÑÙs:2¼ƒy—yÃÜýþÞù*¥ã-Ìy;Yuè¨Liø²¶85UL˜Žaeôµ?u vÙÖ둤÷üké§›gÏÝ𣠦 m‹¥ÓP Ï”K88†•?ºbÛ8ñ/q&Ìè ÒPxÍAÔ˜3D 04QZ$lJƒO¬‹ó}ú¯'Eôó§\VãêZâ0üòê8ØÃ¢@Œ%ðÖÌŸo”¥%ÇÑýÑ›é± ,NÒIC@gX2žQÑÀŒ “iå%ç—Y±-´xE\TXÓÉ5‰(®‹žkäHœJRoסº,ÄdToŽžû>ýýäôiØp’ìÈÔ—úý>æ´ûúðÕÑ^!¿¿õªþ^rÆéIžÛOžÛ_}.þJ§‡ýÔì?=yþK“··öÎ~ýNlÔ7ç.B—Ä ÅCÓKP3‰àíùC$tô|×Òå„$’ë×Å.O‘U5oX ††•ø›Ïþ~üú(M¾–Ì(ÏiC—å;y2Øm虺¡ód¿vÏ=5 44å§Lã´õ[ù;s‹{Gv³†N\ÄjëXª{N¡–1ƒ!šýêe Ï&e6ŒŸ„G¯k,ÝÕ<¨bCÄõpFÂ[”ó÷L™È‰œìBÍ› «+NÝ<.a Gñ\KãÌbèM kh–«‚T(©SÊÑ,ŠM­9ÞbF€íÄ}ÃŽfX›ä"Ž'Š‚áä¡"Œ$o"G”mõŠJq!+(é50h­çš½êEú‰W)Ç~Z’qƒøƒÃ x…£$à8>Ë Å× %~‚Ân˜›ÊœM9‚°u” %E•üÒ™IH €?.lÎK*|;TÄý¶Þwç~(\m¿ð¼vV v±ÏöðlrHúSPžôì)JÚ|¨ßç_°`fE”ð)”é_vhŠæ1ÊÄw{ßßiͽµÈÝsü__oŸ§R¿<ÛïO‡ü’bÀ¥À€Qö¯7Ïþ­è\-·tä¾vq ­é5¶×n¯v–­Ar™¦:‰¾½òpmxúkœ0ÙÛƒ|4(1_iK^]mq¥­µ­Ùì·Ïsɦb ÓÊa~4Xˆ=Ùì‘»¥æÝø•³œA}“@~†.ù±ûÂ/öSHE<Ì/KÏ{UvN, ß OQLßþ2åqײE-þˆH„z»ÝhRÊծކÃc¤7£Ée6Ôm%]VºªúFÃxOWp\ÿ‰æ½iÉǹà/‰ª½2û:Ù[¬ -J É8øª´“^—¥DZn±'Ú}Ì'-ð:%>iE'Kõøº¸'~¹¡Õ(óT“ä¬~™¦Ö5Êß öÜqÖf°ca1Np-köŽ?ˆqÖ­$É­þVŽº‰¥©mä¼õw±×õ£h4û|6çe{ëVcãã(ïm¢é¶~>C*“~8NZExReZ&5ÓK[ƒ ŽÈm¶Ò‘Ül!ŒÜ†šõ¡œ %, ¶Û`ÊBØhT³T¹E&Méä˜ðr¶²ÑvlãìäÕQ÷§ÃÓ )ªcÇDC-"á´;<ð¥ø"ºD//êh†gx5HÁ.|ÔLysß=R\~dô4Ï\WÝù´§¢bÀdrC®V,MÝŒr&!¤ƒ°éiîÆš«)ö3YáŒl¼lnêuwÉz òiý`JzQÆÈP´•òêÃpŽn…Ž+‰©ÒEë7ÍyfÒQ9}:*=Ÿ,%ÚÅêùXƒW³Ìx@;îN5˜ù©/År‹F$2µ˜Ò,}WbñËTÀ–æŸ+Ü+CþÍ  j?Ö»XêL‰³¨ QÒw“DB÷¼ybe†ANhÅÖ4¢é iz{›æÔýýÝë׿—ÃEp|úù¸7××mÆÃg™ %næËŠ^%¦'/ÈI·2GŒôΗ 3©E‹–[ÎÅ[ãÿ‹U1¹dz°$u3ƒ—:Œ-LDB—7³rzKø:Úi-þ]Yøáħª$ñ`l!+çåÌóÿ¹~¿§9}ò\o¼¼Ãº*ôµƒqQ7hðEdÿÅ7šžÀYš<±ÂŠû-߯ÎÔ;ô]ñŸ¢ÕúúI«%ï´¿´_Úí¯®el;UóüÎA^ °>gó[)"I²!˜»I5“’²< ðQuãYËž·žyñ¸ú€.B»Ÿ›ÚÖ|ÉÊœtãÑÑU)<.ù&ˆÌ’qcy¿'§Ý.ÍãXzˆr§ŸÌÏíŸ1Á׉[ŽÁîyêŠPf… ¿¨þê°ª+äã·ßâÕÙB/ sÑßÿÚ)Ò<üÞ‘öÁZyë™\µÐð I?ƒnY[ê±jË.ᬰöyh†VJÙM÷%[¯Êÿ`Âmá7ú gæÏÒ‹ïÛ‰XÉHàMÑ?ð+¤Ç>kNð^ø 1åü÷ý¿_…€‹»rö^žðkµopHÙiº [8€i”Ê÷_XñþÏyúÔõ?º#/'p‰‡.ùvÆkä°tãzÑdPÎ¥çx~»öûE.ABú¢8øɶYþâsMïRº:@Ëöº5ðˆ!AF¨ñú¦9Ä.îéè&××(a·Îf+CöµÂ5rûݺQ0ŽË¢ÔÁGÏgZÒ‘nq ßoo7›Ø”´ôÙ¯[O¾ =Y#&×~TêDÙ4‚–_?é8!¦~×÷`¯Ýþ”)†8|?\òt—ÖeÏ×MüÔ Ñï€ÙbÒ;^݉‘¶yå&ËCWÆt9¿-vü.¼ç(uàoÛ¦_·j{IÉËF·¿!C¦'•!¶b'÷p¤êLù?¶Á‹“ÒÏHŠWE·KKÊG¼W±D ¢Æ.aõ³2Ó[ÖQßøëÖåæûöIQú#‰· ²ì&çÇíÚ‡õ±º$·®âÕr7mB'»½‰Æµ1½žˆ•cY.’‘$ƒ¼›|h^{µ¶xÊËþ-6a=æ“èC&ÆêWc Ï'Q'Pä¼ÝÀºWF Ç=üHr~QÍ¢pý;[ÌÕâE•3ÅÀ×Ãy-ÇK7™ìéu‡»sº‡"vØÀ WkQX‰Îü¯DäX÷ÑáͺtºZãq¬rDÛ÷¤½¡+Í[L's.õKJ ËRTáÖ|ßocónpÔ+c†\å¹ Ôb ƒ*zÔý–<ûZPhŠë ¥¬‰DvΫxî3ÐùDµ“¨â=ŒTï `ARáø9ÐÎÏ^ ˜}P‡Û¢ÉÚ{´¯¼y÷¶÷㻣£×ÔQ¥‚HÐïQIȯDâò(`‘¶ïn×€‡Bs.Ô³bîð:v)ôhu `wS €ÅHk’Á½M°6ÄT@‰Î(Q#Ä2ïÍÈÊÿ ¸ ¡ƒ»âáÃÀýÌpEÓ«ÁiBÙ$O7š!ª¨ã5W`®qbŸÍ‚35U¿ÞöýLú“vCB1B+ƒúè)¸eð‡z û öÊß!’C`( —8¬ÅRì.†×½Åµ}S°Jq!X_ðŠ†Ý kÏíR‡hè‚ѵa!"-G~n1ÍÏŸÉo‡ ­Œ_žm‡‰~žF—<V‡¨Ë—X&™ÜtgÀ•d‘±O‹à+iô .pq¾ôâwˆ {¥ýrI¸¿óæÇ÷õ©}ÿx‘<޲h‰ô§mˆ_ž¾}ö¢{øòåy|!OQLË–ý4¸"(¥ú‘€ ªK ‹€g0£Ð*pîzÙ`Tb­x>–TuÔ [Òì~"ŬRãPйé ]|åâKn¥X°Ì N›ŽzçS S¢SH¹80?Á©ƒw>íé€ûÇsä“Àx¯ðn@Û0cŽ›¹ZY_[hsY-Hzð ”f:ÌF¡1¬c.å¤üùÝeÈqBå5bžä*;‡”ÿ8b×Ìõø†¦ã$j0¡g[JN`´½Ð mƸnY37kK«¼x¨ÖD õ=ÝXd‹™d}4·5WÄT:¤ø•b\Y5æ^¡€¥N•E¨él32*]Õ¨÷Û¦O' E†iÂ}¤å:]\O-ÃÖ"ºQ} F"!maê4…J*–o¬ã±Óa ÊŠi‘›Ø"ަÏ;?nöB–µâ27Aƒæ`Jœ‰Ã—?þr"ÓCHú"–è FxÃ’*b0zÇ%V¢éPKר,È5vqü×'§G» Hr-p ;ݤµÙ:?1Ä=Åõa7‡!hžÅ/¤ýIˆùI æé×0v3© q]d b²·© –sƒËÂÒ#æ,“ŸÄÖH -ZÓõ¥T0lVš1Ç!ÿ¦ò«œ“áQw2zTÓF8ó©Ã‘ê @5hÈOÕ«W€šM¾ŽÐ)§-kF‡Øó–¬ÁŠ”Ing©ÏÇ×'Ó¯¤Ó»†‰ Åáqϰšò•)ulKÒ| Ux^MWXÄp°P9š(êÞˆ;†\îBô‘嬶>Hµ.$ ÈJ± É0„›.eéò„ˆ•ouôc|úÏN¯Šr óÉZ½ò$eI_AS›à¤ù”FD×J¨¶ðÜ*Å㊠òÔ…N‚ÿ¾NË.6LÎܸҔæº#B†›8šÝ-«§î"´rÌ‘ò»êðtú­s¬š$¥‰Õ(é2“Ç 3Ñ=…qAýIã2u„ °sIÇ~Å ¯,?J~tÜôÃÿAhEÌVæçAÚà©s½F¼Ù_®že=Û¹7·»qžKI¿ÿ©¤ßF÷æ\«O"½Îîc©oþ÷R¡²õ\<ñÔ¢—æÍó¤:«ì_š‚ôgm÷ N€Ðš—Ò°âŒ1–,ÓB“F¶*ºÏ¢¦{˜Wz¾EµdÍ  o¢ÜøIŠH*ëO°¼°î®$¹y eàùÖr¿¶(ˈì^3´È§‚A±Ð©j©z™˜þÆ/[à9W¶B=4ƒÃêZíïäÄÁÝ jbIO@'¸)¶5ô Föy)Xf»1ûCrfg3)~E9Ýe“bŸ“ó. \æ…­{â3?gS4t¤yW<Õoå÷Š*ó¼ñWº¡äÉSb§T”O餜‘¶“+àìLb«Ó¸ô¨¿Ø2è]e–!ŽÈ^s\IL¤i/·4™ä]¡„1Ã|ío±v&5ƒhÖÊ6ï³M»·ÔB^kó/~ªa ¯$«êíáé?ŽÞvþùæ4]F?ýrö;žûÿ4P±ûb—J³¡Ô`ö(Á×L *š‘I&æs6ÔJFßÆÎ–ðµZCd=¹"ÓqbÎ9Ö¬F)b_žÊ&üoÊ*Æ"‡Ai²rà¶]yƒêF¢B‚Ž=þ»×áö1lš«DÕY²ºJG­9J#8UpýŸV%3Eî†ã«$kG•4)‘†C©,БjK ²¨PJêF €‰1ëÀŽ™ÛÕU3®$V¶`´Î,1½. ÷U­0üÆ'˜_¢9ÏÕl*Åãm*Ñžâ‚=¥ø}öîïXþàsì+®n_)~Ÿ}R÷6ûÊ¡°>Õ¾òÅ»×̧üûñÑóܺ’Ø·ÖZWTÜjÉdiü“H m±•4›HÐY5&d&’b›‰„NˆÔDBҺϵ†èjqk¬!Ñå±Þbn7·ÉR¤Öl63kˆÛh )i qªT5XCŠGZC\Nî ì³†¸ÍÖbƒ5$ÐÜ­±†Ÿd q«ÖûHf ÷n KŽIæÕXeÁ£^ãt\Eœ%V½›rËÐÿ­#tâîÊ-å*J–·Ô¡»ÀdªoA{dqüšÿëëý½?l9R©ÂíɺQNW® ìë0 ƒ|aO´u%ú•$µ“ˆ‚W yÉw¡ˆƒFa‹Ò¬7¨GY â2v§^ýjÄ…ó@ÁhûSß@£´“±G&àOÆ7#ÀÖ,Ä•f[E ~Wì”—ÌÿzÙƒ‰oK5ö! s\ÚÛÚEÉ(Údò´ cRÂ)ôÛ¹Ó¥¹øcL*<Q&fMü+zTø<ãc˘¦àWšâõ²7Њ/k Ò‚Dv Ùn©Á8KýWíú]È Àm”XÕâÄ™O[ÝøYMƒ ó‹þNéhÏ#û;/&þcúÇÞþ×úJ¡õplãoÿ¼è‡E¸\ü­ð«Íø.Ïõ-Ï’–D±,ï$½H.Cw_ã!µð¡D¢™µ²º)ÑcÚ·èóç½Ä4Õ`³1gÁ!`BÌ*Ö¨s>u·‹'ªÃj¸ºz’–f¡ào‹gs8—R’q1.$a£–õ`GºnGÏs:OIâv€+/Ç—“¥gaá]­®>/å-AXê \{Tj}ðÚg[šIÌ8ô[F^Ì0CÙøƒ¿eEW(šb­$#魯/ŽEnÉP.B›a/kEÖwrSC œÑxq;rÝD+üªPœ'\X=,,ŒJ¬…kѯšßyþ¦¶œL’µðQ³¢©2Œ&9çkQk}EnòO…ì„…mA^–í7¸õ 6Ûÿü·=¸ÿ—ÇÖæ?}¶¹<×ïï.þr΀¶ðåƒ/À@2eü,³ƒìùÓè›ÍïL®Ò7þ$ÿ]Í&éeÕõÍíð_ïGwãÉô7¯G.?Ü|ø÷ÆÆåhY5¹øW?¸s7œã¬ÏßmŸ[€x˜°î^n‚ùÉVò²&cטób!5g ùb–.& ëxy” eÊ©Çj¡L[u\Vž¢Ç»Žé;µ6Ò×åØdÖÏÈ/} ›xƦ¡ˆîb:KF¹÷ ª¼MYNš°o’ÆÀ4‡ª¢´f‹üx÷Î!޶›YËÊa½€ïŠa%šEù×f³hÉ’~™Y§yù‰«xl3 ˜xÆÐ½ fS'F\Vtˆ}‘òMR%è&—ÿBµ0á±-c¬ô5¼«ÚN=p*G¥«Û‡ÌÉÉ5@/g fWJ ‰6ÌÚ„–ÑVɧ­j˜™F[{í´VÍAzH´º­&Üb½ —4pOp=)¤¶ˆœ½ ³!×E ¤èý‰—_É‘JhÖ m µßn0gëÁ…GÛ (ËXË^Š?LY¸°õ”‰q!çܼ”Úï>®ázž½eü-å¢+ì\Nî¬ã[àiVmiÕQÕ !M¡6ý¬ªR›ÐÊ:$}\ ÛY-ZKÙ”M± “…:µ¥`ñ£fnÍÍefj¢XBâÓoâÏ/ßýttªöšg²ÙƒCzU7åoë¢6 …n·ÎŸ r«Ûëm“Êï t9xc_=g*œ#w¨Í‰zAÙ'|;~ÅG¶ˆµ{¥©.ºm¡¹!þV Ök d·Z6Fèʬº›Dƒ¾;ÃWPu:ò4éÆ[g‡?áº^{ž#åºCÔ«ƒ±l6ñ: IH+„‡ŒAa¿P娠ƒuY rOdÕ!ú7å_>;=dÚÉdLoÙ] ›6]Ò²ò¤þêpAÏD¼q5±ÄïM.ùße÷ªÌ&Ý®ç^åøÊ¸ÃE»•7$Žp˜Ù°ÄÇàltéø×”ÑU[šF†Lw­qȳåX„€iÅò>×Òtˆ2¿iݼX ¡ÂPR¹J˜óŽ%êí\LÈiþ/sG >\MS´ôÚêÆ¢¸ K–ÜIßÜ¥j‘09åçL‘ä®®fà >‹{äæ\4$.ZôjBÆ®T~šh1fÆMß!º„Ú‹&b B]Hp ¦ÊEA*‚F¨µÔ‹cê'W‘B7ÑédA¸ BƒÁv¦ì[ßp:0^ r¯xnhЛš¬‰î­.¯|+TÂÖ×(§JÎF˜w1j—nI : ³ì5^‘F0uiˆËª2…3š;ïùîEê“T/A;hÀ“Œc»â—\ÚC´={¨)Žù7äB°n‡—Cù‰8±¢éyú^Bó5X¯ãÛꢲ3¸^V,^h9d3>±™¯rÑZa÷†ÛÆÉÛåOdLÏ ¼»òãLÝD¯ë“È{üw?q(ÖÛÁ}M÷Íoµ½xž_ÙÝä­ І ÏW¤V%TÛNRÇéwœ–ƒªch±ÎÕRÐöº -8"Nú-xÐ<6MÿæòRs±F¬§1%ò|Ü:4õŸüÞ”%gH”ÇÈ`ì :ÕïëÓ·þHüùøí‹ ØîõÉÏÅé»×¯PÍ´ž³àf2.\òÆLÂÖ‡ÕU}k™´«mÌP+bsŠN”¢ø7Lî@“[FôÁá~ÌJÏ']sY¹òzCÈ‚¾\ÏÂp>w»äÆi"¬¦C–8¤ùõÔ^¦À%ÆiÃ8 ^M±á“‡@: $tP4þàèBm,{ÅEÉÁdšEow»fQB&€¬,À»Y„‚¤'? |ߣÊ’|<¾ÀÖŠ¸!s=2jÜjÕ³Šñ­X­T³`‡c—`ƒ´óp;/öAž+¨”ˆé: *~ð†ˆð*geÁU·'ðk`숉îFÖ«ºu4] iî"£r¡•w—WeGì£rjE_±ïÒ†AÛü÷V‘º*ïSZ[d´Ÿ¨¸ñõXIÀIhÚ©m¹¥åÁ_´^úÌ7ÛÌiµ`!†„šºåZ$F‰â_A·ýÁÈ‘ìš9Pú¥h ~y¼ôSæ(?÷ š±d Ó2çØ^-í{¿ï©×„%(+ˆ&ÙÒú<°Ú³pµòk8aè«FÜ<&A¿ß?¨Šÿ͵¤Bµ`¬ÖJÐs3¤«ùp¬ì§¥ÔÉɶ¦†OË᭕W6®Õ4¿4ƒÆ¯nTª}gz´2÷ÓÆ°GóZœ“æSñ [÷P™ÅŠ®|¿øÙÎÅ]ðœ¥xàg4Zž»/%œï"~2–*U–$Y=˱ìjÂJLÄÓ+E Êdžb· Dc ¿Q3õjëÒR†¿’Ê•x ÍpÑxÚz¼ç"˜tZÈÖî‡Ú‚*CSÕd®ùr:Ì’j/®Älá5Ïep²0û#˜ìX•‚5AØ8Af‘¼šhg-–´‘ÏÕdŠ{M± RË þ%ˆÍ‘fÑ8Í¥)FULiï`@^UËßáÃðz™ãÏb³Þ×E0Nû™©•Z/CÏsÿKÌÏNRŠ*ÉH¯ß§À¬PM¡ñ {ŠËн˜„OJUÙË)gÃ){7³nêÂwÙΔÎ,š"ÑÈéy»ã,ö!Kë–hµÿhÜ £F’õ«†E³ ¥4 ASj\Õ—Hpö¨ Ý5 ÝôA3ùŒ'Áp o›–$"ÊÛf­a­j šÃzCKÐõŽ\rÚÐ%4â1µ‹xùäf,#¸™ÔE®´>·—¶¼–[Îhe@͘¹9¬Ý­`SÛVi0EH»¨Òй/ÏÜÛ“Ž„q«£½¼}V¼ð²ôÛÙërÌg’zëRbph»:*P÷ÿ|søúìøäu[¬>~Ù¨•Ž¬Ï U…%„ ”Ál" ]›3¯FB˜®²ÕFÝ_@iñáÿI:(§å¥W7€ÄjdžiÝT!T]éÕÐþh]/?õoŽNßþ™MõQߨ®%½ÒEÅ’X+›ÐÏhúU±Ë§Q«ä~^Œ_<ß Á&mX/”ÿù.ðŠ‚èeMúe?]úN>€/;iïi ‡$”2¤ÆçÈA¶?UÖ˜ÛÚ¶Â'ùïË«+a8ÛMóÕIÊ€ çÅ!8W]ã@H&•š’Ȳp¸´%ôPTÑY³;¨ÔäBÝ®eýRÑ1óDˆaL ×eÞàu U¦:0 ·HÛl 1ôHd/ºÕ¶¶PA¬œ ½i%ô%j½?tò^±Æ Ô³^-ó‚>­6 àة°ù‡„_µB6væ{‹¶Õ½lUëê*¬pô›á%¢Ù[BŠYÁ^'ñ P¥¤8ë¼?L,í—š£Åu‹<%ŒæêÀ2=sb¡v H<å Z øí»·G§¿ž±–ÆÑ¯å~={û *ýtòòÝ«£_÷~Ýÿõëâé/ÅÓÓãÃ×îÅáéOpãêÞÓÂ’ÙJ¹f`—)õœà^Cl"1¶8qœ¬=ò#å¬$•Í*‘i>Väh©™æXƒ&º™€0ÏìIsÚwd7ãñ^x|Ç‹®­Ji‰6‰øä0Ⱥ±¼ú8œ[µD‰àJDÜ… ŒPìÅïŒV)q–2Ëûú tX-^}.ƒüi¶‡+0 fq­)t7üèàt@éHšDÉÀSPÓp®Ü‘àê*ŽRçe¢›É&“Pbî7î 2LfCœØe¼ÚñËjúÐ01ÁÕ†§$RÚøJäêÅDú2àˆã%Ú–×}%ÆìtbÖÎ0wú ³3aëDXÆÕ~ÑÔ}9ýÜÁ/²bãD¼¯ª©luùDKIT1•¼­åCå]f­¼efð<«€W<Ãõš|y%U[¥•Ë4È]ú·‰×§-%”2®bVà„B#Ç|?@s´Èf—Y`ÙÚý¾•…$ÕöÒ²aéj©¯ŸÕácà DIJkbOöÝÌj¶»/3ÎÒà´<¥ ²f˜Ÿ ØBêÒär‚Üê]Y´Ì˜„“àVÕ³^>;‹Úv´KjÂ]œn>žûÄP³„t­x Ðø(ˆï£×RèbøÇ†R2†žCÄ_Z°ëíÝøª½ðqùùîo‘"O«ÙûjTiÍ!“#"Gôjbd¡Ý³ÏÙ€»!öQŽ£%Å L_ót¤ ZÞ ç±-+3[ŽV—„‰Ôl¬H®T‹JÖ1K‰Yçϰ¸Áh@à ¥•1cíÈJ­[à¡6€=X/vU³õ4ÙÉÆ.“Ï)>µOiYeEnÿ:ziçe±4ß­«ò»E1MßUåô»×ÏÎßÂïÅpYÌÒï¨ÃáÃ:›¥£:ý’Œù/æçl‘GcÙ h|lOß¾=»9»¼¸¶7—öüòüïìõÕéÕØ"ýRÛË×ÿ>~sc/¯ÎÆ7ã·öÃÕ廫Ó÷ïÏ.ÞA›eúÔÑ ¼ù¸:¶7ÅʘÓÙ,«a•­ {ó´çÙ¤LÊy±í17i™"|òÂβù~˧©¤õsšæ¶~L«áÐZ—ie“|f xZM–óx od¡×M ã),~fá}U×I9£†êÞ›d]ˤÎÈ‹ ´^eЦ`†Þ`Je:­‹rca¤,€® §Å"Á…ÚbnÃ÷—oÇ~ÿxñâwØÐéc–§ÕÈ^æ2ÕËëj`7ÅÚ>g‹…}LžRcVÀò²Ê,“|ÃÓ^ Îûò¾¿?½x;°_W5¬ïsŠ ±°èF§Å·ê÷?…Kê&˧‹5t4xN“uEóyšÎÏ//?\ÔÀ¥}Æý€¦óõB×z4¿û:[¦‡~{ú#{],S^{^Ô0»*Ê:™,R^Q?1ÉC’å}˜ìº¶š§Ì$#TÈJ[<ç¶Ìk@÷ö}š¯ñ‡×ãŸ/¯ÆÇÇøìôwþûì‚þÿ6¾ø@?]¾}Ë?üñÕ%ÿtöýìæúåüôúföáôìêøØ¶ÿàÛ¾…–×ÎÏnfŸ.¯Þv5¥·#| MoÎÞó¼^ßÑŒvR^†;’°”íG/8Àx·¾7f’Î Àõ!ý1†æØã‡ö¹(g}~<9¢ÿ¿j7•v4õ)ViI'p}]¯Öue{Ébõ˜Àñå#Õ·ÕþFtʼn°ÁfBSú½™œjaeáÿp—«¤Ì*èu'¬8¨³ (Ã=PY&_LøÕæëå$-þÁ‘üýªÕÔ½Ùh–B_Iù€ àB`ðÇC™&uZ®à%ü•qØ Z?ÂðÝAƒ¡´YN[ ÷ Šö›¯…C‹}°€FÕ×B/, ¼‡Áh$€Òå+z"sòO~Ò'¦ÅÝ\}ÛŒˆ¯¬#CnE­¥ñÀþ|z~=f¦ðœUéîµÈìy)D²ÜZt™{VSÌf¼Y þ-|ýJ ñ?¶;¯DI®[Œ¬sÏZþ3-‹xgèI´|ò•ëIÿž‹\øå7.&˜>¯Çq · ]ïžà–×Y½ÂìÖ¥ÏAfYÏç~üd|xdÏj–šÊ%'à“ Ñ@;ÏJ8V¼PXß/À,@lᔑ”ôÁ NÇ2" à]Ò \wˆR><7®7Û# ñ¿—é²xJg€GŸò'+øŒuŠ"×þŠ¢—šnð-àNµJPý}#'ëй~Ÿ‚5(úŒøäÂWö`$»æp _Zz¹{¯dcx—HRuÛmãž}B9>d8ø;©Lˆá€÷rFU4°,î*Ê,]U¡MÈA !Åéìâ¨÷íüìúÆêÎ¥Mbd¯Ö¨mÂ>5‚Š]TU60ë'¢6HQmkµG}¦Æ [Ê#Íë¢FkÀ Ã¥U±XÓÌAo[E9V) ÏŒ¶t`+¤ µ]¯Æù,Õ¥ŠŽ~2®aÕ©]¦I‡©8È8Ÿ€ÈTŒ¢@ŽBØÝþ¹Î¦ŸGèKL‹K˜(JJUú'œÃ£—/_ÊA¿}iãŽÜ?¯Zÿ|/ÿЦÏÇ‹d…T G=¶G?X^WµG] Eph¯2òÀÒ¦Czº˜ØRE’ä)žÕº,žhÂN%µ-Pgllì5í¬éDúh6œÌ‘}"¨¦pî@{G^ªÔú¦c¼±@ñ·OôwÑuÚÄÝ)ŠP4â8÷´ìC¯k˜>šŒY;Œ—&%YR`NÐ<ÍðÛýÖsØs'bGõæ UîlIŠ6¨íÞ´Rh4rú…‰Z$5DM™B·Ô’ކC/.C´xbkDþè»J¶‚>4I¾©ñ4÷Ò/ÓtUGÐê¨ ‘îá·Eªa§¦¹Ã¦0ïi]Eã•{qQÀQš^€¾GŠÞiÖ¶ôñÞŸžµ²Mö®ËÉßajö²Ìà($@®z(“%¨DÛ-^hó"k Õ€[³ )ARnX8ÛÑ©½Þ€\±Ñ6ˆd‹º(X™bV-Šçœ t­b]AK¦¤ã~š ‡´id<š¤Øó3n\†Ý`ò‡uòR' ÀÂ\í=é—Õ¢à£8`“  >m;b$ÓæÙ4E[ÖÙœ-^ˆ}€·5šÐØŽ„ÝÁ+¶å ¹zL,*%éŒ tµ˜MûP34ß• “m €½[ümO?þ~v~…ûüfüöãÕøš­/§ â¿‘ãZÜ|¼º9—ŸÏÞ8¿ü8ÅMßc£ Çõšæ–±½’³ §v´0æ ûŒ©ù·àYPøhí›gAºV0ŠC«‡˜°ÈA,ÒîMÒõ@Û©f@’\dãhk€yB“@¶\/ÐЀl²^Ì"M> 97•‰T¨—LÉô³_Ð0zCè‡Z˜À.JV>`ÂOØÁ mâ€ô€CU ¨÷:N-¶À% °©Þ|tª>ÉZÄ3R×÷5`2€È,ù4CšIgjVÀš„/_ÙYáÍSRf¸Âªï¨­S€ù©„@Ž+`è„9ŽìÇcR4n-RÜÔæ²å2e8RTŸôŒ†r#£6Q¦({\’à þR›,‚VªHàã*Yê8ƒv%ò¬Î’EöŸh FŽX?®Y£\z€#VÓ¡(jX€ê¦@Ñ±Ìæ:އ5Š"îtË~'Ðb–™ÊH“žVᔂ ‘Ž;jGÒý”$À/P¾ ÜxË´ª çÊÞgù”…«C^èý,ÕØ~¸ŠäÈ›à•ìˆÜÅsls¯+ôeøXFm!ÏÚ›®õ¥(õs69¬Ü WëTímüͱüð_P×ßî¶÷äÖ¸­§aWOð¤Í®å€NÀbóÁ:‡}&§‰¦¨þˆ£5~„z ð’+D Úœt¢íY‡edñœl*ŽìÑ€¼h‰Q«~ ;l'žÓÑÁð) ³bBÈ |Wõ -à·ÃôŒ£Y87zÊí5§ïÆLq<¾Ú¬Vy}š"†Ã0ÏÔ  ˜2àÊèQ²•¦° CþH¤%Ÿf@B t!ñiQÕ"A@<` jT.e¶9ü!)CN-GÓ?FBèEœÐd K„78fpÔçë¿3É0‹'?ß`t¶B ‡Â±¨ºÍzG+Fj Ù½ QE:¥=[ǵ€x¶Zr†²î‰pº^×›L'XVƒ‹èé)"ñˆé™JJIÉÓ˜C“™#› ‡0bWµ²Ôü_Ž-ÒY¸²µÃ¡âšðÒK†D X4J…§xœ°®AŽ!eó^–gF¾4Ê]5dè$ÓTF@ –Ù‡vÄR>ˆËoNÏ#yNÎ. ‡›q µL§‡-ÁC4♄V‡¼ 9“Ç4™án€ Z¥‹'KØÐ9Jl¦X<É1ð‚He6í+¾™9LêšÞ8DòÄg‰ÞÛ‰he¤ÌÃÈñy ï¯  P?ób1;! “yDu(#NH4ÅõœOu&¨IßÈvðAÒY½ŠÏZE Â<ÅIãºG˜Ö'0«²· ÉùÏç†$t“£¶i{2>ÀçŒQcúX°*‰lë éÿl)©"(Žì/8w6ΙÆN3´«Å~ü «á÷"D ¸J`l$« pò`Ä%šñP2‘¿ì{$ÙÇ}# ?¡Áç€âDúPBÆG)øÚÒ&”Œel¡Pu7œÀ*¡õðAHE¯h—ߩ܎ô•e6€ùºðÌYl–8ÅxµÄŒ*vÔÞ02ì7€@¦/ R6Ïó™²,@™dQH˜ÚDx‚N´/Ãð qõ‡1¨¦º­Ö€^ ²Çµ ë°•¬ëÁ@,Àû”шˆŽí¹0<éMi@ä4fføcų¬x.3¦ÈÆ!q áOšÌ*¶ ¦\436Ÿ?»cêŽA³ð6ø´q ÷0*4çNØ=×*\ÌM_¯\ç}\E%vRTŸ³)²sû$…J>@hä°ð ͸§Kï‡UšìzµÉëäK(óâ÷xîÄÜ|Ëæ"oD¼•C4$Û%†”8RÌ¢8BšÃÎùR±^Î;qL¡GéPÞÝâÍ—‹d9™% `ŒÎ\ñ ¹ÕKöq‡$Ù’nú, íqàjD£ÝÙÝÙŇ7dš „B¯çV Æ]tt„+&…½1W48Jè”Ö´§#²‘5G}Vöžgr~‰ì¾»Cê¢Ùª5O:ÆÉ*:3„u×CÙYdÑ 4èqR‚°›ù@áôä pÒ{áªú.J I˜A·ŒJjŒ~ŒŸ#±€4N# v/ï¾À}e˜Ü3â‚"q/ëLq¸dRˆ”§ ë$+¦ð¥Èõ@÷ÁÑFlÀ@P X>åû$+aKÐSè¨ÂDk:ßñ´+¶ÅÀXäsM‚bþ› =.P(öÍåûgçcóéòê×ë§oÆbDcô'ñwž-H'“øªàøÓæè®0ò«œ#‚Ž.mdßТ©"¥k±c_©ö${â[&ó@?w0k4Ô0Š"ò! Æ5&‰G¶š ÊU 29ü|–¡AÇÅ ÊDÉ!eCÔäD$§Í·êMŠ$‰>KcN¼we`c¹˜í(vp Pì&6EË7â'&[CU@ÇÀ"YÇoXcCù¥+tá߸ÍŸ(®É”ôU6¦È4ƘÔã³ ,ä\N:ð¾qÞò'fÊzД.æ0”“Ù^sÐ]BDz)Á‰ – z‡ñº^—ŠÜGæ(1Gœ¯ƒ.gÊ›>¦ÓÏÚê >™a” åJ˜qÊ1„¹Ð’.ªÔ dÃ1Œ1w‰XP“Õ(=$h°u*Úþ.XNÒJW!=K!PLŠÙ&Pç#Pm„ñuâÜ0ìÒ°eY¥N±tlÈŒž @3M*Ķ{<.‡ì1Çø€=‰ø$½<`vÀ!ž³…¢gNVCP Ñåä’Qªe6Õz¢¶[ŽÜr¢G–©C  A0#*/ŠåiŽ&ÛrÞÀ6 Ó 'ÉÑÑp€‡$Aö…[Ërœ Ú“*TÍ.ƒÕÅÇä1Ù(—ççö€'G¤BÎì€ú"åjÄjhO4=+Æþ‹Ó÷-ó©O±ÁÌ‹ÄØ;`Ò3†ZµJ¨ ˜Œp™3¼àÎaø8\àA$=õ¶¾?r?i€ß™“eª,-Õ:’HØ4–Ť§â³3ÈLºæ€ ôŒÕÃÐÒr³ "ŠI»õh34…<&™=&Cf`ú) K<ƒ tÔ«ªeýáù füÚ·žãéÈlìtg‘Ñ`B̉ˆ’nÁÒ àT™jP»£ƒ4n…´ °‚4Ë4]FlƒEÀuž‘hÅâ+Ý0i~ Ñ7ìPãôüÓé׿Ï5è:ÐÈ6^¨ÛHaª NÄ볡OÕ&oÈCe9\š;‹“úøP÷AzpH ÒÌs¢nz:qZ¬Ð0ü|JÖ(à={騧L —>£òŒì¾š®a'¸bSý;võíño÷ÛI,LЙ\Š]€{½w4Êú ÈIèçõñw‘'/öê½–˜k6s-wÚ«¬—Œ®dªJØ,ÎT`2”‰íu Ë$bb@AìQå5ÌÞŸþ:îç·#z‹!ðcô½£óôâíÙ¼¡_ÞŽÏÇïNo8âý- o¨¿Ž0y~Kýá$Æ7¿\¾ÿpyuÓjÍoGüö+Üý¼{8¾ðQ‡;¶œ6rËkcBV„¡ù@´ˆW8Vá µoVÝáÑr„.ôg;€‘°"Ò° Ø{lx¨q-}%byúŒi,Ä}fÄXœÈ¡6†ÊA½3N¢f)k8$4÷<)R1Dæ10.ø4’ø@Ž[§lÉÛ¢ì/Å3Z@F ”FU_'˜“J+N^QŒ “߆°¸ûÀ *H(² nÃKï°g7> g ƒÝˆwl­ƒ³¶ßÙ[ ãš!"!Nbˆ\bïÇ××ÎI%è`‚0'ŽÆa1Ðó5âœ@ Ñ’ê3lf²He“ü7%vņLÓ²Õ_fû"âÏ \÷‹¦"–9¹™£=¨­'\}}ñ64Ø‘Æò‚Sa"Múö„s{`œP æãcvãB–³ÈÓŠå–ç6ã¿G[ñ÷̷6Ý…,5ÆX¿‡½Kf³Ý^T<: Y\ìùÀÍK§«äÊ©cí¹QŒ°ç€M‘ùqKyGÌ·ßž½;»9=n{ùæ×}Œ;Ø&¡ñžÙøs¿¹»·o–.ÒXNsûôyÇÁm„²*a9Ô)­Í£"Ëõ§,óyU€1ý»F9T½IäÆõ&¡÷Ûͯ2½»áû¶¹£²/&=¥êAtžØJ¸U-§™‰Æ¦š#|èt»=6ÚÉÏ ¹»Ûž`÷PZbÄXM›ïoÑyO@&dŒXÆF–ƒl)×øè=¶=D+l—xÂì·Ó+&±lãçç¿ad '%V…¸†߉Í®¬mˆ›2® ^wNÌ.Ùù3Y£Åt$ž`4Ï’q±ÑšÅ(:Â9åîð¸øm Ì=„Ü1Áí˜&ËV¸ {ü—,9bú—ŽvvÑ£Xó‰”= NùYøI¿ÙÚd“=Ù‡¥_’%àÎ9œ>!_Ç}¸þCÓX§þßü:¾ñ·@a¬¼º„G øHͳÄh…‡† ˜Í!Ðür³œ\LL›×–ôOöJIGá]—äCÜ2e³Æã¾*(‰®Š´´i€{R ;p|ØwŸb¦)£ô º#ZOrÔ‚é!?G‘7 ¸6‹`@ÚP¢„»ˆ0'y—EÕ&pØ^Åý²Ìø‡Kˆœp(\õÍø÷Áeè‡<Õý‘ åv'fk¿ ’ÿ~7tj¦†%SˆêWk.»TÐר(¿a´H5ÔV‚:UTFáB½Å8j€ƒ’ çxc#qï³Ú‹´ZfÔ%‡'HD‹èh^:À@b‚Iœù§ä²Ç4Êr3¬‚Y¤§>´Æ©==±ïõEæõ²‘¨é>M³§ÔÇ’ÛiŠežþR(|Ì·ÂY>µEôyNÕŠÈân´ÚÑoá‘Má@… …)PÖÞüña R@°Xv²k—Mâ¼Á¸n–ûŶž•öàÅ¡a†=IdãñæP'…hÄãÑá€L,˜ßb®ÆŸP ºx7zsù0ìjDË=þ‹ÃÊÉy«"bã=›µ™=À™:8µ;gtf8 PžÉ ñ‡p¬›c˜ãÆ‘×{™Rb1;óÕ(«àâpê×跈©ÈÑŒUø0ß‹ËrXÖŽ\¤Ó5ì®Qù—6×Å7„…|&2HRðØ e®øQ0‹)½ƒ vx8ZÉ4 ¤–H|ŽÐÙÙ`v…û"«pq Ó"Ÿ¯‰dáäŒÏŽÁŒ“%*ÈMàÕoÏZµ÷s‘ kÆgÑÀ}c1–žpsùax>þm|ÎtS¥Ë²p¡¼úHyã9œ_X=üÈÐÜôéôÃöò øVË7¼¾¼z;æ«èg‡ƒÑÓ7—7§gò0§z¦Wh”F)ÈcÇsVÇÍÈŽ‘-&:¢Ä­‰miSô±ÈiœŠ$†ƒœT0Ѧ=Ñuð õ‘[e(oˆÐäjN%¥Œ ó°þ ˆ5¢TÊ¥Jœ-/ÿ_‰Ñî¬)'†H2…eküLõXU 2+ê¦á°Õ!mˆ©}Ys·ì8Æ0Ç0£Eq”ž ¦Ï2(½Œ½ßè«¢,ž†}ïšÜ󆬊ÁTüŠH8`vŸ³=L ÐqzBJS§8&Õ£ËÑaJ„Ftï,åQÞˆÃ>š¼> ¨I<âiåF®Ñš²^¡6[tÆuzó$¤¥Q‘31â8A¶?&ÅüºLªæT#gÄ_láDròªD ©î¬"¢iDÓ`:„CbÁp²>R%DÑ¡Ak@žMêéãñ#–í)`—Φ‡aò”ºÈ“̪j•bVŸ)ÑèMÓÊã+;ö´—;aj-Ár&Ç„|•¢Æ-RR*1±‹á—ˆ z^ß\^¾µ¯ÿP‘¶e*&ŠÑ¤b»EFYZŒ ÒÄâd‡¨H6+&Õ Ï&›èˆ†3ù®²ì­Ô"…zw´—còÊc¢¬D1Ä9“šcîD©o¡Ò†±èbǪš¦4 Ë×9”Òa’§$[$˜­†¼Š&LÑ[ÏYõ(ÜMuR£(foä# Cãž=F·gD½no) ëGÐK YvѶÕC'èâ^¤Þ‹þƱš“yÐ>›êŽ´?Ld¹E­{·³¹så|Ã7h úŸ&ÐenC£ñ[/‰Ó8aûõ}£€ær peÔñÙ‰Û5 ‘?-`ë+Ušã°£È4Ž©ƒ19„ݬ0¯VÔ5j+O#%ûåÓ¥öÝÍa?$™°›Ad¼¤£fY„A/ûaÈ5…d¢{€¸¸v¶pxÔÂ¥Û†™¾±Ýz ÓþÁÃÑèáÕ(š’k~×è»ã»ÿÖÿl´&ã{VÐP¯xqHdÓ¹†Â’´f„ù@H;ÖÄbUJjîò_Cí)Ò Exc0}‰: KG‘Ø,UeÜoå d"#±\2\RÕqA±ž’uN³Âp@ RMÆ‹…‡„®¾Ç¡ß0 úö9iEHw€…W(±GÞxè"ñ]†Ð±ip?þa¨aóèö;bé J¡E~tž;wò¢¯^µ¾zÕøÊgíÈŸ»ýsù¾Õë÷wRÆìTä€y²¤Ð9Ñ@¢SK»¦ùh#üËn?KUóŠ9m}q>¾ñ1óšmËž2D ÌF¤ÕœµhøŽæ¢Nƒô¡~‘½$ìë'4ê–©ÏT­`:>'•|¿^¾>£x9þvzþq<ÿþá ¤Ò³Ë ª’G:M£kª#ä¬È -"Kƒ¤Ùé+M6Äë\å<Â0œÔ‘ÓÆ‡Ã:0:‡M0?``ÄÖ¶,H¹#ý£=¤ZüPkÄÑ8DBA³’Ÿ~¡:€N­»÷G3‹EÝC¿UQ?šî™'îãèÍ+LRÆy6Hb–$}^†¥„8¿·ë»0C˜¯ÔPB7${2§ì·éCH×jã\¶™b킯·æ@pŒWAÑZ7Äo«æ=Âç[iåPJôÒÂo½"ržÎaØNW ?2þ^ “Íê¨Î‚qàb‰§IYR82¥øüFXè2„P= é+I[íìKÑŽ^ÔrÒŽƒ¤XóÀØC…<.‚ä¯e€ùæÉ ~†žs.g#ÚƒNéý·Ëv‡ ü8Rœ}'"^ Ö¬X?¼HDÖtŒ2‹¸gµ¼…tàçÍö<ÂÉ—~Ê¿Åèú(uîDN…L DÔ!û*$3+â‹+ÓºÌR"•™ŸŸ •¡è°å…üz#ÙåYÂuyanåTÏ—Bþ¢ñÅÍ5z§}>¯Ÿ­—ŒBF²9á)§Z YŽ1âqÁ¡†ãØŸGç±!Í¡y ¦ëĦµô%t)&Ç:]«À¢’ UM‰ ƒ„®î-# AÙ†ø‘Òœ…¯+´@ú,´ä‚EÚ´ 抵l\ûÈ-yÄ™»‡, *Û è{{Ï(*é/g#Iñ)çâÚf>ª`ξØ›P´!aec9…Ä”ø¤(~D4>îIìø_©==4Üä©ÈØ bC—zB¼dÀvвÂqÄ»+§ŸFÀa2¯Pèàˆ(G4}>‘¹G=íÄ…Š)/ŒŠ‰°ÂÕaƹc8J©y‰îÀ{$ÄØ¥·7Û‚í\Žv·0gêbÀ]Ñ \êÇÎÇä‰è šòƒ@,ôD:+5–*ÛHÚf•ÌSÎv†å›¶ò4°û| ‡Î× ìÅãÛ»G‰Kš÷A¶©œDéLj0±°ñæPJ½l¡\Á²'yé™î¶Æe™Õiî…jHlÛ ©€pÓJ€¬‚3\Ê_r=zã_àÒ^„« rSÌ’m˜ÿϨ:Z͆ݭWXÔ°l™âzDYÞƒl³H Ç>«NÏ…ºÐN\‰·0w‰Ý#%•V=3ŸëU|C·Oožg²ö ¡jLÜœ¡WhFÂEÝI4 øÍž°>d&%˜rÏšE‰ã¤a'q)iF©ˆÛD„ÖëŽyí¤/rœÈ%¹C…¸×ᤒä‡ód8'–Ô´Bäù˜óM Ä&d»g´L[ùŠOYBKÀ;i9&¤'ÛiŠñî„샵ôûÖ››‘rHy®°ñĘD?“åKÇIm&òËjà9ð¸lµ^°‹ÖE:böZйÚAš“5ï—{&öÉFÂh6T²/!Tuq2Ãá3­CÔÀ邺_\—Ö$+.ïS$ÝךK°V˜ž™}ˆÅ¬˜RŽ •‘Æd]¶2pqÇ<õд=ªYλÿX,fU¸x¿\Ó\;wHZ‰H%´Ù|—Œç‚ߎÆHUº L@Y$VT— cÊ1o9œàcêÙº·H÷45õ‘S¤jôwè!txó0½RÇ3<Þj´kZÍ+ˆ³äàlÍØ÷FÀ HŒ‡‹=þ‚±·ÇþÛ¹CØLŒX©3@­ÛÐÈ^ûrEÍr=&¯=”«„¼üÉ•Q‘<1®xQ;…gì%w7%5Œ²: 3ëRÞÝÈH”Ä¥à ?­7*‹ÕžtO1Ðï.åä%nƒ@'ó1Kçšb̸¬Èïlm¬|ÌPLBº;h¢BT|œü„¢,·:⮎á h§y”‰ŽüRSÿ8»8»®l@€ËO • ÚL¿_“$§„ïá]#XNÑ õb&$ÃÃ2u*— +Ôšè‰Æá Ù…ß¹ªYõ7d­õ·Ä9KB#œY¶•¾äLlO•éÿŽëEÞ§ÔÚÞí1ƒh¸TÍIµ\<¼õ{Ò¨Yc*Ó‘ÚòRÅ@t2›H(ÊQlmàvƒ Ðɧ: Yw ª¬Âë!4"Å]•Sû cÜ…YAýݹٜñôU£˜D„b8-Çã26‹í‘»K‚¶ê2[ávr™Ç'Ñ(9â ö+aÀcPSŽË&RÒŠ±¼5 œþ 4JNL6×ËÈHÖ Õ¦ð” ë-ŠÊYôáèùÌ´ g0µpj9ÉÖYȤ(Æ·3Ä4D±‹hEâ‘ÉÓÒ¯t „Å“ÇS¿ï§ jóø©zeZêTÐ~´ŸYyèÕ2§uá­ ©È‚TÈ·|ƒ¹’øÂHܵ®þ·õ1D$ÅOØUèIðµ µ*àvºËy'6=Œ¤­.ùùõëTj]àÒŸ®\ÆýòþPl¬ Í:»L:$ë´,;¯a ûn|Cp†¿ç‘”£¸kãAÁ5‡¨įÈ0ß¾…ñ­ Ù\nkRO2•Aª¼L$öÜ‚õŽ5G{û$9?§rw$iƒA·µDÅ¡ªDlcFÎÛ©Ó‡Yïÿqé˜ÓÑÚ¹TÄ=°U¼/Bµ¬áw®îˆ–9‘=DaŒìZ'–dÃÈÈE€9ú"H¿í·m^1x´>4„yõ<â½ÜÈÛOŠºÕrÀ]Û&ñki‚B?^ÄIû‘ù:t°¦ JYõ&ZéW,²1?s"ì–õÀ›¸w— ¸8[r ªÞJ½HÅ(Jëâü‡—ÓÁ“w¢«T+p= SR•‡þhÐŽÚ ù 4¢ƒ/ö`ÓטG7%Š–ÛX‘ù Õ8FàûŸ(…Š9€5ïo¿Ø;S’0€³Æx(µCåõy]*6ÕP)æqü…2ó”ë4:ÆûojçO€Õ#rYÐ %’‹Ûae7+õÕÞŽPŸÝszGþo§ С ña`]øK"ÑG>Ó±P¢>G¶÷áÕ9 FÂA®¼ë›0†)Æ0ÞÜ1Q¥Ò¶“«ÓOL;pPµ”ÀCÕØ2DD "ëIi‹F-¾çG¬_†1Œ<¦«ÕÆ4„ŸU]¡Å2Kã’à4vÜhä,ÌØèu( ,PO[DÉÊ ¢Jm¨I2ý<+¼ÁE †»ÐÎÝõ ³d2Qú•38WÀÅææê9Yµný»wOU¼È*—£H³ó O‚Íg³€äé³Ë“$©k8¤Ô0”Ãj»e4îTè‚qEÂa>„qG›6aG¡Sßj iš3n·Sé‚{èßí‹8­—«o7à´ƒð¹bº  Ìò€ìA»ì!GÍ®·"¦Ðú°~ØþÂÃpýN3„ê~#„š‡ZöÂ*¡F×ðc0ܶ¹8DŠÐÈßëÍY1ËÞ½­G‚Oˆäú4ûà u„oóåž]áÛ÷üÎû¦ÔØ,yÉœ~Gfl­öÕš}á‹®û¼ø0H€ñé—SÉÔýåò“c=_"¦6J å%O.޽,.ÀÆÉ‡XŒ“Ä©Z? Þ2ç»|Q¯áxeÉâ…DˆÁHUîÿø8_\ÿÍÅ´ý†žÛIY$3LËjÎÊ­dí>ãì,1Y%gŽ’J}®hex‡èø³+ÈÇàbèF6WîC3ÖY⊣Tq‰½YhÖš¡¥)c.êƒâôD±ˆçt9…ÑzƒÞ«(S?³ƒÙ9"€P8£Åü‘ Vk˜óV8ÐnÎÄÂQqT‘QÍ…ž^¬Ø7ùdIâÛ}ÿ3nøoyþ”*æîr©.…¦æˆx$%²—ÀýáÔ.·dº& !šfSø`ÀE€Áb%ΘŒs÷ =É[&àiäÃA–Ÿ&‹Q%'i{“îá T ·ãöX×~jSuw2ì&îØ$¤zLÕ =t9⸽]Ÿë4hÌ¡uu‘½EÑÃzú/· áC± 7‚»ÅàuÕÍXš\oP“–w-=O€ZG$>ÌXãF»ìÉM²BíäÄ© ¸Cšƒ c‹—Âpeˆ¥U£Ž š=…-ýjZH!‡ïw7_$d­æBØÅÚ›}©/dÈ@SûçäËêoÜg?ì¥@>,UpŠBè£øöÞzK,Ò]hI26ˆ B4Íõb=ÂQß[žoú ¶êÁÒÈôr‘ñå3žøÚ'>zHL…âšaD¯¸>{K¢N’ýHöaKr¤ó‘2AwWX5H†ÄÖÓGB+WJL SáVj¯¤½ÓÕYÑê^e¦®öX…Ô)aƒ>¦_²1É0ŽN!äjœæ2¼zÓ̯ï0AVûp¨LËß©âr4ùNc÷\gÜdâôïž•€.66ø:òây·ä¥–‚Zõ|ŒŠŠKma(º2©Ye(Ä>¦Jaz² RUXL«ì%¤ä³áñD©âAωıé-0}) @n âÁòbë•\³ÝçezhNývzÞJ‹éÈ–õƒž$¡öCS ÙýMÄEÀásØ+ù çÏ‹§t‚·^§…ßžýL‰£Ñˆd‹A芉\^èÅ1lϤJjœGO˜ÛífQv¨Z‡Ñ„Å@²F\Ø1yüU R ] ôrA’zíŸ uá=‰*~áVéì'>ȜԪƽ!H°ÅÉÇâÊÍî?`U=³µ‘b–•±´ÖC¸°ÛÑ9oöø¹<ƒF.—D4„µþ,…­À¼mF·ÍûöøÒ`]¸LǨusa;‰öƒ¼&í¿qºXÈn9½Å+Zn¹V¹®O7ò_îúMQ‡=ó噆¼óZðí÷[´Ý,ŸÞuª ÕzÙÔeQqµG±^:K·|ßõí°ù5H$iÝýý±B©[Ö}ýßЂÙt.ÆÌ°ÔPhðT[ç´eèŒ1ëeŸ ¡«%PÚ¸'Þý8ßqÚLuœvd9:D‘¸„PJuï4þ‡=üS4-×,üT ²ûCnä ÝþŸÄ¾ò— »Ôš7)¿QÓ-—Íq{0‘ VaÅEùŒP1JRü6¬Œ>Ý5¢lã87¿Ý5#x›xìÁøŽvB‡¢“BµJw«m§%:/h 5' ¡çpêÒÄR¹Æƒ,å §1Æ<¼û)fÀ0øj\Y3ò¤|GŽºdµ<’Kï†nvbŠ<íÌA‘¤¹,‘"ë°štl:ßrv$†/ !ß F¾’“Ž?3+õÜ‘ñø ‡gïö68@·BqJ·ÛÏõ¡ö ¢#¤aM€ÿðÁÞ}´5¤¬Éë⨰ÆË]º¨³>CZûÛ=kØtŸ0t­óýž…t÷ªKÙõ¶íÛT)yÞö~º§ë}½c„ÝNqiOôÝîoÿ1:öÐÊ·÷£¡}òÇ]ùÉκZ/Ýaå^ û;CplÆÓ,vÙRHDHÞEÝÊ—°ÔŒtê׉߳´+%ÎM7J¥7î2]2éö8ÔÈ´ 'S.×/URÍá\QÕ»ù»š(ÌY²þ¶{¦ý>#΄úaË~M?pJ‘u2ø²•BAþåDã¸ÄFʚˈçßzDØd™6ªP»Êõ?£­$t.Ä4r:¶¯ô¥Åô°>‹©ôë’ì¶à*aÃì‘B¾©bsBƒ% Nzõük€Šh¹¸)=¹Ó݉ÙwÖñ»[Ø<ö<»2H —LHEå.H \éT²Ä;ùÖ Ó,ß fD::ôûC~£>F_à‹.µ#ˆÁxS6£¶ æŽü®kr BôõÈ&e–Î)ï½£b ÓK¨Z¿m ¹óüÒ¨ÐüïöKØîí_>è˜[^~‰ÞÑ/ò^Ê«ÝÞu6h¯©ÑeqEW¨æ7>q‡€ßRÙÅc48ˆÔ'hN´Úر­nC㾬éèo?üø£=úñèÇ^JL»\óô$ªvÇ;K 0iluTË_ƒ#ßÃzfê’vDKãtãæ}0,¬” —ìaJû¬}=4‹*UÅjZÌYÚ* áœj4¼“Ƭ1²á¢Ÿ€BÞ)Èy0û– Éú~÷fÏÅ]VzbÊÉÎnï[´ ÷eúœñ½Ö;Lø¡1K=rÉÊãp†eâdæóÅ“&-l»¿’®"oÞ_IÞfEá¼ ç´[`q²(€¼x‡x1tu`I}ºÎM"ã(8€MßZ´¤“c ²!¡:>?{vc¤±»š)°ï5èP˜½ØzÔa ¶Ç ÌUí¶Ó«ÿ7&a4á´eMÍØQ˜–•¸c; Åßh%Q‰µ/µùy°yì¿Ùcž÷Ðܶ¿…Þ»L^»>!rìWfÓ0 tíMoÛ‰Åtýnö¨¹ŸPÛºUq'Q|÷Í‘KÄLÖÙB èȽbzsÒ¼MŠèâ•4äK$ÔXÙS5®¸È«O5ØÕ½6ÚAü!Å„…_±?vQg­ ‚/ÇI«øebñ Ëè5™x“©Õ²tŒ¤­”é4Sš~﮳8D2•¬áªæÊoßÀçxJé©xOEœÅÉÊ2J‰t$µ”<Ô,§²4U±ÖÈk”RŸÌ·âjR㤕MŽ™ÞrKn:“8G[^Péð¤à`pƒìÄÅè®+Sz]k&…†ìsÆø ¿¡Œ ¹mõRGÈã¹ám Þ¥²Pp“Ö% ‡\¡™N‹b¡¢à¢Mëóðê8ÎX-zL¸*‚+Çà½\Qs—ñŽœ[rª¥|+Ôhà$ )R€™Â¸/µogŸJ€¬õ긎ýëc}TwoH…Vkv–‹ç;Žèëp°ŽÚL;H˜–|4r,Ë-[#Û;êó‹šÁ‰[Š4^uŠãh&j bbÙ\]XeÛ‡µ9|±ß÷#©Ônae¡ú ô†ú¿4Ð÷QùQ§”‘îÐÔWÊ K¹Sc‰ß~¿óíWÛÕÆ©D>ø}‡ÞPNwtÕÖ^ýø·¿½²¯~øÔˆ¦ö碨ñö‚ʆ"* /ßÚ#Õ%X•k_ÖQÏ”§IþÚkÖòW$´/e’Ò%š5]d’‰·`ª*2MVÉ4«©TP/Uúlg9ÇÙv C÷(áŒcaüÕ&üÄÉü:]˜"’9ÖlÜäw«ã›_úÐ¥jtEQàÈ6Bê7¸VAS¨ Šxê²à d|~ï™ ˜G{'RGž%À„nAI¥!#àX–Ž9Pê‡TÕÆ´¢wrAg·h5¼* éˆúiHÒdÄÚ>q{÷OŠà­* |¤dHZ"©sÔ­#ú_›£ckî“‚`T¸Ým-%l{VB0ÊÆn™mWnB8;hÏTд€5’½À˜,pÒÔþëæÜÝçÞ)/öNw¥ó[|xÞöôC¹™?qŠæ :äö@8Õ¨uÍe·†`·×Oêþ‚ïÔ¶c–=¸¿ú»ùb]=vC‰ÎT[;ðgu Žôב®Ò¢ûMҌܭ¬Þ0­Œ›H‰_˸’Ë=GEûÁí“:A¨MKéž»ªqew›«9}A’ù:Ý{8J'îÔJÿ%H¥Oi× 3é+:ÙŸ£oQÃ)ÖUR‹2|\-#ªÔC}P,kI)»ón|óLq¦¦„J ÅÅ.x±Á—áZ£/¿m©çÉÿÑ•~5<ñM äâDF (<…¢°Œ6TMÇx«gpûÎB l.µ†WBrâ<éá*µÓ›+X L‚WK¢ƒŽx‹åaW7 õ2>gdÃÓKðæTnÌh×q¸ öÄ;¢qއ1€µû (Z$T2|“)޵6¤ÇЮoÖ¹œìf»u-¤Xƒk_‡ f.üÖë$ê‘ö¢–D£T½¹ýþnwÃWÚð•Ý×ôH›Ùéˆ$Qk›ìk?i´·“× 0™û9ïlèý8~éköõ=M¶5¡3iwk•3á·g÷˜_57Âïíî*nÄ´E¤æR«ItÌø7ïÁ_íwñ®à“ÝxZeÿ™F*(>Øå»ÂÏöÝ©NjøUäæÉÀ­âõ¦Ž4ê©pK2æš^ñz¡’»xÁÖõ‹°€7”5‘ù@¤€ ¶ûON-ÂêÛX¯“B0X#òÇš†º8†ê¢ J4¡¸zM(H󦘾./"€¼ç«3ýÜ©%¡Yv‹!¦QÿMi ŽnðƒNM'–$WE”íÿš}…øÞøÓ˜ë"Ý:œ ï¶x!T!iv2iO‚‚cIøŸ1ÿ¯›þ–Ù·€N:b\eŽì]»%+&iè„Yûez×WWºÇί‘è‡"Ѥ¡Vä"ˆqÏòt’J¥±¦@-h+|*^Tšé$?úoÅ4MÞ›U–¾‰’@Fo²4xóþa8úŸgI‘„ê ìÏV:T~®¾jßóþÃû¨#uVYK\Ãà3q9¼½|]Üâõ5?nÞáàú<úœª—3qwqù|zXž‰÷wq9º¸»Üy^ Ó`ÉTD:ËEÉ,óúõÏ»Ÿ+ñdGû4ð©R%sÏDªÐ²<]ù*U=!Syæ-¤Žá1LàW’Ê™òÅÇ&K•Âã$΄LLS lLV¹Xe!zOÙ*©ts|.Bª ͱ^¢„Ä2Ñqìy"˜ ó{"IE¶Œt ú:öT¤*Î3‘L e„ æHŒŒ²„žNujÙ!Ö:Ÿ‹Å*Êõ2RÈÊûá¥èÄ*ËÁHå]€ŸzžŒC¼Lõ‹Ì•X¨|ž„™è0 £Áýíಠ« üA+üädž=㱡þZÈôù~¶Àiî'bLª„ê&Ž‚HtˆùgfzWø™Ê'Sq¯à¤ö3î$“G}„“Š£¥Ô-œÕ­¯®â×nŸÖÉ`ˆ8²XÍ€U%œH.&¡g •e æ!"Æùb)ÙLd*ššáL>DRÌ$ó‡‰UÁ%K”è  [=U‹áAcÃ(ƒ7ÓGX‹ñc}4o¢ðÑ:¢$SMkíZ¬jÀ!ëO"Q–7‰~¬§~>¾úb88±²8:D‹Ñ£:,*v);¹ûøØ0xHdH“Ž­³Y£ŽŽÇÑrÕH¼cE@½©3´eŠÝ4‰¶LÁÄaÏ´bæA²\ª €YPÝFÞÙÓCÈ.!‚JUù*3¾ª–™ÛZ×° Jåk±XBÏâΊF޶ŸVÉ4o¥f É«œßÁ˜ aÜ]èµÑi,Gݯׄ ÿÛ¥‡Öß¶ñ'BþÀpðnýfL‘Óƒé{pg©é˜Ý‹G_ì…×( ‘ïLo°K-3Õb™oÞ úµƒŠŠÉnÞV_Z ’U¼_D‚†Ñ"xr¶‰ÇnF:òv˜À]ÌW_—Iº£…\Š#pŽã\盿1½8±¦ÍŽÖ»´e¯1«uMGbU'=ߣæôŽŽ˜µígL´ÊæõiL8ø?­3j1Q)…~¿Û¯NvB…‰ye¦’ÿÞBâ5Kp„Õ^rwÛŽ}§ÇÞýÚãgï¹Üv¤6Ÿ§§¯?•Çc°~Š…uTÄI­qÄÑ6 –âY!„z3 ÃŽ&àtšYE„Ð2]EèŸVf[lË™…g ÔpdÌÜ6±!†ƒâiGwÌQ³ÊL4å™X˜£GŒ?_d´R‚'øWˆ!¶gÈ« &â Te•š@Ö3ç9݆—¤†6È-Ö‡h„c0íñ‹Js Îa|™ p#w›ÉEc zGpÕ^¬âÈñ\(¸p{ïß0Úh²*|iÆB=À%ìı•‘q/Óí(;ƒëþM—qԱεŒô¿S¯àä’™Ÿ'ÕEA¡EXÐFˆ®¾×9é²|“I„!ë¹p¦\²8k±Nuž[1/D†Sƹ/(µà-Ód"'цs ÅkD ,M$uÜàœ[& ¡,¸žWÀ¯ˆØÚA,d¨„|‘:‚•”¥9]Åý\/€ ÇžáwÁ^˜¨ã,W2DL¦+,cˆ•W¿ H¢žÁ鉑:î!ƱR!&C$²:)¬¬LÌUðìMV4NÕ1Ô˜òÅu’£êêì\€ˆ®2Ô†A×3A?S,ÁSÓ`³7ÌPA@'Ë\¬e†ÒÚ¬W¸Wêjð7“ÐSKý8[@)n“¬D cêìâÄÈ fºpL¤aëàï´šëšIªg:–‘‡¨®u*øïDåÉDúžgs{>åëàÍ”t-Ÿ§JY&Ь@…@C&:&ãÔ7Ÿ×=ïrts7àýñ~ä¾Þúâ"3êëÌCåAÄ Ò…¼"VãÖ3âÎÞ”£‰€ q!“Sä; =×!8dÄ-#|‹»Ô<]>·æÚ:kÖ¶!@ƒS™vY”h8<¿†Í(Žî£ˆ)(Æ2SÚOçx~£®rzV P·瞬(ÛcˆF“AàJ‚¨AKe¨g Ì â6ƒmÉYD噽j•Ý'M½¸¿¹^ŒÎÎÎí4©á!š¼%ÀršDQ²Æmfq?ƒ‰ÌŠó"þ86y¬U^¤kLSlïfÊ’t:ÿïbô00`s“ÇÁô܇iš´€aÒÍÒ&cIçк¶œìçEHlVLÕ"yQM8c ü»–Ã3¥3tÔìa „¦ç68m@´â<ɘÄÓ¢w0ó'2xþ^Þ›hñÜÄ‹Û|IÁÐ +àΠ¢sÚE•Å ¯©ñŠüdD2Yö#õ¢"Q¤ÐÍNßFÉ„€“õõ]nXè÷·Àƒs…6«qÌ[ägÞ6Á£ÃΙƩ‚œ8ÜndÏi> Œ6°Çé† b8-‘ÂH Xi9Þ†o2×$5‹ sÖ”ž(¸2Øâm´m‡^iôäQ0†4Ð$ËM3­ Œs…"e‚¹›ÛÃë‹Û?Ähxw_l0kÁ‹ÏFÐ…[UÒ3\¬l ™ àXÉ.E°<0×S©iÞ=`Ÿ¡ö3„-¥x¯¦³ÀÉ`óm(ð8›'«¼Xp(ÎçÛáõýïÃ÷¿Ž†WÃ{ïE¦ÚúK8!³$¦ÏÄ[­áÎÜ8_ë0ŸGzB:ù™ßò¿|>—áʉتŽT†®;\óaæLÇÉ3q ;ßùË÷ýÇ]ë±51l‡‰‘Z“jü\°ÚP²‰G²[%FŠïüc‹œ¶u'µu'âþ% ³€ü¸SY\ù›5v#oÌw)g¼G_Í”)øjV“éŸÇþp6^Õp^¡“û>|Ë«„û>ì[`Õß{õÔfOÄ©øAü(~zìšbŸ¼ÊòÓÄîû@§qƒÑú«moex@Õù5¸½½¹=[/É)¡ÄK–' õ›ðQsV€';÷nZæÄ •§oß¾ýYü×/¿üôöÑsš@ÄÇ$Éa98³Ý†ÎI—c,Ó%N‡ÍOp»Ãû‡Ëß÷ºòiîĹÄ=s’FÃ! n „‡IZªbtDÀý x•#ßµJ•uR8&÷\ðpHƒK 'v½ª^K”$χä˜R8+Ra;k*}4ÜZó¿ôMWÓySo¬ “úÀwŒw6×0?y9sZL3°vºṦs6ØF´¸H—‰ ª ‚žÇ!5çÅ©›m¡Ì„ñ³T.Ô±#³çÌ¿&kpëSÊïeì[vïa&­êé¸çÑÆHDò‰¥Â,Eå “4+4ƒ2~ˆ„éþážÙRZFâYsˆ}Wc‡yçïº=“s[(¿r’À²ð–´DòDLa=A2Ê4ñ½áæó4YÍÙÃÛ»{Û*Ä4×—R:ÊŽ{ÿpOÃ<3Ì9ÔY9e|Ê &#_t²ÊLNÒZ2Ó艮åó™2˜k`0¿·ÄN#õUOt¤ó eÐ@žs@$â|-ã]V0¡/ZÿØ(Ø6’ûØ\ô»â,NE,NLºS/£Q‘CÅœ°WôS)L¥˜ØßÚ¿h²¢ŒÞ …Zâ‹qMõŽ'~çceµc|†™Û²ÃFOÉ´á´¥0tÓø`ÀÒ$ÝW1ct—˜=œ(£*{´…‹"E¼Àf¦ÞŽf(BIO©PÀ17?kÁ…ékíºrJz4î°)Û%ÊJÎ75Hmuã4¶àÔúnÜ‚çî^‘1³ [= §Ì9Äì.OØm®TËPv8Ü)sHÝÔYdÓ­Õ"•~SëÄÙÕP[§2ÏíiYyVR]}» N[exµw€æµq¾Jä–ˆ¹?ç`¡ÕêÆ méÅ·©Û¦U§aŸ@äY«å·kÛÆ©¸sÜõu¦Í´2¡Ò'ÓZy‡1{4„»8wjì‘ôk*ý¶fþÎfò¶èm®åïF`o~÷tÊù˜4jÖ§¶­Y—·KýdÚ®ŽFo[¤átS=›¿ßÍ>„£fÕã·ÓÙŠuàþf}¥‰f7N%¾<¿UØRoª¡ÈN Ý) ÿ‘¬84€ƒ_ì¹d² 4zÛÔnÓÍNÙõÜûÿ}{CN¢–\³E' —Ü+6º›¶É¿vLÕÉ ÕTb¥Ü¸üen¹K•8P ô}ã}{XeQºô=“_÷†×Ã{ZR¸ØAùQrH#3,ˆ~¬õ+…cv¨HæÔÜÃ2°íݧ‚1˜9§ž&§Ì&‡·=¿ \VsP¿½dVEžtCE­—ýÆÒÙ÷.ûŠZ#ÖßRFkƹ¹Êõ]¥´C™ChÒ–ÝAêáõµzÄoklßY_kBëO¬±µƒ?¨ÎV'»¡Öæ3ŒýUµÙUä°ÊÚnU{mu­‰AÆ]:¨„VçPa,©zÖ¤Nõ¬ôxŽmF¯(œµÀïP®‹sÉ”z)š1€9<¶ l†4Çe©.Háo ìW{ýßilýpC'ýÔ9 ¶ˆr‰Ö³sXBígsŽŠU؃ÏĤê(™%5˜Ë©lêbUé 5M9#¤Pê`œËåRÅØÆF.6öÒ\6™ëyáÉ'GÝ96±ßÏ–2ŽéÊ«m,%{úV,ç›L#‡¨1µl„ƒc9ezHP4—/:I©«1LÈÐ`ïÞ3>ØÃHx¡Îpì€ ì)aÂtìnn>ßa›f\ ê¹uï—<‰XbW£˜/ΘxßûµuÒ0‹±¸GëSLHHØÎQ:ËœèÅ›pïŽ&ý’…I™ ‚]ÜÝûâ†=)î&ÆD;waÎÁΩÔc·Ë†åÏÎí•i<Ö¨êçe˜06°EV:¢nhC¶¬X2»Î`9§ßwË[Nñ,\¥(Ö¢ñ/„NÛ"§èE'D´Áyec3ˆ¥Ñ%…¨ËI2ö*Bý>€L«-%ôa’SýÁõ~èŠ[ÅÎaôùá¾8òI0Ó©´Šƒé¢1U¢Š¯íé©ã€ñ·¿RCMA$÷W9¸Õ%ÒfãHP½*¢’GxcC(R_øMªž©6·p÷Íújµ¯R¬×û¾¬x|µŸ¹8Oo[óôÕÁ-·˜!°ÛÉõ…<ô…|q5R~‹E8âœlœNÑÚ L8ø±TdRs,öâÞ¢òÍHÅ ­Üc¼å3vRAä¯-`vAFÍ*V^å÷)‚²Ù3µBczªß§>wK¸ýîFLh'Öü`+ôÀ{qÊ•½zA<ÔùÊØ‰‘ž¤¨Êæõ1oݧPñÇî;„Œ³5–:žGW ÌA~tõõye Ò@ô‚d± và¬"6îG§Á,ŠMȧᬉè@YM¸j(˜‚Ï`ú5S@V£Ù| NŽ;×]ØÌj™ÙMNs<,‚‘ª4Å]Å»(ØPœó:ÞvÛ=0â)8=Fu¤MÅ ÂÓCX-ÔxýArA8Âc—õ‰J—ö=õÌep¨Ä3³M3p AÉhXʅƾ€~ÎÙ)Ê™œo|B)_'oG0'ȸDÌ¢$YÀ_ðIÄo|qy²-€zÙ£ï*6¨L%%¾æ°ïÅåévÑ»8²ð ¶Åç:ÐÑͧ>«ÁíðŠQØÆÀ…ú(Yó˜I’ç`ÈÌI.„‹¶rD óu“•ñ Ì‹Ïtp$š`Þ¥úÌÒd ›k÷xö{ÿýöíÛ"yà‹ßQ/ɇáñ󬚅/+À›Wwª´Ž¹ÚJ°†*jøÖ‡m7å¯ýš‡Ãª˜*&ªîä2M{jVH:hLãW²ï˜ lÍߛժ‡úÍÅñ¸†Šr(&;5®RÂ^Ú˜µÄ&¡ªW8ËÊ…™Ã…Ê–¬?ëC=Ó?fžá?N¹S”…-ÃOú³ŒGEKUä5—öšª LJs‘¡zœb6ZÓ˜„äT–lÈyjg›VS#4³Þæ\:8ãÛK—ËHéžO#aÅOé2Ô¨C“䯢š/Æ©Âfµ^™íaKÔœáù²ÛqÄ×–Êù²£%¹A<¨dZ¶è¨GúרAÑÂ,w³ ®“ÝÃl«pЄi¦ÿUM რ¡/M@œÌÌ s¾›[k¿à¾bߣFyóˆÉÞôVF|ƒlNNlzþjýÎÎÏ/M‘'¿œžþ,Núé]‘‡oú}Û7b¯r®#·5ïÈá´¼õzœ¢À2Åkú¥âíšÛ–yâ¡Õ°º ¼µ‡95‹íh×Z®]î‚înïGƒ»¢rxõy4¸\cö溈ŽÜ`ÈÄG7ïÿ1¸¼7·C=ø >ßÞ|º½¸º^‚¨h•æ`¼ÿáŸ(´,Yb¶wµa%˜¶‹k³³ª¬yBÏ(Õj áF¨² Õ®Ië8©`äÜ´_ æ=¹v "±@(æìÊS:ð ¢Jß`9¨L‹v; = îÎÎàáåÍÕçá3“ðé.~o)d_TÈ¢&"Iõ¡çݾHÑ•9_k½°0–¦_qM“ÈI"qÌoè”Ù€@¿2ßTØï/’ BDÓ²…o•cVÛ k%â­âŒ³,9%O4ßå}®iÄ^@0—±Î¾{Å?1éºÄ)˜+rø¸S(Í×åAEÖ1݉Ç5¥çV͌ያ$+Ò]i뚘œnv|‰UÊuì!4Ê&T­ås–¾ƒRä>Z!ˆ¼^ƒ3~ÀÉ—äY…ží8¸£lŠZ/Á\˜H/™a"Âa•Ñaîçz|NSNP“Õ (œ¥#ÝdÈ*Ÿp‚‹±¾RâÍCDLW/L‹–ÚÆ8?([_ql67nÁIyxÒ³hbèi²•¶¸j&ØÍ™P¼i=¾žGœ°æ|09Ìr¹‰€г $»TΗ§ñv² u ÞQh¾í`m»†‹†lÌ~NMÇ<2ÈÆ€U¡ËD{ƒ± ¨m¢r°Û¬:ms޶åž·MgÎ6Ñ(Ùœ¾Ï’pú`ž#½Üo’{ÈÝÝF%G n)ÒD>®gm;…éåþÂ;ذ{¹„(¦ šœ½ÒpÚTÆ3Ò¤¢á¤UíjàÄÆïáÛ´¡!Áb…@l¨idnUCËTÙ¶Æ€¤Sª[ÐŽÉ¥")qN8Ób¾\ƒ·É³“ ^ÑÇUÚù=ncŽä»‹M¯¦»û}á–2íìÄ Æ%¢dj2| lÊžƒª'~Ñj%¦ÄÅ©*´ ÉÙbh\\³‡É…›6 Jó h»}+ĆÀÎ×bpÄZ;¶ÒŠ’Ó^g%u…û¥¨K‹ÒX.ŠÆ‹N1¥î ö:TÏL†<'“Ì̺¾øD°Ýo?0'Šˆ{OlwŽy]»Œy³¾’i)¥$ëxxå%Rì­6î‡ÚÆ5’9jµu¸_‘‡!]få¯Ðx ›Ââç” |ItÈúˆ¬”y`ÚyL¨*Êš¼ó-* íƒ÷j„ ÀÒº¬1œ^Eä?Ê*ºÒcD ç),WnšLˆ£éåAÝ¡ÂQ·r`’“©'‰…ÆP㉉…µLÖ:p&Iúï⮵©,É~¯_QÁD©W(Úý˜YË1áÀ˜n³ÇàîÙ%A PPiª$cöÃþö½çdæ}”$ðΣ׺m¨ºuyó'‰+õ*sxŒVÿ‹+¢,&®£$óüPf1µ“_rq’&å'¦B`²BʲÆÙkÕRb0”åÂÓÂéQ>=›¹ïݱ8Ǭ­Ü8±¨Tü%ÕÛÍûR•ˆZ¹PÀ¾0H (CBÖ@A|¼~… q+æ¯}˜(OË«¥n¿lktüS=q£EDn•ëqÏ-%Å;ãdjë¸ôŸœègÎEi åd dl³fQ¿z%šNL˜OZ÷žö7Tɸ…B2à‚«…|Ç/ƒKùOæå{²ò¢žÉ·<#…4mÆ †O9;«ãKO<ÞŽådÏŽþ ¢R™«¯Pc¾Æð"âæsF"MãðS[-¬T^oZæoš‘¦Rø(?…Ç3 *z±9kòÖÝÐôëæõ·°zµìˆyªF<΋Au÷ÌV0ÊìRÜËã ³‹¿œ±ad¤9ý»%… i˜äq·L>ä-6Àª±F#°–º 1]Ù´¾ § ÖÚÿ~Àì-Qz½ÄNwÈËŠ¡hjÆH]r€NÏ,­×k†M)þ‚ES‰_ŒÞ"æÃÁYz¿ƒ&y÷)ËÏáàf÷'ÓÕ%<º)g Ÿ•ï ¾ÔHNéhöʘÿˆ(â³Öj®è·ùÿ¿¯x~) Òg¤6¤/Ùìñ/Ô?Ïyy:ù”&ÿò¯u6K„ûúúÅ÷L"à¥iÅ Ò×vÕ*ß1KÑü’3ÊNDKNŽ%„l©|^ÅÚ*‰ÃØÆÉä¡ .•3²m±” .Äá»% R–¨×téÂÛÀ`ÕØZÍÈëŽRægÞ[ˆä´FìgM!º‰mø¼hÂÁöOÏÃð¢Nëî'Æ,²¯›r¦¬È7 ã^­Ëx tÝÂŽ@×O©íemÜ J š T-èçǽ+®«¹ZŒ—åÜI(írÔ7…#µ ¸kÄðDZbñ14¹ v[¸ó¹*³µ x•ô1.ñâ >‘kÏy^ñ¢3ì&v‘#Wõ‹'ùÆ‹æ]~ñ5¼ã_òE§É³…®=ö­…1ù±'Ê^mBòdžïÐ:}ÔšÛÝhJÑ,žäb:µ{ªW©‰Šý·’2ç¹êzfBÐëà.ñ÷ÖÓ^%ø|_›=uÆÔì»;÷¦¥™W;ø4¢ãkÊnoÏx®i«Ô˜ª¥èi÷M¼QB r8ÏÀÞN'Oëp‡à{òSt†~»˜Q² ~,ò ËÃø¸ú§±ç0;ü°z8G,S|ò S©óÛ¹3è43qÃD–MÑÞh&™¥¦‘ÏŠ.!'ì;#•9`û’‡Ò° yþåãáá»Óø#Ÿ­öX“­žå ÎèM¾å*k ^‘–€b¤(*„š¹ÓñßS=2ß ÇF ¹ZZÒŠQh—³2MqÆÒ$ˆ7¶^9CaòE.Ó²X!ˆÄ~»Â]!Þ+PÇ£  ⯎²ØmÌ,”JôCRB…½,’E‘¢’øBcì:ú²©¡ÞKµÜ'¥N™«"Š_ íKœ ª€öDôFÀOm àrpøúã†ØàË[»Ý‚NÊ­ ŠCEüzŽ€Ì¾A±K©ÝQÍ-O-Š(g;³âËN²'¹¯#äÊ>h¦Zv¡9$þpÁ–ý¿v ¸ò‚YA»J¢âOPk1›—ȉtâ×K¤û·µ(æˆITC`'c=cù%_T¥8Ì%”£DĘ’¸ÏwfβK€~fîm1—Ä\×[¢’dµÑáØ–ƒµívgH]qZ–gÁ¤Žõ°¥þ<#ê†c¼¬ TPQ«4JdìKîs{áM"f#[ªØ˜zÐS¡µQó¤ ËÎ83ˆNU¥0˜$ÄIìÓ‹ ¤]¯ÆA6"Ÿ*cd»jœýÔª^ò4›^é,ÛW—B€î-Z^Z·öð årϪ 3$¡náúºÞu÷eúà$Œq‰¾9‡¤ˆKr]ŒOÓÜ>,¬™ž¾Dt|O>ñ{y£)kF6yÎ.d nàæaÀ2Í’Y qjj0h‰È‘ýÛ´°dó³ÆÌúö«¬Y(€>il”Ri”¹·ñ7‡™F°,x¢Ô&u\]jÑ«$æŒ4ñÁýÕÈO*øî$kÙfýò Õh±Ý÷ïïÍm)‘ßþšPûÖפ4?]À§ ƒ¢1¿jýñŸ'÷"- t;ýC¼‰á:Ÿ'™¬þ¾oÙ[à4ñé9=öl1ÀQ‹#¾Õüo£žr"šáº(ëY{BÁÉœb&yrú¯°•2éµw¯i÷p×y*ð¼;Hò…ï¤Û"Œ±O(ïñÚ÷vFúIü͸L¸ L:Õ.w2Ò=ÖÂG&+éŸzÊŸÀ)wèÔNp#uŸ»×Ɉ˜I² ž¹s´V²Dý˜É :’F.ÔXµ7zjêC»ÊoËA?×Í—Mv”³2WKçë&Qú)OµÙ;>Ú{X»xç‰oBöÁ³Úη7_Úüœ³ïÐȸƒÙ“h‹V^Wseþ“«î.åcÛÅAwÃp]¹9{Rp£ô<+öƒào¶-Ží6Np:¢X Nl„âþÙ>óüwýL¥à¢Ôa…Êì ÝYº×hqoióÏ¡é è1i/n‘ƺ#1Aho/v©ø8AÞëõ6Š_Q‘·qb_»3*6n¦ä®Wu£Ø°i_ÇŠŸbškLøþo¨Ì)–¨æ9Þûêõ~4U•ªm¬Xçhªvy€½º]T¥o(ûׯŸ[ÚØõN j²ëÛJãS¨°¼¬æ‚D«q?êòÃΟE¾»íó`uÒ®6Ë`¼Ò©ãÀÛü0ïzT/(Ç>ùBÍ$ÓmbÉfG£ª«è81Նȓ<š(·Ž©ÒÒž{)ª¨ _l‡o ïÜq;äËw®yçÃåî'™šñiëtTƒ>O‚PæÖ5ó`g²º¼-—†JЕ~x®;;p?÷†øºótÙ¸‡RõÞ(¬$N»lªÅB8Ïlu7—ºs€RüôéNª'í%rœ”KK$gi‡®ÆÝöô6 ‚æã}v1IÇŒÜÏ»ÖÅ©FÖÛŠùOðbÛÈ-BIÿŒ’bŽ‘ Ú”7™ÊÁÞ3-œøÕÂþpxzg‡=è,$ò;õ0^&C þNǤIoé¡jR·õÌJB,\Ž_J§„“QÌ;Œó¤|¥hÜRyò µ`î“­–iÞQMŒØ~–ÐÙ<_(Œä!¹¤ëB­{±bê«h}jž†Œ>:-s¥dŒjÍ L´šÙFLÄ6ïVH’—M`ª2‚˜™²VÃw…{N­”¬qñX‡¼øÓɇ·ûÇ£Þ»ý·‡§1Gîó0×IÈÆŽŒ:¸´4™½î†£æšE›v|>²Ê‰kQdìY:øýXÞ¿xÜæÜEµê%aÃd)-ºä…ènê@l§]¯Öœ$åüsÕÔôˆ)uý¤ê\6>«–ٳ̬{a¥s¥Ïæb…‘' ‹ªC;Þ¿h<™¹³‘W¬bôá5ácjY'°‘Ÿ$t­Öti›µáÖ„ˆáî솱hKäGǼŽ{{¬ N1”•Àcuñ½Þ÷ãdB’EƒŠ­|×BRŸ…"̯>WzCa øð³±*o×"…Õë•ôm¹±¬HÌPii–â8‰–Êè¶è$ÚõƒuµÜô`=ãý¡ò#‡'7ÕGòÖšéaÖå|íw˜‹žlª&µbYoù¥Z’ÝþÐeá¿îõP[¿‘ƒGXS¡ Ç'Ä\k~¤1¾n‹:åìÒDϰÕÌ¿lè\¸n7ãvYjN}|’òÞÇwõ$P6«’l‰øÀ}j2Gb[­B*Hü] ®)ªScÁ ‡R‹ÀWH¡N`|5§;ÙÒZTD¬ 1íwG‘è³X@.•t¼Zi[*ƒU^¦0"]ýÔÚüíáÙ›“×£^éqø×÷'ÎôGÆÊÇHÀ £¦¼.šé x×¾U^5×=Mý Ž`è“måá:Ëݵø´Îc:-ý®…ÁÜ‹“z¦ý½øZ§Ô’ž…ƒBň©Ih:ÝTÕ¿4'µ6š<Ü/ØBjvLx[Þ7ô‰¢- ‹+÷ŸjZ„q?™iš í‹Y'+(+D¿AB+ Û|-,R‡˜\÷£^h‹ÍXøŽœM1oš%Æ}Šù­Q×F ÁÖ*—T¿”=œ½}¿U¿ã”SÝ´êÞÛã%€Jg…b†ôÌdëIJI¹˜¡o¹®—^Â]Ý?Þsdûáðôôèä×cçmž*Yu¢d¥ï·ÝcŠ)ÙÚ“º è]LG´¬\—3¿By"V‰žË2ŒdÒjR˜^I¹†Þ­wex‰¬¥S,^YrµGZi“$s”5™Ž±´e¡Lå$“‚1dˆ¬ŠäM¿HýU»©’x¡>•]U@< ¸IûÊ}‰‚*hI9:²ŽµE¨Åà͂ӞÅqxâ`Èv¹ª’‘R¹¼ª¿ÇÎN‰˜Õuš›Êëè*‡>s€AݘÒ+ä4êÃ7žÜ%rY_í] f¨-&ŠùuÙÔ+€VDœð®úB‹LRA?™ ú2h½’õÈÆÖèÁN ìq JÂ7ŠSÒñ¤!’Ø¢fÓøa’á¾A=ªSHÏ —!óî©IàtБD«ý.î|YÜJÅ„:Ê/z»Nq(`Y)©‡ËšÏsü£2ÇßÊ8g4dÐÇ*Õ„6äkßJ¦Ul«;J2Á-ÃE’Æ-Æ{xBú’N=Kí1Yä´÷8K0´‘ôÐ3.X‰Ô«Ü‹Éhxû[á?ÄœŽ±D©’Þ¾¼_[I@$©þ¬æª6³»ÿS5³Ûë9äÚá=±+OX¶õG Ÿg&Ã=„L…Þ,õ ›:ø&¹zÛ¼ÀìM#hÍâwH²Z,x?Ê%*X©ÕLcæTvW<Ú`F•y‰ù(ω¸A†ðÍb m™ò——„ »&¸˜"{ùн֭ÖRŒÍ!¦ÍÃPºˆH²²Ð-Îî ÙþŒ*NH s銙ëœL;ÙhÖmprd‚yQÎ¥ÄθeѨ>£%ÇÆu¥fUýžSér3&"*Ž.Áõêm·Û_lî°]l\ó‘ági†…ãh£û¿Ä£ûXU§8=0¦” ~eòåQÄ^A.+Ìò”Y‚Œ˜Ÿ"ircúIþ¦p¶‚;´Y|ß@e~öüùŸ4ÝPvùî¡s\REéÖr5 ×ÞEn£ ݉îàôø4_´¸ÏFÔyÔ#›`cH×^_à¾ÿîô·Ã!ùðPÍC<«3püÈ1˜ìý“Ôä»7Þ¿9:ZüÓÿ|ûêäØ]td<~ &Ê\“C÷ð€âŽ;¹_Ié õ÷M©.gjdz‹Ó"(®ÞŸ̵ €Oq©P>.¸‚ÍbÈ·e·ømø “Ê[£¹}éôpiq¢Â\ѤV1èz[I8Ön.ÍAö ¨ºI© ,0œ÷ÌÓœ¦¥¹VHû2WÞ߇%¾fÔ_ÒLÜÊɦ¼È’:ÞVwÒ9ŽËnÝÚèsö‚’Iæ÷g?àÄ› f]}±R1½ùqŸË„ùŽ()žÑP‚dN˜ÍVVådãWK¯oB—Çé1Ú6Õ|ÕµXÏ&1ÒìÆÎµ ˆ™yÜ]°söö¸7¬^·(:~öÃ,0ÖüVùÚ_H:Ü}ýïùúG˨Jîhu¹RÕ£ðÅŸfÉ'L Êò~õ C˜ù¶i”«âìXdÉ:"4v'Ê7ß…Gõ¦ÑGóñ<ÏÚre÷Ív²:g>>í~Ö">ŽtÈ õ©É³ÜÓdØÏ—ú‹s¤cìØšÆÑT˜…ÎÒ²<ñ¬Rgò¨Ÿõú§÷žåÌ$—¬ƒF¡feõìf^-×#äà ãdg¾ËÏÿ£¾™ç?„5?FåÀlæîÕ‡zâþ-ê†¥Ðø‰ãÎø¾™t¶~¸Îüó3ùTw„Ç¿´iÀðn<âÿýíøAÝ7yŒ±>K“ŽýásûUF ³<å ¬ªÄµo¤ëL( ‚‰ÓGn{»¨õÒmÝ Zš0o%!Q…Ë@FùG§ß6Ë'ƒùkI ]Ú¨‰3ä3Ú§£¨‘/©¯v>õqãþÔ!€ø ’9¸àñÁÉR•£[ð}uÖ°c[~¼¥¿Ë­Ù—'‰ö£ÒV¾¶Bªá¥_Õ}™ñ8 ’ãΩù²“ÓbYx¬"•t"c”IéÂ2Qʲ©¥¸aÑàÃÞ]1EÙŽNB]•cÔÖ$%6î¡ÉXÍïê÷ÚZ•¢Úï{!Ø_âªÊ,`•ì^GFDÝ‘#,’€MšYUB@4:‹$Çä‰>(Ï’M©¼ŠˆÀ€6ÅQ©‹ðûÿ 'èK2;vÉáEÒ‡nk“ßí¶îV€âJ›J½´ˆL{+¬Iuôê*d8$Ú|‹f:ÞçÃ(Ô+¢kÓ{H¶Èd³öÂ(ÁÝÙh ®rˤqSáÂ\‡,kõò!òÂ[[]z#ºC³ þ´QþšÎ\ÍE©Ù¤‚4â(1„OòfñRäv•z-aTÕ´Ü+¯®/féžLµ-“_IÁ‘*jF`Q¶QT‚¼ŽzZH€“›!ŒÛ <ˆœ°‰«ùluyû +c$ª¢$Õ4°íê »»Y'؈3• »¯=6 J·×úi¥F …l#&´Öbw¬¾üä”õ»øbþçüYÚËÑ]uô礣{+üóæGÆëðËf0‹Ùôû}7\£øÁµíé4ôû»:[¡¤wLùßÖ3rú³;²µŽ‘T‘ c©ªT³c”"\êT•jÑZÛ½ù*;`B à8“ÊÃ( "ºÇ¨³[ua×ÊУ•3·Ù²j­ØI4¥ãȺó¶òÛ´¥ ó¨ürx¦à<U\EPsµzK^—á*â=Qóµ¼OhC§8‚%Î¥ó_O§È. KEbNB€÷Mtãbc]ԛԘŜ4 3«ò£Ä±Ÿöt%3_:>x©¹Wô‰  ¼[v1±ÙE›G¨¬ ­¤’í@«­g†w™“çêÿt[ðò+Ó,Þ ÜÓH¢½4·ÿ¶ÕÏ+§D£7ãKɨ°8§c¤Ÿ‘4[$mŒC”Kz=Zì…Ñ.\maà¢ÍᑉâÛß—tö/ä}»Š~aѹŒü™C{¾&Õ®jé»|Þ€-ÜÛ¢[Že¯Î×y%ÎÑ餔œ/‹ÝÉÿ/êdjÎ…¯ucblogo-5.5/docs/loops.info-4.gz0100644000161300001330000002163707270062710014463 0ustar bhdoe‹b:loops.info-4í]ësÛ8’ÿŽâ°¾–feMì$“Ä©«©Œ£L|ëÄ[¹ì–ËU¦$Èæ˜"’²¢­­ûÛ¯ŸHÉÌ>jw/©Ä±Eh4Ý¿~^¥•…¿YQÌ«~šO‹ž—Åd1v;ZÙYríðS{ãÊ*-rû¤ÿÈNËbf¾_Tå÷Y1N²ï«rüýO^ÃÏ—Åά˜¸ï©ÃËE:qýÚ}IûÆü‡y“fn¿1–}/ïÛׇ?_Ùƒ£ãƒ?à§îK½où8¼?…?”îfßž|ÿÚ_ýt4€Ï>Î÷íéŸÞýt|tx`Žß}ø8<|ÿ³1¯ÓË´N2{´]›ø1Ÿœ]‹lb³ôÚÙº°Ë2­MpΗe2³õURÛ*-²¤vüèì$­æY²²ÅÔ&f"½±÷¾FÏ«+î¹(®¥{àí¾1ÿ©‚ði‰ouÒ)½¡[>E†¢Ûõ=(…°é¼€ôyKÎ\’W¬ü<iz¼É`i>_ÔÈ¥I:†¥úiÒÉÌ‘¾BÝ3…©fÎïxYŸ>+=ØÔµ¥´ñ’¢d¸ j5¯JÇEQ‚F ¬[×p¯}û %Äw‚ý/@É\T®/J«mü4Ò{«*X¢ˆv‹"J匶üŒt:(k ììËTœ]áÐç ãŠ%î?\DîÉ _7™›ôI9m«^‡ñü‡vŸ8¼?k…ÚÍî3U}`Œ=Û/ XƒçÜ®ªaòc{vÆzûL4uími·¼NìË‚Ê,uÓ=—nôÏÙbΣŸÛ³)JS >A$VGiY2M»?«.…2e&t!íøîK Ø,¦Ô8tvæ·RDåY½š£Ã²mñœ·àµø…e>Š?™F þ±ÙìÒ¿ø˜õVl­³ÝFoÜ„‰ÞØêŒh~Ð-®*¯Iü†Ë@ÞðùÌå%*½-´sò&3B߇áŒ9¾>ÉÐ<¡q©Ë58HÓ2)'/IÇ«ö\7„Ü-(Ãú*2n‘¶ïÛ ”‡mÚï¹-æ¸\On’2M`+öíáÔæEm.Ó—÷Pבf¸i²ÈjîØCÞ£b² à1 ÀEé:{l˜w^šHß°@á†3ºíKWÍIMAïEžA—0yÐUr &õðýÁÉàÝàý°oß¹úª˜Xÿ èkÁ\S˜TܸÔ}v¨ëUÅʹÏùëkVUC.*äç.ì6꺤ޮÀˆ¬p:d’h4š× àv”HQŽ-ÛÎÎh1BWÓlQ]5F<Œtn¤q‰Í(mLŠÌÿ*ñI5@¨È\sä"x-r®ª½²ämö'Ó‰ðR78ŒÙEš¢ÂýZ1:ò m‹Iæ ëçÐoð´;™ôœ@gYD¡„`! 7N{…qŒÚ8V¹âx}arVl´¼6HHÖAõ#4…éŸ {òƒf»ÀõÙVU)ï›`HŒ9r¨×kÐBÞSu#sßbŸ¤%¡›ÑÙãGv÷éy—›ÏKAÜ~‹©O+1¥‚Y‰Â\ñ¿z¬":«37âþW5H‹W“ªŒ¯@ÍìŒña^tQ¤DC“ffdpѦѕAà¶Ñ¼OíªX)9K0–³²Y=ÎÎUÛ ß˜¤´: Cô>¹}èø0‹ómÎ.<±sWN š ¼`‹¨^ OӇŠ,Bkâ Ê ô{¡A’mÆßi¼bÆõἚ0µàøÚm ZitšÞžìªx÷í±ì!¢(ö“ɯÃ>|l;ðˆ„ $Dt±÷XhïŠÇÄ›²2:‚í8S¿bݽ;ôáv rlËH@äO‹Ÿ,Î6²ÞJ–Ø¢`œ¡Ñ"\€ÝØÈ…þ+‹ÕY¿U:µn2R%bø•Bê¢Û3Ñ×y±d¡EÊÐ+#H¦Ôýfzë¬ 2 ûóNÑSÙ‚±¢ºbU¤Ñ(nÝÉ´ˆT…H6­W;;ɸ†Ï²‡]*’ñ9ê는qU>À/#j—ÿÛÛä›­›µ{œ³ÝuëHí}mGqI¿&Á<¼¯Ýî:TÚìuVËdÞǸ”Zmaÿ¿œ%¯s͇|ˆÿI=òA×;/M¦pËËõ[wÒYìÆl ¿ñÏYc<\ž{[€ÖI² ³¬áGl‘Ù½½Õ&G|Cns¾oAZ0þßÀùzç'vÃEs“úðþ k¯Lpûí ÜÕÌRoÈ™%ª\õ2»Á5²IŠº“£Õ¨§HcšHcrÐJÔ##´MÔýŠ6(çøžhÇÎv¢Ñ»‹ÖnÝŽ4{U€BAëØš¹u»<ú~¯+HL]ìùí ø}¯NOm°. æl¶ˆà$ƒMvùÔëï"$Äð.¾˜aŒÀ?G6)Ê–e=×½=ўń› T]%~’L&`An+êAãS¥Ð銅-ò§ÕÃ¥¹7l*É4€ Ü%=¡oRh76pæ ŒtŠ}'ù 3Øp£á1o ˆÂô ‹ Y§‘G£HHÚÓ<ôá•F)Âë$òzððgAÙÂLÁ §ƒ÷¯ûÞ¯þ B62ÿ#IK•´L`ýaTSŠ `x ÆŒ ‘{†òš6B^ú¨@’N›”®Ò2¤`$à$ˆÕeên$$¤»N˜8r—ð*î0ê.g%ÛÜôÞPîý‰´ ËÓˆÎôÍQz f´r=Î;°ú'· â'ˆFÝø*O?c˜…ÜÄG„u«kŠÐ%“¨ l/€¦mv•`Á8[€1P5hS8ÈS:ÙÒˆ¯ L V®L%Þ‹]©*8ýt8e'¡n`@›L0_ˆþHŠË²õpG·G{ì ûø[Äç[Äç7D|ЛÇpEZ­‚~2löÿá t¿-`Ú½KÐ3˜ÕZ·ÄŒ,lèd‚úD]+e3Lò’PEÁ¦£ÇêÕ{}¨fÉs°v†€V:^dµwƒL¤µåè#1Œ!`d*_q®YL!{¸è[.%Ø·0„ºÌ ÀÜWŽAµW¦¯Œ¹H¶™MŸ¤ $wKæ8{.-@$êØ#lu¹— dõ¶š¼·i^ï[ ’ùdŠõ`ß¼ 'nž%c~—íƒXë­Þ‹tºmÌO®Fë‚ù¤Ú]RzÙ~£‰Yr¢öó±oë¨(iã´„%I`õ “I±À¼Ê ËY&0h%q’ n²Fa ‰Ž,±LEêºÚ!»)R²Æ&B‰6+.A¡C7Œ¯£¬Ï¿‰ÿ0ï;pž{¸ÇS‹ˆÚµñ{çÿ²ŽºßÂ_‘"Ž\ôµæw:çMßú*Ö}J‰ý3{´’¨]÷{Q&¹mì7šö×pEýÓ?;ÎKÂYƒ˜ÍMn¸ìc³ð‰ð-Ñøðg¼'GȈNœ£{[‚³A5’`åN«ó¿LÇŒÊs…¨Ñ »09Œ´bÁš.pÛ'Š1š^IrvéÌéÛÃ7ÃþÑàÍpY4HÉáéÖwùR0 ‘BGˆÈÇÌâY|¿ç§.nKc]°T°Z¯ÜÌ× Ïö䕯³½F»ÝMíZ}’) U’öMQÔ`Þ`…ãÒɸXQ \T8çËÈ$dKL˲d¶³×µï‹Z"ÐK^ç RÌ $vD¯lÇÅQ<¼ÃE™£—®¹&°®¸X¸Ò9V1°aäÀ¯€ðû²Á‘“.ÐeÉW@òÎN‚à=­ÈþéÃ@]D_«gt·z׿²,Ü 78yu:èÿô߃ƒaWJÁH–àóõù «Ê¤„nÈ)½(5–(mýç"¯æà©MS7¡P:åPJfô¬êÃÚ aðoxòq`Ø-$¶ú ù¤PÞð¤9™£ÓFÖ»/h{ÓÚȸÛ0s’Pœ®øƒ£Áϯ†ƒ»Ëv[ºí*ÞÛJtY8—WF%K‹B%15/æˆF²0=WŒa÷“Ë ¤ÎpáG´`+âŒøt”Œ¯¯}¢mºÈÇ\ƒÜ@¦IÆ¥]د™cÚ‡‹ÿ¤F†ö¿#É…ÁÄ>œ ^<œîïSŽª'`´r.0‚xРS F­|JHP|06qÕ¸L©fgÕ­QbÇW U£")'Sˆ‹\ J»¥ ‚-î˜Ìßã6™U.»‘ê ªÈµøÂÉï–î; H{àC‰qÕ»ž Ðö}ê{»¥çºâÜR@ïÊy¯Í`ä&ð£Í–vÒ,¿lÁ¨„Ç\²-¼ÆEH¢‹ºö„üè¬*¨*ªöåmœPYc”%PZÂ!{ ”'RÈÆ¼­á²)Ýsô)Œ2Ùè÷N·²¹È#ME5ò&àûâ¦ñª/i ;åÁˆ“;+Ée™Ñ¼ë÷1†Æ5ss“ŠÃQŸŠ™Jí;V:»‰¡}í5dZñù†p~ Í+Ç•EÉ´ pjM‘ß$–êU¤¯Ýíq8/ï”Íõûl ð[—ì#‹37¹ÔS!Ü‘Öësݽìl´º²Ú({`¤?ÓEv/èšÁ©GÝížXTq§SPKÌ~ÚݼàÄ1êµC)0`ª:náœøŒgã­Eqð:"ƒÇÀJÃ’Ç¿@…WÄZ†«¨§&!5òKˆ…–YB ò‹BŠUžlθr40“p‚îœs†z”¢}§ÌíѾ‚1²`éd,Ä–“9Lv<˜W6ÚwŒQ E¹ÎX~]Í07NÊ.Ÿj¶MÃòjbr“¶•câ%0JAøK “‰>¼;þŸW=” œH³¦h5¤®%gF‹¦ÉãoÚXŸ>ò#sºŒ…Î×[ßÔ›2ÙQJhöåaðnz5ña‰pDƒ;Àmém)^ÖÒ˜é\”¤ „¼D}U‘ï"Ÿ+¶‘P*BÅçÔŒ†ÿš‡»ÚQL+{[4LV3¨;ŸŽ–ÒÖ‹9eóÅläðˆTéDM 1cÛćØÚÌ(ÆãÅ<Å¢E©Džð‰<4mÀ±«Ô~¼æ„æ’‹#ø€ƒ,ãí:_T¬@™^:Ý‚êÌ~¡µiVBN±I—QбA¨å¤—Y¬fÄ4ʼ.W¼Öã7*ubèymXh¬QTa È0$öÍá›ãÎãnpτܡã§,´¾`_–Þa¯Šâþ¼øŒMSØ ”­¾:øÔA*ȉjœ´ õª '’×OÝDs0³ÿÙžQŒ¿Y ¹Ê2<;ÚÌÚxÍáŠùWõY9Iñ59Çn‰ø²„þ† //ôz)Së,K8Äð²ý=8>úøî}/>SdšgŠX¬}î fÐaTÒR ÷·3'®öR(Œ½ŠJk®GQôbÖ Æe#a$DpOã ‹;ÎošdXBüáEäæ=P Ÿt›Ð)B’`î]¥Å sÓyð Þܲ¸ŠyÕ0µžAÞÏyÀ”ÞJ ÛÜçiáûÊûf%ž¶Ó­ìàþì; àÌ^|!§C×ì4DÕL§ƒ£7=Ži’÷RÒ †,:&Ù(h8]Š»£6Ø=±,*´€V}&ȸç%ÄMøV#žoàÁçõˆBo)¶>o¨û¼^öÐh o}ÞP ÷ùñ=íöàß“ ížÜÓî1üÛP“öùé=ížÀ¿6´ûážvOáß³ ížÝÓîø·Á“øüüžvÏìIË¥r›]€ åT÷Ñ»R5Ñ€Än6¯W?j]®(Â`ÿóóûסqÔ;ŠÐR ÀÁòÂJÓÀ ˜Õççç(‹ç-TþÙCéû€;ÂÞÝu/<”ƒNú»Ÿ.`ûÒ!&¨#\þñýppRèR8:97ÅÜAP0tŽK¯ÁðZ¶²/ö(Gðº·*à®Å?ÇLGv½äIâÔÜÆz ñæœç‹rŽÿKñ{]Ì)ã¾\á¸ô4ŠDjˆ,É LÚÛáñ°êÌH»8¸XSdbM:´J®Þgt•–:OÓ<Ú¡44¬*À¨Aѽ *Ñ9Xº*F€¼”!xh[Qàƒvpè—Ý€øõàjÿ˜k¯ÑTþòœ›Â3€"ýc=ðÊ!Ý©êe>X‹( G®(ëpÓX/Ýá”ÎÈ­¿Oñ‰€<[õ£â q0”¤ŠXj NæúKZ|Lîó¡è¡\ìB½sÍ3>ˆ?rk¬k€¹„&ò'I&†ÛGH*‚xÀR€sHd|ZoÔápü2YNöƒÌn¡@½$‰RhR9L†ÔÄ7Ú;^(B/ûã—Ýž‡˜¿ìI.<Ý‹žîîì$f‚YJåßÙ”æ÷Wâ(ƒ;Ḡ@@K©I”zÆ”U7tMÌæø|I~/·T0–lT"º•¢þÒQ6mìh#öÆcÆ/]íóLþlÌ¢ÖðÖžhÑŒ)ù§R——Ô5£8ཡÅJ*m0GÞ;5ŒÝt@¥u§GÃYÇ]¢ÞzþGEoׅܧ"Ð.+}Ø…‘K*n!ølÞËîÔþœ¶¤zƒšQõª}=¿Ýi§½ƒ2гðä\Ûc<]» ädp:úêž(óKÖMô—$¨ ä{OïèÆŽgŸÎòlŠâëÚú#G-×µy™ÞÀvî_û-»5b¼¥Æ«ïËU­xVR'Z‡ãp}bA§hÔ{øéøäõ@ʪY›“šÄå(á‹gÆ^/ÄoËŽÔ„SÄ›ÔZ7>t¦§Çqi”ñ;7"#]ð…òŸáò~rú¦•^ítÅã†ñxˆÞ“¥êE-|ݘ‡ìrÊL¶eÏ´·¡²f{S\»IçI—¡‘¶ÐÒx®ÈÖy›æ¥ |V|" wSEâ¯ë¢SіƯaÅ¥‘tß9Í®oGR(Ñ ©ã•r’GÕrtµØ,©1ù?ä8MY·=Y/KFkaä:ÀpMÍÄÖ•A3¢*èl]R ÛJ¶/ñ zV‚Öû¼ø“9ß ¶µÓõlþû]€û,GÂwàÇÇBšöë)k«¹o†`cnçñ;O™k Ÿ_•“.l§±pˆ.w@‘4é~ÊãsSxO"a‹Ýš<@a nÇ¥–ÀÑŠ.˜ ¡á»´ŸQËê-X£Å ÛŒX$—ЃhD_‹•ÁTØéb”¢“ž>Õ9rý­üaKK0;HòFfV1s$ë`E6cQ‰NÔ8…UûüŒ£M^—†($QÑ:8# )¡GQ¿àR?±{ö™}l°ÏíS«Õ¶i .õSøò„š?‡¾¦1øÕ-6džØÅ­Élð³G·¼_¯ìí={}î={ñôQ|× ,g2d:×_‘”¡®J÷àŽr <”_úÚK.ðÂ} `—¬à¢.f®¦rýŸö ¢œÈ–5MÑÆÅ['$¿Kqð9°Èj݆Œ_H(&Á´gM9y~· ³Á„Àö‘¼Ó`ísÉañ!F~áÜþo 8ƒÕÐ'BbÃ1Ö~¢e„£L56ý2ÊÀ&)&þî­•ü+û*!LÎøDø˜®rÙà!“zK$¬g6˜E Ž©¼n£ —ð›ˆL‹.AŠ)ú&(‹ÈGÄ®'­ërE¦¬0©…„xGÌ s›r_Í o⼤-4-€Aénà þxÔ}o>>w/uܤ¸%ømä'¿…ÆÉ‚rk+{A´í³i-s&%NX@‚<’ˆt1ï)\Q«ƒœ—vãÊh\¶½IîWf÷k,<@Ð|õÅ#{&ŠÉŠ¢j÷ö‚|F ×Ö_¡ŸÑ á•'þ•S¤ƒ•rWð”Aè²°—Y1Âì™2µòÅý¢ÿ¤ë¥˜W#E}ïõææZN:¨}i)v"Ý·ÕA.w_=1¹{ý` SFh½Ä*þ­Ö’•‚V=eÏcˇ´ÄHA-mpü¨rãÜØC³ªŒqWxÀ'7éD.ËàRïzsª8¾ÌYœØצÃL¨HŸ —½ŒËupÎÄG-ónQa”Þž_Pv ŽÓÁAß¾eg…‘ê[‚¾¥¤à­¢\aYµÕ‚_œ£Oq‡äÒ ¾g‹ïK¥šë½jEý(h½wç¦m#>bªÜÀ4©ˆÖš 8~‘庙b`¦£q ž]ênºÿ —VCÁ©g̲¾°ð, qŸG‘ë` 9 Þ¶¿·ˆ¸=à¶;øóãõ£xgwãï[ü60¾¡;xعšcÿ[Vê[Vê[VJ?ÿŸ•Ú–ú›d¥j5XùrAºšÏ”~kzáì0Z%.Þ4á|FµÊëä‹úWºeE§S¤¹­àÚ‹iÇÕE[ãd J„$N‡]N®3©ÒYŠÇ% öµ.ñÜh¸¦éO+I°UEçóÚ­0Únß †o_÷üp|2lû!žX÷d㨛È3RÀØÛ8‰¯†pMv <§åó"…%7¾Š©\à•­R ¯æ0ôG!1Œzåã¬à’ݱƒ CsEþ8ÍØ…` Ÿžâ576T¥â ¥3fš|4f¶l“¯?êGõLyáoÀJ2=t@àI S]ðU"ÞSäA 3ÅŸˆ¸H8'Ì8Ü*•*bÔ[Â¥“x"\Õ*áà \Ïî‡^”Û‚=éWŒXÛŒ”É­ß ÝžN/\Õõ8E!uQnÍñÀ߬±é’O>œ©¿cGqj½=’Gc²ìÇ÷²ð ±ß¿.¡)”=ÝÍ]è =ÇBð&\ª–ÖÑ]Xµ$B¨˜Ò4b6r컾娟•£~XZÎñúÃ\¾9^Ôðù“.Ç5OEÁß_žo¸W}c!"ÐÑUÒüëǘ_½?ý489õ¿wˆ}Ÿƒã×´yøqx|røêHN5‹¹1ÒÌ|ÇŒùd5_ìã7Ñï*Òî÷÷ás¾P=þ„ [Ã'wº¡WOt£gOwøÉVŠÍ  ©¨­ñ ’^¾Ô¢S»÷a7“~ÅF¾ïš§5°Ð ˜€W<…;žv¾ÛõøðgÑþÒ|ÉoÍ€|} äoypd={ÒòãG›N5ÇÏ[œãG;ëÜdÈ×{nµà èF«¿ê0tÜÓg˜\[;"½ ;NKÿÖAx†ºÑêþãÔñëw{”þXuCíý5Ô'{ucblogo-5.5/docs/loops.info-5.gz0100644000161300001330000002437207270062710014463 0ustar bhdoe‹b:loops.info-5í}ksãF’àwý‰­¥ãdÉÛ }»ðì(ÔÛÖY-õHê±g9 H‚¦A€ €zL8î·_>êƒc{ööâ3nЍÌÊÊÊÌÊÌÊ*Ü=dµ€ÿåe¹­£¬X—¯Ä¶*W»eº‹±I>¦ø«xL«:+ ñ¯Ñïĺ*7_îêê˼\&ù—uµüò͇‹Ësøû¾|½)Wé—„ðõý.[¥Q“>gÑÁÁ?¼Íò4vúWÐ8—××ïoÅÙõùJŸ›X\\O„¿ÞWéc,N¯n˜ÞÜÂß¶±¸+·à¾ÐŸƒŸo¾ùF¼þâµ@zð‹þÕ$Å}Z‹¦dìÛ*ÛÀ(ÓÚ†@“*]¥ë­˜4Õ.õð|ÕiõˆË*»ÏŠ$И8R®e¹}Gb’­£†þiýžæu*ŸáWïyQ6ôþõž¯é üë=)+zPVÞïMZ32üâém•¦8 "Ù¸ÜH+%1ËÖ‚é@ Í3ˆ&â™·ç§ö*}êâI´I–LíZÄÍ:zæÅÕ®ˆÑbF_× v4›ÏÅ× RnÅs0ý´Kò­†œÈ¦l.ÿ@tóc9Å"O›ƒì·è„Yƒ¢÷‘ž×@'ªî‡„ºà¿»ñ™- n·tG9±þôÚj!"žY8tµu:@I™Åë²ÚDô•‡0—¿Õø£že9üÍ\˜çb¤S…F3WíÝŸ©a²Ýæ/¤Šù˜!µ Ó’Xü&Ùlˆ-«^ZÆ!Ú+&²:ä*å4´ÆÓ'¶ Wü}9ÔÜ0?!yö}_Ìy¢_kÎÖYäÛPñÙ®¨·é2[gà%À„îò&0¥ˆe~`êMΖÏÖÈ•„>΢9qR¼ §, :bFjóiÙdñiW6@” +%šÄés¿BcXñÖÙ3`ÛÚ”UxÁXeëuZ¥Å2jû/¯öŸ¥EƒÔ÷€ù6ðBµb;s"î«4øDäi]ŸÀš¼JOæžPXbšš¨ØmÐØ¥üµîýœæh“»ÚB`fËBúZɹ«á/ƒ¡ÓÜéýÊŽ¾_ZðÇAʾԔ±ÃÛŒ¡N²9NAb™*{Y“ÔÀB R,K. 3ç>º°ó¤Iä=£Õee¶›ðï¥Â™†r¤²B=ÒŠj‰úEdI,[ÆÒAéj¥Œ‹ø ÝÓª‹:xÒAc &Š4ÕXRfõ1š.äuúéטÎ?´Öau—Øp`B1iØYÇ|vg÷ÜG!sûÓ¯1¥Öt²nâìNÔ¡Ù?ËÓ¤@×z·mÅåC¶€€e½« `ªt|’š¤U¡bËbW½øÎ9ù°ì1ÒoàXàH !-qÒƒ˜Û(,û^¬™P2£Çï.<­RgI3 WGqNÑðí»ìþA\¦i.nalËfW¹! ÅæiS¥ËÀ¢žÓgE”[m( !f‹rõ"›´y(WÑ!ÄáË’(Ž'Úsâg6†5y+«Ýf£bßÌæb±¶9Öò”O6QV<–€’ŸFi{@±Ó ¨7 5±ñÄË<ÙÕií¹ºá¶àe‘]ô[gGöÀŽçj‰ÜîêŸEL¢$4Ô1¢Æ8‚§á詬Vb2Q²cGª&Äõ=€åA:<öà̸ :tw¶â&}nBÜÄ߉‡ÇÚÏ‘tme¸‘&Ù‚QÄ9µÒ°›Nþr4kÙl“n¸\rsAÄ!±nãd8ýÈÑ1Ÿci‡žÓ怂1cuëõêkйåÉÅÒc"阋Äv›Tn'=´÷„Ii ºí„C÷æÓ__«D™gÜÄ®Èð ( ´â¨Ói(#Ër³ÑQ rrÃD„ò«q&Ñð´ZÍXãÍ/Ç÷ÐpÔhõ j„m¥.9Æv-9qì¨üMä éj ‡œxR G…\djZ\mP@§p¼´B6sÄ¡C… <…ò×€ð0”Ú"w‰ö¡[;M=FÌœ°w>7Ë)³¾v¸Ô¶VNã6[½À&m—Ç]§µeY0Çš¡‘·Ò]Zä˜Ë¡M=™h âØ6 ØÉ¥Žë…»p&:r€é'«CÓ•²Š²€A•ë<›¾¯AæÓª¥JËÿ¯Kÿ]Zî¥LËÿ;´i¼&9D·¤µ¥C¿­þôÓ½F&µ¿ 3¼*¾‚ئ_lvuó…(w ®Ô‰°r{®Æa¢,Æÿþb…káøï£p4%ýý:ç·­v(k2¶`þN&Ÿ5IuŸ6Ò÷þÆàCɕ՗'WøÄWãNÞmMù½=v„¹½MÔNb9Ž€æ8ZætZsBz6d'ËèÖ7„[z ç/_›ì~[¥¯dÆSìbÅ»[ÉcJ*¤u-=[þ¿§h§S²È‘ùÿblÑó[ë`{-íUÂå_-ì™ð}´s¹¯zÚãf›å\;Q—»jIU¨¦i›R |‘¸FmÅrŒ%·^‘Î à–ð$«tåTX|C™#*·Y*ô³x[•K,òY¦+L¾ÍÅWªµÊÍÔ(¤2"°Ù ÿ™[Ͻ¦/Õ$3'Mú@¤ÀÖ”Œ6YÑ×Xº ÝÍhZÚ†c€xÓ Y·ýÁÐZÞor¢-“¿ ëM޵“)ð¸R"-TÖÞog´)Ä´ôy‹|·´‘HƒMŽ™sÇr<0–™¹"ð&Î0cG‚ãd¥Æ²ŸPP)4¦à°ÂŒb1N6‹À;‘¹ú©Uþ©– å'³xtv=sm¼œÕM¹í¦xQ ˜Œ‡°Ü(° ',“Ÿ©*¬{g\/ÖýüH¦ñŽô·Õ»;шs­Ò5¡3%A•TéNŠ6Üé£ü¤×万;¥<ªXMåŠg\”±uÌÚŠh¨Û“díÄãßõ÷ãGYm4ŒXHEE %z©ó æ=<8²$[‰?ÓM[lÇóÀB5“É.¶rQ³­3,ú¤2^RU+…t9,2{K:j(lч+U–£füK9:ˆºu ,¸@m f‡¢¢â^¡ëx¹Tú&⇲úXo“¥.RÕáć=i?çMš¬p÷Óu@4ÈÛLÕÊ–Êç¹ñI¸p‘KHSU…ŠžT]kð3m)ÎðwPtÒ¤õ+–ˆœ‹—kˆ``™*jˆlÀ?+‹UþòJ#yÊ [ZüÉ®ØÕÉ"§h¹rýæMÏî¢w§ßOoü1c ×s†ýÊÁÙæ™tZBLñ>,ÁG³Ùó\­Ú„UÐ#Ú቟Å$ ‚YÐetVØGúJü`‡E7„§cc)üQ;[Å15š«ùñ<ŒÉ8Ÿñ¯ ­ý¸8zL«E‰¦À4è.~ÍèC¡‡À s$ðBåÆJAì(˜g@# Õß&T[üÚ_¿Ý° òˆ®!ÚŽt»YŒÅبÂT¼õN‡,¨žb96W‡´Ä ÿÆâç<«žæ:4•|€g‹*+š§lÕ<äXÖ þ·Œyæ µAûå¶§êïÇyW?«t;ص‘ýXíM?æGSlêîÇj&O&:,W?q,ÇÌ….óÕS•i%e8ý£°Ÿ•Û´ ¿ .~P§Mð÷m)Žäš ƒ.Š}ÜÈà>¸(³·Úžã–Ú™¾½‘,sg"grxn%«üŽé{hNyªl0kÂbúVÆ@ |–l“,M–êeÁ²Îöc™Â¢óeµIš™zó"þƒõ*«6å½b•Á7ð¡L4~ù§.Ì!éÏ厎b$«•x_”O…1,K‹`:…ó˜Ñ‘h T㱃 §·Äó´Ž™îœè6KèQ­ÊkŽ {óçÄ ƒ …dÆ œ  ù:‘8Ŭ{¹~ Kî»ã‘„^¤Ð‚Ó¯_[h°êé)Ã\|¡ì…òÖ€çf˜äºò5Š6RæRÃt®xe §tuÌÌ2cÓüc§4Ça¦þ5’tË"q‡^†cj]‡–ãô‰Ì€Ø3lG›ã£ZA†›£Z¹Èø¿\ò5 •ye1D´½Û9 áòSËÅ_Óeã-QD>.µV~ºÃÉ–ñboyÌ8{{©—8½#íØ¼™Z—ç:¢eVºæRJ#8Ó‚üVû@“*æ“çÅ‚–Iž)ó±Iž¹\Ö«=?Ð ‚3rH~Ó!¬ú‡Iu_:ËÍìé=$=ˆ)üÃ: &ƒß“*:¤p¾5›-$ùÓažl«ä0ÄÃÃr‹1C’²ev¾©S OýD²#qÈê ®¬ˆˆDq¸È 4]Š~eî5Ý\Ì$G«]%,ï!W‹|qE˜¤ Ÿa0@›àÒ¤&.Ø”0b˜½Fžl¤3o y ˆäñ´”ÍÍò# ÀÈ)«cH¬’e#íRÀŒA»¶5Ûnñ˜«/°-v˜¢®­ã![>ðøUbÎõ•…ñM¥ÏáL^þŸÅŸ{(~ŸäÖÚXæ¶Na4³NpÄ ~݉Ÿ A,s±C?‘+ÉÄ/Ó$§yFÇÐxñ:àbSŠw„¥ °I¦ã-¼R <@äH¢¨B øp-õvðLf% ªc=%(–URѶ—28M†Ž UÝ!´:apèO›–÷.f䜾àì“ë}ø ëYWe_'kx'˜›GfÊü¾g28Gßþ òbn&<φ˨…´,u“rŸÚl5FÍ­ÒÕV¯ƒÛ¸½ù.?*×£)·¯Ù=bkëø¥0#Ò7ÝŸ¢CiÉ%4Z% p«…[(›>ƒ`5­âL&º{Æàeãµ 'ëÇN¦U²…—.§[ýM"Ù%~S¶×h í€ÉŒc:=››NÈÏl¥$Ý“T5cAùžÁ„áÆ¤ecœQë%°Õ2Ó p:9ã¸NP=33•Ý|ˆü>¦/\ +™ÍLIÙyñµê]­£G®©UÔƒy=|i×’:ç?}Ipûîpnf¡jìújwvv‘Þg…\kŸK"V\<ö† KÌyÍ1Ì6É*¯6HYh¿)¶€5®À]˜«± ø=š\›åöœ8šæ/݃O¥<7¯l´xÌêlA‰FQ uº½;½»8ãX‚+eãc"[/O¨^ÃýBÙG©£È͞ɕ0HØXÎÈu*È$ T‹F!!Ž"À´qÆxÈHZfK@ðÔ"¸G§ïÞœŸZK,Òuì2µÙÚJ#z:¯@»'B ¬‹çÇmmc®cÆ{zss}‹wY]óá}…eYUèl[£_ã¹oï¼Ï¶2ýv5˜a’õ¡Üå+ ›> º³ý¸¸+Ç)fŒ«öëÖ6+ä}š‡ª|/©ÜÒ:5×´Øe99ºöÊ¥¦F:èvÕ‡Ñ$»©ãƒ‹êÔqÈÐe!hu:#ÆfbÂ)'ó#ëºÓH9óNrdœ0sRD꨼ ‚&‹ÝòcÚpÞߢ×CbÓ:™|¿ëDÁg>Ç’ ùà‡ÈŒÄLމ–e¾Û¼w"'›—›£ºÄÜÒ¢^bÞâßi“0uY;s©Â*9ÐnWŒÊšR[$Ê­£Ñ0bƒYþ­FL¢íUŒìO ÇŽ Édƒ\X][Ô]‡–ìžrô¼M&Òm#](ã®™§õnaíþÈÚ3wùŽ©AÄ‹ˆ|dì”6ÓV+Wñ"ëzV´ŠjÎòœx'…¬.ºkÄ•ªEg焵W§ó.G;Ï!yþa¹u60´K‹ÿ¨r)­O±ç=öËÈQ{²¶Î¸YÔ¶PHb(ÁáxÓkNÑÐ Œg=Å®Ne"íóÙZïҔƫKƒ%ðWI­2ýi4Ž €£B%ŽÕªl°  ›«}ÊÈ‘,›æ˜ô8¶ ¥—ãˆV;Y¤,í“ nå‘7S ¤£> “¥ižÞ'”¤gÍŽ7õ½=e2cºÕ ¨FJNcO=”Ay m{wE¬SÌ_Ðá& ªvE†¦EÔ/E“<‹ÏéÙ„qñvU}®AOgØéž}h©D :(›u±Ä‰év`'%Øzêm 飿Nži<íhä]ºÌŸ€ß¶7YrúZãoOúÌä%«Ø\Ò˜FôzeØÍ97™¤‹Ú•Vt‡•ñ度Y¦KbŸ)GÇž^]c p$BŸ³WH' œí´«ÛDíÊRV–U#¼DÅÙ}QVáÓùC(xÑ•Ún\Mܾ_$ ¬Â¬ðþ¼â9]î@=?Ç¥%ŸmÏçf‘›LnO¿Æ:…f©Ë‘“ ž¸ÈÀû„åì7j•9¬ ¦o?ǾÌZɽšnÑ:jé%¡V|‡& ›çƒÇ{ ¶yt¨Ö¦Š:µeu[¶¶?*ôaŸÙY£o}=k¹lå÷‘%ðžXÐ#©ƒ¦שÂ}Åk•[ËÅ·2ZÝ̰µT«Ç2§$ŸûüÚG殢¸MÈÖõ·ÄB•¼÷°¬bþg6kž;ŠÜf¼ó2 >Äç3}"P„JÒ{ ÝÐx0™‚‰îò/“µ¶Ê[tI6ÆE,QO¯TºE!½ãªÇ äŒv´:x03kTG¯3*Á̱$ ‹JàLeµêŠ]ðÃX”y'ÛôGÙ9nÿãýî°³>Íé‘”³vj’zkOgr—AuLr{6©XiL ÅC`²îÔ™¾aA‘+S“2}¡ˆ”*gO!•îšâW'ºû%×U­ÌæFh²+}•X…¹“-Ì‚V ^~þ"”WÐ=c~¡‹Ö L£Hä„—/ÁšÈµ¿;;Y¼(CÊK }EˆÆ‘…çå_Dѽ•Ér™ÖµµšÃŠUV/úÌ~¯ßõéÑ Û‰Šdù‘D>›ÑV\ÑȇŠ`¾Qޱ,ûQ‹§JÙó_Æ(yþ¹’.íë`†š‚*Õm0 Òvö€©Sßµí‰/gpîÇã¦Íz6nÌWÇpÁïÚ ˜¸ë_w|ž¨ò@+è0Sw¨Z;C´µÀ1 ßuºu£Ç&JTÞ+žKà0ïØ’‹¤6Û¾yV|´äë1©2,ülUãYàñ3 x¹/ü¯– `^-Ó<·;úGeCDZˆ`‚äYùœ±zrI½—V³NÑÄPâ¦õ´ò{èà.ɳñôªÆÎíÖ(Jð´çHµÓнìFtã_%‹‚½¼ÈL‹6úè*y›-O¶_cúÝ9¨;0É¥{ÂÒq gùÚ~v˹¶y|ÈS²%´äbâÃ’1ĨV²çKÊÌ #Ú(Ãñ|ÈÈéŽ}$ ɶ2ܲÎwE8 ‘TNH¬v«©`EµB™hÚÛÖ³68w›íqpN S‡gTi^ÿd.À…Iõ²Ss* OCÒýZàfUºP˜û«_qI;–â‘:fea,n¤ÈÊÁ7cÖX½‚ÃäD¢Œí°tˆ®“¨ÍZg“$xrå®é^ÊÂÔ¶"Äwÿx{Â`®‚ö {ÁDA@í0F†Guš¯­àHz£ø£—A艈ÂâëËnú >),)i5·ï‰sšØ~:5ê3¾pÙ\ú0NÒ á¬ã¨fë—\ÙAÀ@ò¼öÐàZ÷91D¥Ù°åçf4-¡0á-,ˆ‰‡n'tºfü‘NfP-U*V ¢šâÍ£iZÔÿÎ8m5JSI½•2E.ãð^úìY¼Ìí‹eâÂ8°Ï-t6Ãáîøýå¸Ï³¯ITLCׂÐßmoQ ºúŠ-±´@öôOÈÅïJK˜Ï삊ÆLQ-£þgàѪI›/tïù§žþ°ý6ŸXŠ0¼xÁëQÛ\‹¯\k¼J;àC°¯}h¼­½ ÃÇŠKaë¯æõײýˬZîò¤RC…’âõ³¿òþÖU n_ùåëš$+RÇõÔ“O'zmÊlþ+~ЊE˜¿’œK‡Q¸“pUs´VQªA´ÐºÖ[î8ÈévP­^^Dµ!7Õ¦: csŒ]’AfàM#»†Ú£9Œsä|dœ• ,ååL¶a%™Oä®÷\°ös$.-‘?ìV¼=~¢¶Éçæþ˜*4àh¸u¾«Â\šÍ»Ö.¥«Ã«—Ä7°z½½¸¼úˆ‰EuO H±f h)Ê|Õa÷ó+Y‹­Ã<Ýù$¨í.7·¥œš«e|\,~Aëßî˜Ö]1»¥¢ ˆ 8p?ªì”•ÒG²hA1²+ ¿ýãÈï ¾Åt²“n"'ûЬߒ•3•“d ˵Æ5 Ù«r‡u¡üv¾™Ç‘d~¥|S.d±›S‘>—, ø…^~ËÝB´g “{¨C߀3¯¼µg”6 ¡ Á³rH±˜Ü o'Þ‹ÞP‚Þ!8‹?]bÝ$+‰¾Ð³½Ôyþ®AXq´Y¿ÓUÄÎn‡ïàÆÅŒY—¨u;ŸvéÎòˆÂu%¨eÐ)†~±ïzŒ[jqŽÔrûÛ/µiA£²-¾œXÓ€aÅ¡3‚ ¬9"RA€Ð)d²7W-¨ÙYFÁœ´Ð¬O,±ÈEiæŽDº¾<ß–çT/ #=Þ°h²<Ò:Ì3üµ& c}í0ƼˆÕíI)áîUÊMÐ)N>¨eŸÐÄ’|T€mI«ÑÚ&ÕGS¢À—Š2LV•ÑRo“Kpk£¯·-ŽóéK}/óãvïT3Û¦Œ™¤’½¬º¶«øxîÓËš|Fx®'3 ³y»µe®í:¡_諯³ Ö^o­³ÿEÎ~8yŒ_¤ªGé'7òÇöZ†dÙL^û·ÿZ¤¨®°uœÝÔ³ ö£1µŸû!ŒýÌrE[ í4âþkLCŽš,Å¥Ö„ËøÁ_åa¯Ç Û`CŠ+|ÄßÇ‹ ¦Ø¶>¤/u50Âו p=<—£Ƨsfªžp‚ÛgŒ30·¼¡DˆâÈXØ_þwÏ^Û‡pùÊ¥ÿ6”Ò¦§mzP‘~ í݉‚. ë2V^̰Knøß9 Çd‡õOÉKGGtM‘ H±\9²²G´äõ˜À>æËÐfˆ"7êùGÖJ7„ );GqÊ–ícVÛ’nåQÎÄÜ &™µÝkÌ> RedŽaXœÂé†Ä,&-öáXU‚#Üq½•Øu©Ùû.?ƒër×’^OG/§û¯ÊNT¨ã¤p²Âãâ–}<<ë)j­h¯#Þã³]N©¼[¹ÑUµÒÊ‚>Þ^ ½èÅ‘­jØÀǯŽmméØõns{*´¥Rq° ò%}XäF—·ékÚ^™ZNyE”*^Äòq™i¢giß·HÞT|?¡ayG£·tCyïèhè¿a€ïqËû¸%WŽxCÀð»=»½‡Od±öÕõöÉÖÉ]Zƒ0@»'ï¼|ë½’AÅ42{ºZeX.Lå¿tn5Ïx•™'òžùz‰2½ÚÜ}“²ûòtõ.e ¤™ä¿LY7·ð—Þ{”M+÷»r@¹ÃÚ$ÏÂ÷º7k fæäÎeLº½$;±hÓ„µÆAÔô½Í}ƒ×1ýÝäÊ×k÷Ó =Œ£Ié£5}L ~Ý÷ÂÜX,þ–¢©Ò ˜îžµççjše¹}Y¥è|²þgëõS®Vínè^›€.ô€ã„þë#gr}ìêü’¤ýwýÈÇ ÿã£×N{\7»õZw`ÿÙæ¬åöæuãÏ?½PJI@nÏœ“mº:°Sâ4Å=ˆ8X¤‰IÍ¿-wòhW™·DQ›û”Ä!ƒyGq”éÑàuÎû¶ÚË:!ÙÜžÁ¤>\p£HŠ”w=˜6s讯b¥˜Në^ ÷xkå¾<ª~ÀCY³9Qÿò?ꉤm[ወeÿˆù\ežlkz—ã]Þ}ȱÒ9f*&üš‚Ž«ñå %ò²7ú'¢—µù*Eô­Ça— 2Ú3´¬‰¬Ã¤®¤o¬[¬Z´ŒÖ_KLørM¤ÅñÅpE»IqWgö/›H õ›´úî+ߨjZÞÉû\ÁSÛÒ½¬(Ê|aßãºf ïQLOµy…'u›FµìÔs0[û.m²µ|§fëwò¼'Þ‹©ôs:VËþ•÷!üOûIYáÿÛ¿ã•Øüßö³U¶^§UZ,Sû{T{Í>íÊ&ƒ)4ßZMHwOä¿[ï¡\IOô7¿®]'üÿˆ…íD}Ùª t±²”ÒÊÛ©dGÍ”òHW•ù&ˆKBrDЩÁïüã·þ…Þ›ð÷Ü–-ï™öQÙ/Dnß[í¿~Í5ˆ¥0íKµí>Úó)̼‘Ÿ~jûÉ™'Ò}ƒ/|Ͷº©Û½ƒÛÚwÑ×f›ŸF\ŸýÍ7<ÔŽ)t6Úì³È¾'lǟ÷†¸‘(è]aj°Þ½õ±SE[Œ°n:¥×K°±àî—*©O7þÖKÈ,lí”]ZE}!ºo¼:Ü3û‚çážoÔ'WÚø‡î8éÅ%òú{ŸæiA7¯³-8¸*X9qˆ‡Ä"M Tíb “³z…ÇØeó`Q¯&û€.ÈKX_èåøNƒ—§äå•ýŽAù(¼–oeÞ†´Jù¬&ôw@ýi©‡•(UÃÈô­J> â/–ù/†I%h÷ÁÁ?¼$±dV¬ËWB\Ao±¸¸:Ÿþ½¯ÒÇXf#ήϧðÓ‡m,îÀ= 6_àçàà ñ.-v1~qï"‹Ã¢-Ä›gßOï"à7hv¶”Ÿ³ÓÛ)6G:Ô>«Ó«sj.-Èȇۋ«oÅÝwSç»÷—Óו]ñ0 [[²Úò†­Þý„Pd@ûx3}{}35'C pb > 0Ä%8TÜz3ýöâŠÚ¯Åï¿úà ÀÙõÕÝéÅÏÂ|= s~ýáÍåt5•LžêèâæìÃå)÷“¢Íë'EœÛÏ8ÒX¹Äè7×7çÀZÂú´2ê‚ ~x£×@½G- çªy$7éú´Âj>F$ ù™n?Œßnoûœ]ŽTŸA¨D%ýt¹LÂMîA êȃ ÙOWßf˜[®-pœð>–}¸ºãnVc´ÔƒXg…¹¹ ÚWåßôv>½œ~{z7eÚí¢ï¦dû*å° É£„`o¥Â¼›Þâ‘·ª¾ÞÞÎ/Þ¾ÞL¯Î¦.PÔ·öø@÷Y“à Låòc7ÔùÅ·w§—âìòúì{‚3éö‘øþô‚gÉ?˜rÅÇßÚëèÈzNãÍQËrÛÃ=6MÈw6ÇÄvYÀ2¤Ln‡ h@mb˜½Ü™©¢­ÝÍv˜´V7{zc²n|´fp†i°“é?œ^’¿k_¾ÒçV¹Ë+Õxð’=(Ì~CMÿ4½z¯Ú3ÌjÏw–N¤=)²ç¤Œq+½~Æ8•á~F­£F0×yÒŒà1†ÀbúöíÅÙØ«?3$^Ù>8*D\ðlV Ⱦ£Â‹áX&3Ê8¤ȈEÒcž”†Ò*ŠëŒËL 3"£€µ àt#Ú[Í_öi^%Û‡lÙ· âçÛ›Ó÷ß]œÝ2'¶A¦àÜœX C¡»‘¡ûÃp8‰ZhÁa¹ýazCô©—¸‹óéÕÝÅéJ6.¿xËÇäRtcLy¶¾x;½äøKçïûa,€Í(+é 9íµ¬fž§¾’³Ÿ6·Ò¯Û†ÁÀüÏ>£€à_Çg пõ)½R͇„<Ú¹œ†îŸp®å`àB½º]ÑÆN= áÔãÇã®Z]yVáÁDƒ÷‚:¸n@ÎÅÝ)ð¡ÆäG„7³cÒ# 1éáϭޡ퇼<½½[© ÎS~e9娻ᦨ ÈEŒ¨.§§Âï”¶f$u=bu¿„€çDµÎR{iDy·n° %©÷7×gÓó7ZQ!&nIX"ËŽêä~~¦¨Ã,&÷Ï=Û;5€a‰Îǹ#žÐŒôGçØ½éÍ^éϻө5×<ïû(˜¡¸£g ½uD}€¸ H?m!Ò•$ÀƒÁ 1 ³?qƒQËë5Ý€ï¦wß]Ÿ¯¦?¾¿¾!#¿³ñp¼ñ/ÖÑÜÞé©iQŽrc¯®ïdë1^“l-7JÁríhë°Îæ’³uÞ=Ál† Û9 ±zwúý´Õåf¬Á¹ëósÕ|DÐlšˆã±9 åÊrãí×£ö…Ôi*Ï{¡tórÌ(ñ–ìõ`åvZõdÈ<ô£‚T ý(Cm©Ýô:<^°£¾!vÐb‡h$Ó¡QA ‘CÛO»lùqÐKì ko¨ûã‡ë» plÞœ¬ R%Oûˆd•nÊÇá`Ì0Œ.«ö <€1É$ùu*ÀÀÖ»kò™@D¯ÎOoÎÉ®0†`)èfúÃçÏíÞéˆÓ^Ë8ùûùû¢G”,÷ßw§~«»ß[ö ¥“vî ×íò!ݤ?Ã~‚ä§Óªù©\ÿô¾*ï«d³Ññ½ùC¾†]<3“°§«F…UÃ}ÜJW€›:¡]Aœ¿òŒf£.£DÙ¬ëýRUõ~©*såÇ~ªu9Èx' oçÛg±0U¼½P·ï//îV?\ßp'¦†®Êt‚uÏÃglÅ5…ƒc³¦Ô!PywqF®A=õî}k¨Nßë€ZWëtaè}IÙ’6ÝwMGæCÜþùÝ›ëË‹3²'î€#ÜÝNoØnPYûèöÿ6qY!0½ucblogo-5.5/docs/loops.info.gz0100644000161300001330000000245707270062710014321 0ustar bhdoe‹b:loops.info…VÉrã6½ë'ÂcRÛÄNø’¢HHFL‘2 zÉÍci&®x¬)Û“JNøõ4 "ãeªt_?ôÞ ˜?ïŸø=ìvßžï?ï~M¾=í6ßï¶›äÓ¿É×Û¿¶MþÞ>=ßïzœ&ŸŸv_g'ߟŸNvw·'ÏOw'ó^W%|Ù}Ým¶'^áÑ—ï÷›íñËöŸûãÙì§™~ÜÜ?mï^Ng{Gè4Ai6FðiBe†Ä#§‰Ì¤$cŒÂIJ249Ì I öÌí—ÄÜ~zØžÎ~¶™Õàßibv߬³»ÿÒµi›²/ŒnjˤàæRµ—Z]Y‘±RµQ­®—I^—I¥òK÷¿jšug)¥d`gy½T]bš¤3ÀÌ[ 7Ë&Y·M¡Ê¾U)J‹ÆÙ¯l–F za3œáø¥ªNY‰QðبÎXɳtøÞ€(ÍЀ9]äUÒ¬U›»¸:KBót’JBmáSÒpºnŒE”á𭮪KUBj¡¯­M J© Á©R/ªUu¡,b2•|Ñ7FCâ,★çjÑ´ê7ÀXÌûp D¨.ú¼H`œ_¶*‡28#4ýq!Eð©R]HFx:B<+i8œ—¥öIr%s•²H¦DÆú”*Q‹…. Œâd|”g—åQ]1&O MÐBsy1IŸKKÂ#~YXBåÁtu',‹…r@aiJšµÛÏp´Øí^w/Û#d)ä¿)à ãEc«µ®T à!}çÚœ©‘˜ A'}ðšÂIÒÛígb•ãÔP!iˆ¾¡s2!–ÊTˆ÷ª’TzÞæíÝ/ˆq×X–ÂÜÐ*¿¶ ¥‡o c YU—ª^²XS–Y¨Íªmk' a =¬Í…±á\•wf³Îu (‡»u¥ÍæªiKË 3lô ü$”àèúÒyF¤ '›ùïª00Žn`öÙ[¶ù XZFy,„φÛAó’f¾“¼¿Ö•†<“Ï19Dë­lVù9㌆;¨®å„ȸ‡ Ú-p”q”ªRK6Ë)á„2]x€ s¯ÌYSnÔõºiA ,x1‡îL È`çÜã(ö>Z.8‹û¡/Ε͉yh#ŸzP‰cê¯òõ¾ Bщ9”B9HŠ8HMïv¹Íà,‹My¥÷í¤°À¼¦WÂñÐI‚ñAsmr]»Ó„¥øŸâÜ­ìN¡Û¢¯r ù«m?±6ÖR‘Qúž;¹ÌBý˦ŸWj£üuʰ ðD3¢Y*Þg`Ï€¶~—A€ÁRþwÔ3â¾¼èU¯„ѰÀ<2õ ¶5~SèÊhÌ)¬TëÜŒ†îÑ«u¥V0>þÚs2.ب¿]WpäKRºK×Ûú¿p⦄¢ñ°ãq™þˆGOÃÚw»ÒQ÷MßyqPóJ:ñ .‹«ˆà´bà"qD”ò˜`·¤óÊ£4Ìl¤õ™.:‡.»îf5o*]xõ½q ä‡ÎlajÊÄäÐ!NÀCÓŒðIdL’(ØS∗z© \ÅÜÈçvxî»r,™˜`’ò! {'‡îUî%Å çeìP€&jEJ(~[Š”ÂªxSJ¼”¿s–zij“×Ý•r/0‘2ž½Nò˜ H¨‚o$Bš7ÁƯ(÷Âõï ;<¯ãõ ®-F„P/nõ¸Iâ«{ö+Û ì^ ucblogo-5.5/plm0100644000161300001330000021134110271516655011455 0ustar bhdoeUnderstanding the UCBLogo evaluator Prerequisite: understanding the metacircular evaluator (MCE, SICP 4.1) Corequisite: understanding the explicit control evaluator (ECE, SICP 5.4) Contents -------- 1. Review of metacircular evaluator 1.1 Recursive structure of the evaluator 1.2 Tail call elimination in the MCE 2. The Explicit-Control Evaluator 2.1 Typical C-style procedure calling convention 2.2 Procedure calling convention in the ECE 2.3 The evaluator uses surprisingly few registers 2.4 The two-screenful version of the explicit control evaluator 2.5 Implementing explicit control in C 3. Complicating Issues in UCBLogo 3.1 Commands vs. operations 3.2 Error messages and tail call elimination 3.2a Tailforms 3.2b Tailforms handled as embedded calls 3.2c Caller-status arguments to eval-sequence and eval-dispatch 3.2d Detecting errors before they happen 3.3 Macros 3.3a Why the MCE uses special forms 3.3b Using rewriting instead of special forms 3.3c Logo continuations 3.4 Dynamic scope 3.4a Reasons for lexical scope 3.4b Reasons for dynamic scope 3.4c Shallow binding 3.5 Nonlocal exit 3.6 Lack of parentheses delimiting procedure calls 3.6a Tokenization 3.6b Monadic and dyadic minus 3.6c More on runparsing 3.6d Treeification 3.6e Procedure bodies 3.6f Changing a procedure's arity 4. Data structures and types 4.1 Pair-based types 4.2 Numeric types 4.3 String types 4.3a Internal structure of a string 4.3b How to create a string node 4.3c Including punctuation characters in words 4.4 Symbols 4.5 Quote and colon types 4.6 Arrays 4.7 Primitive procedures 5. Garbage collector 5.1 Node allocation 5.2 The mark phase 5.3 GCTWA 5.4 The sweep phase 5.5 Per-node gc data 1. Review of metacircular evaluator ----------------------------------- 1.1 Recursive structure of the evaluator In Logo, as in Scheme, evaluating an expression involves recursively evaluating other expressions, for two reasons: 1. Visible subexpressions, as in (+ (* 3 4)) 2. Expressions in the body of a procedure invoked by this expression #1 gives rise to the mutual recursion eval -> list-of-values -> eval while #2 gives rise to eval -> apply -> eval-sequence -> eval As usual with recursive problems, the resulting program is remarkably short, but it gives rise to complicated processes. In what follows, we mostly focus on recursive path #2. 1.2 Tail call elimination in the MCE Since recursion is the main built-in means for expression iterations (iterative tools such as MAP are written using recursion; for the moment we ignore Scheme's primitive DO and Logo's primitive REPEAT), it's important that implementations be able to evaluate tail calls without creating extra frames for each call. The proper handling of tail calls in the MCE depends on proper tail calling in the underlying Scheme, and also on the fact that the evaluation of the last expression in a sequence is done through a tail call to EVAL: (define (eval-sequence exps env) ; SICP p. 367 (cond ((last-exp? exps) (EVAL (FIRST-EXP EXPS) ENV)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) To emphasize the point, the evaluator would not handle tail calls properly if eval-sequence were written this way: (define (eval-sequence exps env) ; wrong! (let ((result (eval (first-exp exps) env))) (if (null? (rest-exps exps)) result (eval-sequence (rest-exps exps) env)))) This might seem more elegant because the call to EVAL appears only once in the definition, but that call isn't a tail call. 2. The Explicit-Control Evaluator ---------------------------------- 2.1 Typical C-style procedure calling convention In typical machine-language programming (including compiled C programs) it is the responsibility of called procedures to allocate space and save whatever might otherwise be clobbered by a recursive call. So the calling sequence (in the calling procedure) looks like where the second line represents a single machine language instruction that saves the return address in a register and jumps to the procedure. The called procedure looks like this: ... ... 2.2 Procedure calling convention in the ECE But this won't work if we want a tail-call to avoid allocating new stack space. It's the caller, not the callee, who knows that this is a tail call. Therefore the ECE makes saving the caller's job: When the caller is making a tail call rather than an embedded call, it can leave out the saving and restoring steps: That last line works because the called procedure inherits its return address from the caller. In other words, it returns directly to the caller's caller. 2.3 The evaluator uses surprisingly few registers exp an expression to be evaluated (argument to EVAL) env the current environment (argument to EVAL and EVAL-SEQUENCE) val the value of the expression (returned from EVAL) continue the current return address (set by procedure call instruction in most computers, but assigned explicitly here) proc the procedure being invoked (argument to APPLY) argl the actual argument values (argument to APPLY) unev a list of expressions (argument to EVAL-SEQUENCE) In addition, the SAVE and RESTORE operations use an implicit stack pointer register, which is never explicitly saved or restored. 2.4 The two-screenful version of the explicit control evaluator eval-dispatch: [Corresponds to EVAL in MCE] exp is self-evaluating -> val=exp, return to caller exp is variable -> val=(lookup exp env), return to caller exp is special form -> each one is different, much like MCE exp is application: SAVE STUFF EXP=(CAR EXP) CALL EVAL-DISPATCH ;operator RESTORE STUFF proc=val argl='() unev=(cdr exp) ;actual argument expressions ev-appl-operand-loop: unev is empty -> goto apply-dispatch exp=(car unev) SAVE STUFF CALL EVAL-DISPATCH RESTORE STUFF argl=(cons val argl) unev=(cdr unev) goto ev-appl-operand-loop apply-dispatch: [Corresponds to APPLY in MCE] proc is primitive -> do magic, return to caller compound-apply: unev=(procedure-parameters proc) env=(procedure-environment proc) env=(extend-environment unev argl env) unev=(procedure-body proc) goto ev-sequence ev-sequence: [Corresponds to EVAL-SEQUENCE in MCE] exp=(car unev) (cdr unev) is empty -> ev-sequence-last-exp SAVE STUFF CALL EVAL-DISPATCH RESTORE STUFF unev=(cdr unev) goto ev-sequence ev-sequence-last-exp: GOTO EVAL-DISPATCH The calls to EVAL-DISPATCH are capitalized in the above. There are four of them; the first three (operator, operand, body expression) are surrounded by save and restore operations, but the fourth (final body expression) is just a goto, without saving registers. (SICP pp 556-557.) The version above simplifies the actual ECE by leaving out an optimization in evaluating the last actual argument expression in a procedure application. It's important that special forms that evaluate subexpressions, such as IF, are written to tail-call EVAL-DISPATCH for the last subexpression, so that (if (= 2 3) (this-isnt-evaluated) (this-is-tail-called)) works correctly. 2.5 Implementing explicit control in C The C language provides labels and goto, but the labels are not first-class; you can't put a label (i.e., a memory address in your code) into a register or onto the stack. UCBLogo gets around this restriction by using a kind of pun: C has separate namespaces for labels and members of enums -- the same symbol can be used for both. So in logo.h there is a declaration of an "enum labels" whose members have the same names as labels in the evaluator (e.g., begin_seq). The newcont macro that's used in the evaluator to store a new continuation (in the ECE sense) on the stack actually stores this enum (i.e., a small nonnegative integer). This stored value is translated into an actual label at fetch_cont, which says switch (x) { begin_seq: goto begin_seq; accumulate_arg: goto accumulate_arg; ... } (The actual order of labels is determined in logo.h; I've tried to put the more commonly used ones first.) 3. Complicating Issues in UCBLogo --------------------------------- The SICP evaluators leave out one important complexity of a full Scheme implementation (the nonlocal transfer of control allowed by CALL/CC, which is somewhat like the issue raised in Logo by CATCH and THROW). Also, Logo is more complicated to interpret than Scheme, for these reasons: Commands vs. operations (not every procedure returns a value) The desire for error messages that hide tail call elimination Macros Dynamic scope Lack of parentheses delimiting procedure calls These topics are discussed in the following sections. 3.1 Commands vs. operations The UCBLogo interpreter contains an object named UNBOUND that can be used as the return value from a Logo procedure to indicate that, above the abstraction barrier, there is no return value. Consider the following Logo procedure: to bfn :n :lst if :n=0 [output :lst] output bfn :n-1 butfirst :lst end The call to BFN in the last line of the body should be a tail call. This means that we have to treat the word OUTPUT specially in the interpreter. To the user, OUTPUT is a primitive procedure that takes one input. But we can't evaluate the input expression and then call OUTPUT, because that would make the call to BFN an embedded recursion. (In other words, the call to EVAL-DISPATCH in 2.4 above that evaluates argument expressions saves and restores registers.) Instead, OUTPUT must be treated internally as a special form. When OUTPUT is seen, even if there are more unevaluated expressions in the body, its input is evaluated with a tail call (a goto) to EVAL-DISPATCH. Similarly, STOP must be treated specially. EVAL-SEQUENCE looks to see if the expression *after* the current one is the word STOP; if so, the current expression is tail-called. We must catch STOP early to handle things like to foo IF condition [tail-call-this STOP] ...more expressions... end Under some circumstances the STOP is seen as the current expression, rather than as the expression after the current one; in this case, EVAL-SEQUENCE just returns to its caller. This situation is exemplified by to foo IF condition [STOP] ...more expressions... end In eval.c, OUTPUT and STOP are referred to as "tailforms"; there is a procedure is_tailform(exp) that returns nonzero (true) if the expression is an OUTPUT or STOP expression. Note on terminology: In above-the-line documentation we distinguish between *expressions*, which return values, and *instructions*, which don't. But internally they're all expressions. A third tailform is .MAYBEOUTPUT; this tail-calls its input expression, like OUTPUT; the only difference is that it's not considered an error if the input expression returns UNBOUND instead of a value. This brings us to the next topic: 3.2 Error messages and tail call elimination First of all, in order to give error messages at all, the interpreter must maintain some extra information, mainly the names of procedures, in additional registers. The main ones are: fun the name of the current procedure ufun the name of the current user-defined procedure this_line the line in ufun's body being evaluated FUN and UFUN will be unequal if we're evaluating a call to a primitive procedure. Logo gives error messages if a return value is expected and not provided (X DIDN'T OUTPUT TO Y) or vice versa (YOU DON'T SAY WHAT TO DO WITH Z). These error messages would be straightforward were it not for tail call elimination. The obvious place to check is right after a call to EVAL-DISPATCH; the caller knows whether it wants a value or not, so it compares the value returned with UNBOUND, giving an error message when appropriate. The call to EVAL-DISPATCH for evaluating an argument would require a return value other than UNBOUND, whereas the one in EVAL-SEQUENCE for expressions other than the last would require UNBOUND. 3.2a Tailforms One complicating factor is tailforms. Consider this Logo program: to foo output print 3 end to baz show foo end When we call BAZ, we should get the error message print didn't output to output in foo But we don't call PRINT and then call OUTPUT; we just tail-call PRINT directly from FOO. So if we're not careful we'll get an incorrect message such as print didn't output to foo print didn't output to show foo didn't output to show On the other hand, consider this program: to foo print 3 end to baz show foo end This time, when we call BAZ, the message should be foo didn't output to show in baz and not anything starting "print didn't output..." To avoid these incorrect error messages, it's not enough to remember "the current procedure". We maintain additional information specifically for the DIDN'T OUTPUT message: didnt_get_output the context (fun, ufun, line) wanting output didnt_output_name the procedure that should be blamed if no o/p These should be thought of as arguments to EVAL-DISPATCH. There are three special values of didnt_get_output: UNBOUND we don't want an output NIL either output or no output is okay (from .MAYBEOUTPUT) (NIL . NIL) this is a macro, and must output, but not for anyone in particular 3.2b Tailforms handled as embedded calls Sometimes it's not good enough to handle STOP and OUTPUT as tail calls. Consider the Logo instruction repeat 5 [... if :x<0 [output 3] ...] This is legal inside a procedure body; the OUTPUT outputs from the enclosing user-defined procedure. But the evaluation of the expression that is the second input to REPEAT isn't a tail evaluation, since after it's done the repeat count must be updated and tested. So when :X is negative we can't just tail-eval the 3; that would return 3 as the value of the entire repeated expression sequence. This OUTPUT is a nonlocal exit, comparable to a THROW. So in this case we actually do call a primitive procedure named OUTPUT. (Never mind for now what OUTPUT does in this case; we'll get back to nonlocal exit later.) 3.2c Caller-status arguments to eval-sequence and eval-dispatch To make all this work, we need an extra argument to EVAL-SEQUENCE and an extra argument to EVAL-DISPATCH; these must be saved and restored with the other evaluator registers. The extra argument to EVAL-DISPATCH is didnt_get_output, mentioned earlier. The extra argument to EVAL-SEQUENCE is named val_status and is an integer containing some combination of the following flag bits: #define VALUE_OK 1 /* [instr instr instr exp] */ #define NO_VALUE_OK 2 /* [instr instr instr instr] */ #define OUTPUT_OK 4 /* [instr instr OUTPUT exp ...] */ #define STOP_OK 8 /* [instr instr STOP ...] */ #define OUTPUT_TAIL 16 /* not [repeat n [... output ...]] */ #define STOP_TAIL 32 /* not [repeat n [... stop ...]] */ Here are all the ways in which EVAL-SEQUENCE is called, with the corresponding values of val_status: entry to evaluator (from Logo prompt) NO_VALUE_OK body of procedure when output wanted OUTPUT_OK | OUTPUT_TAIL body of procedure when no o/p wanted NO_VALUE_OK | STOP_OK | STOP_TAIL body of procedure for .MAYBEOUTPUT NO_VALUE_OK | STOP_OK | STOP_TAIL | OUTPUT_OK | OUTPUT_TAIL RUNRESULT [sequence] VALUE_OK | NO_VALUE_OK | OUTPUT_OK[**] | STOP_OK[**] REPEAT n [sequence] NO_VALUE_OK | OUTPUT_OK[*] | STOP_OK[*] APPLY [sequence] args, output wanted VALUE_OK APPLY [sequence] args, no o/p wanted NO_VALUE_OK | OUTPUT_OK[*] | STOP_OK[*] [*] means that these flags are on only if they were on for the enclosing expression sequence. [**] means that OUTPUT and STOP are actually not okay inside a RUNRESULT, but the RUNRESULT handler lets STOP or OUTPUT be called and then detects and reports the error afterwards. You may wonder why RUNRESULT and REPEAT are special cases here, but not RUN, IF, and IFELSE. We'll discuss that shortly. 3.2d Detecting errors before they happen Sometimes it's not good enough to detect an error after evaluation. These situations are obscure. For example: to blorp :x repeat 5 [pr :x if :x<0 [op 3] make "x :x-1] end ? blorp 2 2 1 0 -1 You don't say what to do with 3 The OP in BLORP would be legal if the top-level instruction had been PRINT BLORP 2. When we see the OP, we know that no output is wanted, but we have to evaluate the input expression (3) anyway, just in case it prints something or has some other side effect. Because the OP is nested inside a REPEAT, it turns out, we can't just let the error be detected downstream; we have to flag the error without letting the REPEAT handler continue. So we non-tail-evaluate the 3, then after the evaluation returns, we flag the error. (Look at label op_want_stop in eval.c to see how this works.) This code is used for all cases of OUTPUT when STOP was wanted, but it's only really necessary in the REPEAT case. 3.3 Macros In the SICP evaluators, IF is a special form. This means that the evaluation of the consequent or alternative of an IF expression happens through a string of tail calls within the evaluator: eval -> eval-if -> eval (of consequent or alternative) Thus, if the entire IF expression is in tail position, the consequent or alternative is also tail-evaluated. (Of course the predicate argument to IF can't be tail-evaluated, because the job of IF isn't finished when that argument has been evaluated; the result must still be tested for true or false, and either the consequent or the alternative must be evaluated.) SICP handles COND differently; instead of directly tail-evaluating the actions of the successful COND clause, the entire expression is rewritten as an IF expression, which is then evaluated: (define (eval exp env) ; SICP page 365 (cond ... ((cond? exp) (EVAL (COND->IF EXP) ENV)) ...)) COND->IF is a rewriting procedure that returns a new expression, which is used as argument to another (tail-recursive) call to EVAL. They could have handled IF as a sort of rewriting, also, except that the rewriting procedure would need access to the environment: (define (if->exp exp env) ; compare with EVAL-IF, SICP p. 367 (if (true? (eval (if-predicate exp) env)) (if-consequent exp) (if-alternative exp))) The general name for such a rewriting procedure is a macro. 3.3a Why the MCE uses special forms Special forms in the MCE have two purposes. First, they delay (IF) or prevent (QUOTE) evaluation of subexpressions; second, they have access to the caller's environment (DEFINE, SET!). Neither of these issues comes up in quite the same way in a Logo interpreter. Delayed evaluation in Logo is done by quoting (including " and [] notations); this is why we say ifelse :x < 0 [print "negative] [print "positive] with brackets around the PRINT instructions, but not around the :X < 0 expression. [In Scheme, parentheses would be used for all three subexpressions: (if (< x 0) (display 'negative) (display 'positive)) and it's the status of IF as a special form that prevents the early evaluation of the last two subexpressions.] Access to the caller's environment isn't a problem for Logo primitives because of dynamic scope; the evaluator's ENV variable, which is a global variable in the C program, contains the correct environment when any primitive is used. So Logo's equivalent to DEFINE and SET!, namely MAKE, is an ordinary primitive. As a result, Logo has only two special forms: TO, because of its strange notation, and .MAYBEOUTPUT, because its "input" expression need not return a value. (This is the above-the-line view.) In principle there's nothing special about RUN, IF, IFELSE, REPEAT, or RUNRESULT. This simple view of the world doesn't quite hold below the line, though, because of tail call elimination. We want to foo if ... [output tail-call-this] ... end to be a tail call, so we can't recursively call the evaluator from inside the IF primitive. 3.3b Using rewriting instead of special forms Instead we make IF a macro -- that is, a rewriting procedure. If the condition is satisfied, it outputs its second input; if not, it outputs the empty list. (IFELSE outputs either its second or its third input; RUN just outputs its input.) The evaluator recognizes (in APPLY-DISPATCH) that a macro is being invoked; instead of just returning what the procedure returns, it splices the return value into the sequence of unevaluated expressions. What "splices" means, more precisely, is unev=(append val unev) [If you're reading carefully you'll notice that I'm having APPLY do something to a sequence of expressions, whereas such a sequence exists only in EVAL-SEQUENCE. Actually APPLY pushes on the control stack a return address of macro_return (so that every call to a macro is a non-tail call, by the way); when we get there, the C instruction stopping_flag = MACRO_RETURN; is executed. Back in EVAL-SEQUENCE, this flag is noted, and that's where the splicing is done. A further complication is that if the macro was in fact called from tail position, we won't return to EVAL-SEQUENCE, which tail-called EVAL-DISPATCH, so instead macro_return has to go to begin_seq (which goes to eval_sequence) itself. If the macro is called when an argument was expected, it must return exactly one expression; the MACRO_RETURN flag is caught at accumulate_arg, and the returned expression is sent to eval_dispatch.] Why not just treat RUN, IF, and IFELSE as special forms internally (that is, handle them as special cases within EVAL-DISPATCH) even though we tell users they're ordinary procedures? Two reasons: 1. The UCBLogo approach allows these to be separate C procedures, outside of eval.c, instead of making the core evaluator know about them. 2. Once we have the macro capability, we can fairly easily make it available to users, through the .MACRO primitive. (Note: As of R5RS, Scheme has a standard rewriting capability available to users, more complicated than ours, but with the same purposes.) 3.3c Logo continuations This is the entire story for RUN, IF, and IFELSE. As we've seen before, REPEAT and RUNRESULT are more complicated, because they both have more work to do after their expression-sequence arguments are evaluated. REPEAT must count down its repetition count and test for zero. RUNRESULT modifies the result of the evaluation, returning [] instead of UNBOUND and [FOO] instead of FOO. REPEAT and RUNRESULT are still considered macros, but they don't return rewritten expressions. Instead they return a special internal data type, called a "continuation." (The name is inspired by Scheme's continuations, and it's a reasonably appropriate name because it does embody "what to do next," but it's not an exact analog of Scheme continuations.) A continuation is a pair whose car is a (representation of a) label within the evaluator, and whose cdr is whatever data the code at that label expects (this generally means the inputs to the macro). The code at macro_return recognizes that the return value was a continuation; it sets VAL to the cdr of the continuation and jumps to the label specified in the car. Since most of the implementation of these Logo primitives is buried inside the core evaluator, they are similar to the special forms of the SICP evaluator. The difference is that they are recognized through the same table lookup used for ordinary procedures, rather than by special tests within EVAL-DISPATCH. GOTO and CATCH are also macros with continuations. GOTO doesn't take an expression sequence as an input; the sense in which it's a rewriting procedure is that it "rewrites" its input into the expression sequence consisting of the part of the current user procedure's body starting at the corresponding TAG and continuing until the end. In this case the resulting expression sequence replaces the previous value of UNEV instead of being spliced into it. We'll discuss CATCH shortly, under the heading of nonlocal exit, but we're not quite ready for that. 3.4 Dynamic scope It's rather a shame, I think, that the second edition of SICP no longer even mentions dynamic scope, so I have to explain what it means before discussing how it's implemented. See also _Computer Science Logo Style_ vol 1 page 49 on dynamic scope, and CSLS vol 3 page 183 on lexical scope. Within a procedure body, how do we handle references to variables that are not local to that procedure itself? In C, any variable reference within a procedure must be either to a variable local to that procedure or to a global variable; one procedure can never refer to another procedure's local variables. In Scheme, one procedure can be defined inside the body of another; the inner procedure can refer to local variables belonging to the outer one. This is called *lexical scope*. [C is lexically scoped, too, but trivially so, since there is no nesting of procedure definitions.] In Logo, when one procedure *invokes* another, the invoked procedure can refer to local variables belonging to the caller. This is called *dynamic* scope. The following would print DYNAMIC in a dynamically-scoped Scheme, but prints LEXICAL in (the actual) lexically-scoped Scheme: (define (a x) (define (b x) (c)) (define (c) x) (b 'dynamic)) (a 'lexical) Focus on the reference to X in the body of procedure C. Since C was invoked by B, its *dynamic environment* is C -> B -> A -> global whereas its *lexical environment* is C -> A -> global because C was defined inside A, not inside B. 3.4a Reasons for lexical scope Why does almost everyone prefer lexical scope? (I prefer it, too, under many circumstances, by the way.) Three reasons: 1. A complier can produce faster compiled code for a lexically scoped language, because the compiler knows which variable is meant by a variable reference without actually running the program. The rules refer only to the physical position of the procedure's definition within the program, not to who calls whom. In a dynamically scoped language, variable references can't be resolved until the program is actually running; the same reference might mean two different variables on two calls to the same procedure. 2. Lexical scope avoids "name capture" bugs, in which the programmer accidentally uses the same name for two different purposes, so that a procedure thinks it's getting one variable X when it really ends up getting a different variable X because the name was reused in a procedure that (directly or indirectly) invokes it. This is the reason most often cited. For the most part I think people who name variables X deserve what they get, but name capture does come up as a problem when writing higher-order functions in Logo, if the names of inputs to the higher-order function are common words that might appear in a template. See CSLS vol 2 page 204. 3. In Scheme, in which lexical scope is combined with first-class procedures (i.e., LAMBDA), that combination allows for persistent local state variables, and therefore for object-oriented programming, without any OOP-specific language syntax. See SICP 3.1 and 3.2 for details. 3.4b Reasons for dynamic scope Why, then, does Logo use dynamic scope? Four reasons: 1. It allows for a simple notation for higher-order functions, using first-class expressions rather than first-class procedures. We can say to add.suffix :suffix :words output map [word ? :suffix] :words end The expression template [WORD ? :SUFFIX] is evaluated inside MAP, not inside ADD.SUFFIX, and yet it has access to the latter's local variable SUFFIX. In Scheme we'd have to use LAMBDA, a more intimidating notation. 2. Some of us think that dynamic scope is just easier for kids and/or novice programmers to think about. If a variable exists, it's available for use, unless shadowed by a more recently created variable of the same name. You don't have to think about scope at all, really. 3. Debugging support is more natural. You can tell Logo to PAUSE whenever there's an error. You then have a Logo prompt, to which you type ordinary Logo instructions, but all the relevant variables are available for inspection. This is important because the actual error in your program might not be in the procedure that died, but rather in the caller of the caller of the caller of that procedure. With dynamic scope, the variables of the erroneous procedure are visible. You don't have to learn special debugging commands that mean "switch to a different environment." 4. It allows for a programming style using "semi-global" variables that are local to a top-level procedure. For example, a program to draw a complicated picture might have a SIZE input, which is then used by its subprocedures, sub-subprocedures, etc. 3.4c Shallow binding There's an efficiency problem with dynamic scope and recursive procedures. Consider the following modification of a common example: make "one 1 to fact :n if :n = 0 [output :one] output :n * fact :n-1 end Suppose we ask for FACT 5. This gives rise to an (embedded) recursive call for FACT 4, which calls FACT 3, which calls FACT 2, which calls FACT 1, which calls FACT 0, which says OUTPUT :ONE. We have to look up the variable name ONE. Is it local to the FACT 0 environment? No. So we look in the dynamically enclosing environment, for the FACT 1 call. Is it there? No, so we look in the FACT 2 environment, the FACT 3 environment, the FACT 4 environment, the FACT 5 environment, and finally the global environment, which is where we find it. This is quite time-consuming, and would be even more so if we wanted the factorial of 100. Here's the solution. Instead of putting new local bindings in a newly created environment frame, and linking that to an enclosing environment, as in SICP 3.2 and 4.1.3, we instead keep the currently active bindings in a single global table. (Since this table is used for every variable reference, we work hard at making it efficient, namely by using a hash table rather than the linear lists of SICP environments.) We still create new frames for procedure calls, but what we put in the new frames are *saved* bindings, the ones we replaced in the global table for our new local variables. These frames are used only when the called procedure returns; we restore the previous state of the global table from the saved values. This is called *shallow binding*. The implication of this technique is that every variable reference, local or global, takes constant time. The cost is that returning from a procedure call takes time proportional to the number of local variables in the procedure. Since all symbols are looked up in the global symbol table, there is no ENV register in the Logo evaluator. Instead there are two registers pointing to a stack of saved values. var_stack points to the head of the stack, where new entries are added; var points to the beginning of the current frame, so that bindings between var and var_stack are the ones that should be restored when an embedded call to eval_dispatch returns. 3.5 Nonlocal exit Despite the proper handling of tail calls, a typical program still gives rise to several nested calls to EVAL-DISPATCH. Ordinarily these are "unwound" one by one, as (Logo) procedures return values. But sometimes we want to unwind several such recursive evaluations at once. The prototypical case is a call to THROW that appears several recursive evaluations below the corresponding CATCH. Were it not for shallow binding, we could in fact leapfrog over several nested evaluations at once, just throwing out their local information, sort of like setjmp/longjmp in C. But instead we must restore all of the saved variable bindings, in the correct order, so we have to let each of the nested EVAL calls return to its caller. But we don't want those intermediate levels to keep computing; the whole point of THROW is to avoid completing some partial evaluations of expression sequences. We need some way to tell EVAL-SEQUENCE to return right away, without evaluating more expressions. This is done using another evaluator register, called stopping_flag, which should be viewed as part of the return value from EVAL. It has the following possible values: RUN program is running STOP non-tail STOP was seen OUTPUT non-tail OUTPUT was seen THROWING THROW was seen MACRO_RETURN a macro is returning a rewritten expression (see 3.3b) Logo.h defines shortcuts to test some of these states: #define NOT_THROWING (stopping_flag != THROWING) #define RUNNING (stopping_flag == RUN) #define STOPPING (stopping_flag == STOP) It's NOT_THROWING because that turns out to be the most commonly used test. The very first thing EVAL-SEQUENCE does is if (!RUNNING) goto fetch_cont; so that if we've seen a THROW (or a non-tail STOP or OUTPUT, as explained in 3.2c) we just return without further evaluation of this sequence. The continuation for CATCH calls EVAL-SEQUENCE for its second argument, then if stopping_flag is THROWING and throw_node, a global variable, is equal to its first argument, it sets stopping_flag back to RUN. (THROW can take an optional second input, which is a value for the corresponding CATCH to return. This works by setting output_node, another global variable, to the thrown value. Non-tail OUTPUT also sets output_node.) The variables throw_node and output_node don't have to be saved and restored around embedded EVAL calls, because only one THROW or OUTPUT can be active at a time. If CATCH catches THROW, who catches non-tail STOP or OUTPUT? EVAL-SEQUENCE does, after restoring registers and before looping for the next expression. And so does REPEAT, so that it won't try repeating its input any more. 3.6 Lack of parentheses delimiting procedure calls The SICP evaluators see an expression sequence as a list in which each element is one complete expression, because every non-atomic Scheme expression is enclosed in parentheses. So, for example, how many arguments are in this procedure call? One less than the number of elements in the list. Easy. Logo has a harder time, because expressions need not be parenthesized, and also because of infix arithmetic notation. The Logo evaluator sees a procedure name, realizes that this is the beginning of a procedure call, and must then look up the procedure in order to know how many input subexpressions to evaluate. Furthermore, some procedures take a variable number of inputs, so the grouping may depend on the use of optional parentheses. This grouping of tokens into subexpressions is slow, and it's wasteful to do it repeatedly for expression sequences in the body of a procedure. So UCBLogo does it once, the first time the procedure is called, and saves the result. In effect each Logo procedure is translated into a Scheme procedure, as if it had been typed in with every subexpression parenthesized and no use of infix. 3.6a Tokenization But I've skipped a step. Even the division of the characters on a line into tokens is problematic. Here's the classic problem: Should the hyphen character automatically be a token by itself? We'd like print 5-2 to work, and so we'd like the 5-2 to be understood as three tokens: 5, -, 2. On the other hand, we'd like print first [555-1212 642-8311 868-9827] to print 555-1212, not 555. There are three ways to resolve this dilemma: "Old LCSI" style: the second example prints 555. This is what Apple Logo, IBM Logo, and other early LCSI products do. "New LCSI" style: the first example gives the error I don't know how to 5-2 This is what Logowriter and later LCSI products do. "Terrapin" style: both examples work as desired. I apologize to non-Americans for naming these after the main USA Logo vendors, but that's the history I know best. UCBLogo uses Terrapin-style tokenization, which I think is clearly the best choice. To make it work, there are two sets of tokenization rules, which I call PARSE and RUNPARSE. These are in fact the names of UCBLogo primitives: ? show parse "5-2 [5-2] ? show runparse "5-2 [5 - 2] When a line is read (from keyboard or file), it is parsed. When and if the line is evaluated, it's runparsed -- but even then, text within square brackets is not runparsed. (Such text will be runparsed if it is ever used as input to RUN and friends.) The precise rules are given in more detail in the "Tokenization" section of the UCBLogo User Manual. 3.6b Monadic and dyadic minus The minus sign (-) is particularly thorny for tokenization because it has three different meanings: (1) If it begins a token, and the following character is a digit, then it is part of a negative number token. (2) If it follows an open parenthesis or bracket, or if it follows a space and is not followed by a space, then it is the monadic (one-operand) negation operator. (3) Otherwise, it is the dyadic subtraction operator. The part about spaces in (2) above comes from the problem that function argument expressions are separated by spaces, not commas as in most programming languages. This, along with infix arithmetic, gives rise to an ambiguity. Does foo a - b represent a call to a one-argument function with A minus B as the argument, or a call to a two-argument function with A as the first argument and negative B as the second? The UCBLogo rule is this: foo a-b ; dyadic subtract foo a - b ; dyadic subtract foo a -b ; monadic negate Once runparsing is done, the spacing information is lost. So when a monadic negate is seen during runparsing, it is replaced by the two tokens "0" and "--": ? show runparse [a -b] [a 0 -- b] The double minus sign is an infix operator that represents subtraction but has the highest infix binding strength, so that a * 0 -- b means a*(0-b), not (a*0)-b. It's an undocumented feature that users can type |--| to get this tightly-binding subtraction operator; if they type "--" without vertical bars, they get two separate "-" tokens. 3.6c More on runparsing Once a list has been runparsed, we don't want to have to do it again, so we want to replace the old list value with the new one. But we can't quite do that, because the non-runparsed version might still be needed: to foo :x repeat 4 :x show :x end ? foo [print 5-2] 3 3 3 3 [print 5-2] We wouldn't want the last line to look like [print 5 - 2] but we also don't want to runparse the list four times. The solution is somewhat of a kludge. In UCBLogo every "pair" (as created by CONS) actually contains three components, not two: the car, the cdr, and the "object." At first the list [print 5-2] looks like this: Type: PAIR car: print cdr: [5-2] ; of course this is itself a PAIR with car 5-2 object: NIL After runparsing, it looks like this: Type: RUNPARSE car: print cdr: [5-2] object: [print 5 - 2] The car and cdr of this runparsed list (the parts seen by ordinary procedures such as SHOW) are unchanged, but the object is another list, the runparsed version. If we ask to runparse this list again, the runparse() procedure will notice that its argument is of type RUNPARSE and just return it unchanged. A defect of this approach is that if for some reason we want to runparse the cdr of the list, we have to do it from scratch, but that rarely happens. (Another defect, since all Logo nodes are the same size, is that even ordinary pairs have to have room for an object field, even though most of these fields are unused. This is a big, although constant factor, waste of memory.) 3.6d Treeification Now we're ready to return to the problem posed at the beginning of 3.6: The form in which we *really* want this instruction list is [print [- 5 2]] That is, we want it fully parenthesized, with prefix operators. (I'm using the word "parenthesized" because that's traditional, but of course what we really want has neither parentheses nor square brackets, but rather list structure with sublists.) Note, by the way, that the Logo instruction print [- 5 2] doesn't subtract 2 from 5! This instruction, in treeified form, looks like [print "[- 5 2]] except that the quotation mark isn't really there, either; it's a node of type QUOTED. The important point is that unlike runparsing, treeification gives rise to something that is *not* in Logo surface syntax, so we don't show it to users; there is no TREEIFY primitive. Treeification is implemented similarly to runparsing; the result is this node: type: TREE car: print cdr: [5-2] object: [print [- 5 2]] 3.6e Procedure bodies Since a line can contain more than one instruction, and since an instruction can be continued onto more than one line, why bother having the concept of lines at all? Why not, like Scheme, treat newlines the same as spaces? That's what Microworlds does, so it's clearly possible. The only reason to maintain the concept of lines as important is for the sake of the user interface. When an error occurs inside a procedure body, the UCBLogo error message includes the line on which the error happened. Also, the STEP command causes a procedure to be run one line at a time. So we might represent a procedure body as a list of lines, each of which is a list of (treeified, eventually) expressions. But then we couldn't use a procedure body as argument to EVAL-SEQUENCE, which expects a list of expressions, not a list of lists of expressions. So a procedure body is a list of expressions, but some of the pairs making up the spine of the list are of type LINE, namely, the first such pair of each line of the body. In these pairs, the object field points to the text of the line (parsed, but not runparsed or treeified). When EVAL-SEQUENCE notices a LINE-type pair, it sets the evaluator register this_line to the pair's object. 3.6f Changing a procedure's arity The *arity* of a procedure is the number of inputs it takes. In UCBLogo, the procedure's arity is actually three numbers: the minimum, default, and maximum number of inputs. In this section we focus on the default number. Consider the following example: to a print (sentence b 1 2 3 4 5) end to b :x :y output :x + :y end When we call A, it should print 3 3 4 5 The first time we call A, its one body line is treeified, with this result: [print [sentence [b 1 2] 3 4 5]] Now suppose we redefine B: to b :x :y :z output :x + :y end We have change B's arity, and so the treeification of A is now incorrect! It should be re-treeified to [print [sentence [b 1 2 3] 4 5]] But if we check the arity of every procedure every time we call A, we've lost the efficiency advantage we gained by treeification. The perfect solution would be to maintain a data structure for each procedure indicating which procedures depend on its arity. Then, if the procedure is redefined in a way that changes the arity, we could re-treeify exactly those procedures that depend on it. But this would be a lot of trouble; UCBLogo, like several other Logo implementations, does something simpler. The principle is that it's pretty rare to redefine a procedure in a way that changes its arity, and so it's okay if doing that slows things down a lot. What's important is to keep the common case -- no redefinition -- fast. The global variable the_generation contains a pair. Its contents are unimportant; it's created with cons(NIL, NIL). What's important is that it's distinct from any other pair. Whenever an existing procedure is redefined in a way that changes its arity, a new pair replaces the_generation. Every LINE node in a procedure body contains a pointer to the pair that was in the_generation at the time this line was treeified. Whenever this line is run, its generation pair is compared with the_generation. If they're not equal, it means that some procedure has changed arity since the line was treeified, and so the line is re-treeified. This means that every line of every procedure must be reparsed after an arity change! This produces a noticeable slowdown. But it doesn't happen often. (Defining a new procedure doesn't require changing the_generation, because a procedure can't be called until all its subprocedures are defined. Remember that the body is treeified when the procedure is first called, not when it's defined. Logo won't save the treeification of a procedure if it has undefined subprocedures.) 4. Data structures and types ---------------------------- The basic unit of storage in Logo is the node. Every user-visible data type (word, number, list, array) and many internal types (runparse, tree, primitive, line, etc.) are stored in nodes. A node contains the following fields: type flags node_type info for garbage collector my_gen, gen_age, mark_gc, next, oldyoung_next other fields by type The type field is a collection of bits, not just an enum, so that tests can easily be made for categories. For example, many types are special-purpose pairs, so they all have the NT_LIST bit set. Numbers, strings, quoted strings, etc., all have the NT_WORD bit set. The bit NT_AGGR stands for "aggregate," which includes lists and arrays. The types are defined in logo.h. 4.1 Pair-based types The ordinary pair is of type CONS. The other pair types are RUN_PARSE, TREE, LINE, and CONT (continuation), all of which were discussed in part 3. The empty list is represented by a zero pointer, but nodetype(0) returns the type PNIL. The constructor for pairs is cons(x,y). The selectors are car, cdr, caar, cadr, cdar, and cddr. (Combined forms more than two deep are not provided in logo.h.) Ordinary pairs don't use the object field; special pairs are generally first made with cons and then mutated with setobject(pair,val). 4.2 Numeric types Numbers are a kind of word (because you can examine their digits with FIRST etc.), so the numeric type codes include the NT_WORD bit. The numeric types are INT (32-bit integer) and FLOATT (sic, because FLOAT is defined in some C header file or other; 64-bit floating point). Someday I'll get around to bignums (arbitrary-precision integers). The constructors are make_intnode and make_floatnode; the selectors (to get back the underlying numeric data) are getint and getfloat. Note that a string containing all digits counts as a number above the line! Such strings of digits are created by operations such as butfirst "x123 There is a procedure cnv_node_to_numnode that takes a node as its argument and, if possible, returns an equivalent INT or FLOATT node. (The argument may already be a numeric type, in which case it is returned unchanged.) If the argument can't be construed as a number, the procedure flags a BAD_DATA error, so after calling it, you should check if (NOT_THROWING) {...} for whatever computation uses the number. 4.3 String types There are three string types: STRING, BACKSLASH_STRING, and VBAR_STRING. 4.3a Internal structure of a string The string format is based on the goal of making FIRST, LAST, BUTFIRST, and BUTLAST quick for words. The characters themselves are not in the string node, because nodes have a fixed size and strings can be of any length. Instead, the characters are in a block allocated with malloc() in the following format: struct string_block { unsigned FIXNUM str_refcnt; char str_str[1]; /* This array will be of variable length really */ }; The string_block needs a reference count because different word nodes may point to substrings of it. When a word node is garbage collected, the reference count of its string_block is decremented; when the count reaches zero, the block is freed. The word node itself has three fields: #define getstrptr(node) ((node)->n_str) #define getstrlen(node) ((node)->n_len) #define getstrhead(node) ((node)->n_head) (These lines are from logo.h, which has getters and setters for all the node types.) The strptr is a pointer to the first character of the word (not necessarily the first character of the string_block). The strlen is the number of characters in the word. The strhead is a pointer to the string_block, as returned by malloc(). There is a single empty word node, pointed to by the variable Null_Word. Logo takes pains not to create any other empty word nodes, so that all empty words will be EQ? and not merely EQUAL?, to simplify comparisons. 4.3b How to create a string node Words are usually created with NODE *make_strnode(char *strptr, struct string_block *strhead, int len, NODETYPES typ, char *(*copy_routine)()) This constructor is used in two different ways. If you already have a string_block containing the characters you need, and just want to select a substring of it, you say make_strnode(strptr, strhead, len, STRING, ) because the last argument isn't used. If you have the characters in a temporary buffer and have to allocate a string_block for them, you say make_strnode(charptr, NULL, len, STRING, copy_routine) The copy routine is usually strnzcpy: char *strnzcpy(char *s1, char *s2, int n) { strncpy(s1, s2, n); s1[n] = '\0'; return(s1); } This is in logodata.c, along with various special-purpose ones with names like mend_strnzcpy that modify the copied characters in some way. For example, one version strips out comments and line continuation characters because in UCBLogo you can say ? make "foo "abc;comment ~ def ? print :foo abcdef 4.3c Including punctuation characters in words Sometimes users want to include in a word what would ordinarily be word-delimiting punctuation characters. There are two ways to do this: abc\ def backslash before special character |abc def| string of characters in vertical bars Unfortunately both the visible semantics and the underlying implementation of these has changed over time, so many names of procedures are now wrong. Originally there was only the backslash form, and it meant what vertical bars now mean. First, the above-the-line semantics: Backslashed characters are treated as non-punctuation when first seen, but if the word containing a backslashed character is runparsed, the character has its usual special meaning. By contrast, characters within vertical bars are never interpreted specially, even when runparsed. Originally, backslashed characters were special forever, and were specially marked to indicate this. The UCBLogo primitive BACKSLASHEDP checks for this special marking. Alas, backslashed characters are no longer specially marked; the backslash just gets them into the same word as their neighbors when the line is first parsed. This special marking now applies only to punctuation characters that were entered within vertical bars, so the name should be BARREDP or something like that. Now, the ugly below-the-line history. Originally, a punctuation character that was intended to be forever special was marked by having its parity bit set (0200, 0x80). This works in the USA because all the ASCII characters have codes less than 128. Therefore, UCBLogo uses functions setparity(char) -> same char with parity bit on clearparity(char) -> same char with parity bit off getparity(char) -> nonzero if char has parity bit set to manipulate these marked characters. Then European Logo users complained that Logo wasn't properly handling letters with accents, which, it turns out, are represented using ASCII codes greater than 128. The new approach uses otherwise-unused ASCII control characters, with codes less than 32 (040, 0x20, ASCII space). Some of the control characters are "format effectors": tab, backspace, formfeed, newline, return. But the others are pretty useless, and so UCBLogo uses them to represent "backslashed" (really vertical barred) punctuation characters. There are only barely enough of these unused codes for the Logo punctuation characters, though: space, tab, newline, ()[]+-*/=<>"\:;|{}~ (Don't be confused; tab is itself a control code, but backslashed-tab is a different control code!) The special node types BACKSLASH_STRING and VBAR_STRING are used if there are special characters within the word. In fact most of the interpreter doesn't worry about these types; the only important use is that compare_nodes() strips the "parity" from the characters in the strings before comparing them if either word is of either of these types. 4.4 Symbols Scheme distinguishes between a string (an array of characters) and a symbol (an indivisible atom that happens to have a printable name). Strings are for text manipulation; symbols are to name variables and the like. Logo, above the line, uses a single Word type that subsumes both of these purposes. Nevertheless, it's useful to maintain a distinction internally. When you want to find a procedure or variable in the symbol table, you don't want to spend time comparing strings letter by letter to find it. The internal equivalent of a Scheme symbol is called an "object" -- an unfortunate choice since we plan to add object-oriented programming to Logo. But for now, let's understand that the word "object" refers to this internal Logo data structure. An object is a list with the following elements: [canonical procedure value plist flags caseobj1 caseobj2 ...] The "canonical" element is a caseobj, which will be explained later. The procedure, value, and plist elements are the ones named by this symbol (the procedure FOO, the variable FOO, and the property list FOO, for example). These elements are UNDEFINED, UNBOUND, and NIL, respectively, if the symbol does not name a procedure, a variable, or a property list. The flags element is an INT node containing the following flags: #define PROC_BURIED 01 #define VAL_BURIED 02 #define PLIST_BURIED 04 #define PROC_TRACED 010 #define VAL_TRACED 020 #define PLIST_TRACED 040 #define PROC_STEPPED 0100 #define VAL_STEPPED 0200 #define PLIST_STEPPED 0400 #define PROC_MACRO 01000 #define PERMANENT 02000 The meaning of BURIED, TRACED, and STEPPED is explained in the user documentation of the Logo primitives BURY, TRACE, and STEP. (It is meaningless to step a property list, but the flag exists anyway because various primitives know that these flags come in groups of three.) PROC_MACRO means that the symbol's procedure is a macro; PERMANENT means that this symbol should not be deleted during garbage collection, even if it has no procedure, variable, or property list. (This feature is used, for example, for the special variables that users can set to control Logo's behavior, such as ERRACT and CASEIGNOREDP. Pointers to these symbols are kept in global variables so that Logo doesn't have to look them up in the symbol table each time they're used, so it's important that the symbol not be deleted and recreated.) The remaining elements are nodes of type CASEOBJ, for "case object." In Logo, names of procedures, variables, and property lists are case insensitive, so FOO and Foo and foo all name the same procedure. When a program is runparsed, all the words that might name procedures, etc., are turned from strings into symbols, so that when the program is run, the named procedures, etc., can be found quickly, by dereferencing pointers in the program, without string manipulation. But we want to remember the exact way the user typed the name, in case we print it. This may be clearer with an example. Consider these instructions: make "Foo 3 print "Foo In the first instruction, we really don't care that the user said Foo rather than FOO or some other capitalization, but in the second instruction, we want to print the word exactly as typed. But the parser doesn't know anything about the semantics of MAKE or PRINT, let alone some user-defined procedure that might do both. So we want to turn these strings into symbols, but we also want to remember the original strings. A case object is a pair whose car is a string and whose cdr is an object. Given a case object, we can dereference its car to print it, or dereference its cdr to find the procedure, variable, or property list that it names. Each object includes all of its case objects as elements, so that when we delete the object we can delete the CASEOBJs also. (This is therefore a circular structure, since the object points to the caseobj and the caseobj points to the object.) Each object also includes a "canonical caseobj," which is the one with all lower case letters; a canonical caseobj is created for every object even if the user never types the name that way. The canonical caseobj is used for case-independent comparisons. When an object is created, it is also entered into Logo's global environment, which is a hash table. The hash function is based on the canonical string. This process -- creating the object, creating the caseobj as spelled by the user, creating the canonical caseobj, and entering the object into the hash table -- is called *interning* the symbol. The procedure intern(word) takes a word of any type (number, string, caseobj, etc.) and returns the caseobj with the spelling used in the argument. If the word has already been interned, intern() finds the existing object in the hash table. If not, one is created. If the word has been interned, but not with this spelling (that is, not with this upper-lower-case pattern), a new caseobj is created that points to the existing object. Note that a caseobj is a pair, but it has NT_WORD on and NT_LIST off in its type identifier, because Logo primitives should treat it as a word, not as a list. 4.5 Quote and colon types When a line containing the notations "FOO or :FOO is parsed, these strings are converted to nodes of type QUOTE and type COLON, respectively. These nodes are pairs in which only the car is meaningful; it points to a caseobj of the word without the leading quote or colon. Like the CASEOBJ type, the QUOTE and COLON types are words above the line but pairs internally. 4.6 Arrays Like strings, arrays are represented as nodes that point to an external block of memory. Here are the selectors for array nodes: #define getarrdim(node) ((node)->n_dim) #define getarrorg(node) ((node)->n_org) #define getarrptr(node) ((node)->n_array) The array dimension is the number of elements in it. The array origin is the index used for the first element of the array (1 by default, often 0, but can be anything). The array pointer points to the actual data, which is a block of pointers to nodes. There is no need for a reference count in array blocks, because there are no primitives that extract a subarray; if you want one, you must allocate a new array and copy the desired elements manually. 4.7 Primitive procedures There are several node type codes for primitive procedures: PRIM, MACRO, TAILFORM, and INFIX. Macros are described in section 3.3; tailforms are in section 3.1; the infix operators are the usual + - * / =. All other primitives are of type PRIM. The fields of a primitive are #define getprimfun(node) ((node)->n_pfun) #define getprimmin(node) ((node)->n_pmin) #define getprimmax(node) ((node)->n_pmax) #define getprimdflt(node) ((node)->n_pdef) #define getprimpri(node) ((node)->n_ppri) Fun is a pointer to the C procedure that implements the primitive; min is the minimum number of inputs; max is the maximum number; dflt is the default number; pri is the priority of this primitive, used in treeification of expressions that involve infix operators. Multiplication and division are highest priority (tightest binding); then addition and subtraction; then comparisons; and lowest of all are prefix operators. The four numbers are stored as short (16-bit) integers, so that all five fields fit in no more space than the three pointers of a cons node. All primitive procedures are of C type NODE *foo(NODE *args) They are given a list of actual argument values and must return a (pointer to a) node, or UNBOUND if the Logo primitive should not return a value. 5. Garbage collector -------------------- This section is not a primer on garbage collection. A good general survey on this subject is Paul R. Wilson. Uniprocessor garbage collection techniques. In Proc of International Workshop on Memory Management in the Springer-Verlag Lecture Notes in Computer Science series., St. Malo, France, September 1992. http://www.cs.utexas.edu/users/oops/papers.html#gcsurvey Even before reading Wilson, read SICP 5.3 if you're a gc novice. UCBLogo uses a generational, mark-sweep garbage collector. When the interpreter needs to allocate a node, it calls newnode(), which looks for an available node. If no nodes are free, newnode() calls do_gc(), which disables pause and stop interrupts and calls gc(). But the main purpose of do_gc is that it allocates a lot of local variables, so that any register variables in its caller will be forced onto the C stack. Do_gc() and gc() take a Boolean argument, which is FALSE for a generational garbage collection and TRUE for a full garbage collection. Automatically triggered gc is generational; a full GC can be requested by the user (see the user documentation of the Logo GC command) and is implied by the use of the NODES operation, so that the in-use count shown to the user will be correct. 5.1 Node allocation All Logo data types are stored in fixed-size blocks of type (struct node), which is given the typedef name NODE. Logo allocates many of these nodes at a time; the number allocated at once can be set by the user (with the .SETSEGSIZE command), but is initially 2000 for DOS, 4000 for 68000 Mac, and 16,000 for other platforms. The global variable segment_list points to a linked list of segments; a "segment" is a contiguous block of nodes. The global variable free_list points to a linked list of unused nodes. There is only one free list, not one per segment. Segments are never deallocated, even if every node in the segment is free. A new segment is allocated only if a gc fails to free up enough nodes, so that Logo's total memory use doesn't grow unnecessarily. 5.2 The mark phase Marking a node can lead to several other nodes that should be marked. To keep track of these pending tasks, Logo uses a fixed-size stack, of size 4000 for DOS, 8000 for 68000 Mac, or 16,000 for other platforms. Long lists should not cause overruns of this stack; it's the depth of lists that matters. If the stack overflows, garbage collection stops, and the user is advised to save data and quit. (Logo maintains a small "reserve tank" of nodes so that this saving will be possible.) All node-valued global variables in the interpreter are marked first. This includes evaluator registers, some of which are not in individual C variables but in a (struct registers) block. The global variable Regs_Node is a node that points to this register block; the node itself is unused except by the garbage collector. Among the C globals are stack, which is the evaluator's data stack (a list of nodes, not a contiguous block), and var_stack, which is the stack of local procedure-call frames (containing shadowed bindings as explained in 3.4c above). Then the entries in Logo's global symbol table (the hash table) are marked. Finally, the C stack is examined. Since we don't know which entries in the stack are pointers to nodes, every value on the stack is examined to see if it could possibly be a pointer to a node. This is done by procedure valid_pointer(), which first compares the address with the position and size of each segment. If the value is within a segment, the procedure then sees whether it would address the beginning of a node within that segment. If so, the garbage collector assumes that the value is indeed a node pointer, and marks the node. This procedure is one of the places where optimizing C compilers tend to produce code that doesn't work. Some machines (DOS and 68000 Mac) have 32-bit addresses but require only 16-bit alignment. The garbage collector therefore, on those platforms, looks at overlapping 32-bit values. Also, stacks grow upward in some systems and downward in others; Logo tries to figure this out. (Almost the first thing main() does is to set the global variable bottom_stack to the address of its local variable exec_list; gc() compares this with the address of its own stack frame to determine the direction of growth.) This is a good place to look for problems when porting Berkeley Logo to a new processor or operating system. All of the above categories of marking are done only for nodes in the current generation. The garbage collector then looks for nodes in older generations that have been modified to point to newer nodes. To make this check possible, the list mutators (the C procedures setcar, setcdr, and setobject) check for old-to-young pointing as they do the mutation, and keep lists of these old-to-young-pointing nodes. 5.3 GCTWA If a single-generation gc doesn't yield enough free space, older generations are examined. When a full gc is required, Logo also performs a GCTWA (Garbage Collect Truly Worthless Atoms). Here's what that means: Ordinarily, every word read in a Logo instruction is entered into the symbol table, just in case it will become the name of a procedure, variable, or property list. Since the symbol table itself is marked, and since the symbol table points to all these symbols, the symbols are never found to be free in the mark phase. A GCTWA goes through the symbol table looking for entries that are not, in fact, the names of a procedure, variable, or property list. (A subtlety is that a symbol's value might be UNBOUND even though it is in fact a global variable, because the global binding might have been shadowed by a LOCAL command, creating a local variable that doesn't yet have a value. But this isn't a problem because in that case var_stack points to the symbol table entry, so it will be marked.) Some symbols have a PERMANENT flag associated with them, so that the entries won't be removed in GCTWA even if the names are unused; these are mainly for Logo special variables such as CaseIgnoredP. The first step in a gctwa is that all caseobj nodes are flagged; in the mark phase, mark() will not actually mark a flagged caseobj until it is called twice for the same caseobj. (The first call to mark() for a flagged caseobj just clears the flag; the second call does the normal mark operation.) This is because every caseobj is pointed to (directly or indirectly) by the hash table, and we want to know whether this caseobj is pointed to by something else, usually by appearing in the body of a procedure. After this special mark phase, the symbol table is examined for unused symbols. A symbol is used if it names a variable, procedure, or property list, or if one of its caseobj nodes has been marked. Unused symbols are removed from the symbol table. Finally, the mark phase is repeated so that non-caseobj nodes that are part of stale symbols won't be marked. 5.4 The sweep phase In addition to finding and freeing unused nodes, the sweep phase also promotes nodes that have survived a certain number of garbage collections to the next older generation. This promotion requires checking whether the node points to other nodes that are now younger than it is. If the sweep phase doesn't free enough nodes, it tries another generation. When all generations have been collected, if there still are not enough free nodes, Logo asks the operating system for another segment. If that fails, the user is notified. "Enough" is one of several tuning values defined in mem.c. Besides the size of a segment, there are three more: /* Number of times to collect at the current GC state before going to the next state. Basically the number of times a given generation is collected before its members are moved to an older generation */ #define gc_age_threshold 4 /* A new segment of nodes is added if fewer than freed_threshold nodes are freed in one GC run */ #define freed_threshold ((long int)(seg_size * 0.4)) /* The number of generations */ #define NUM_GENS 4 5.5 Per-node gc data Each node contains five words of information to support gc: int my_gen; /* Nodes's Generation */ /*GC*/ int gen_age; /* How many times to GC at this generation */ long int mark_gc; /* when marked */ struct logo_node *next; /* Link together nodes of the same age */ /*GC*/ struct logo_node *oldyoung_next; my_gen is a number in the range [0, NUM_GENS-1]. It is zero for newly allocated nodes, and increases as the node survives multiple GCs. gen_age is in the range [1, gc_age_threshold]. It is initially gc_age_threshold, and is decreased by 1 at each gc. When it hits zero, the node is promoted to a higher (older) generation, and gen_age is reset to gc_age_threshold. mark_gc is initially zero. To mark a node, it is set equal to current_gc, a counter that's incremented at each garbage collection. (If Logo runs long enough for four billion garbage collections, this won't work. :-) next is a pointer to another node in the same generation as this node; the generations are maintained as linked lists. oldyoung_next is NIL except for old nodes that point to younger nodes. Such nodes are linked together using this field. That's five words of gc information in a node that has four words of non-gc information! There has to be a better way, a project for the list of undone projects. ucblogo-5.5/eval.c0100644000161300001330000011364210271524335012034 0ustar bhdoe/* * eval.c logo eval/apply module dko * * Copyright (C) 1993 by the Regents of the University of California * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define WANT_EVAL_REGS 1 #include "logo.h" #include "globals.h" /* evaluator registers that need saving around evals */ struct registers regs; NODE *Regs_Node; int num_saved_nodes; /* node-value registers that don't need saving */ NODE *exp = NIL, /* the current expression */ *val = NIL, /* the value of the last expression */ *stack = NIL, /* register stack */ *numstack = NIL,/* stack whose elements aren't objects */ *parm = NIL, /* the current formal */ *catch_tag = NIL, *arg = NIL; /* the current actual */ NODE *var_stack = NIL, /* the stack of variables and their bindings */ *last_call = NIL, /* the last proc called */ *output_node = NIL, /* the output of the current function */ *output_unode = NIL; /* the unode in which we saw the output */ #define DEBUGGING 0 #if DEBUGGING #define DEB_STACK 0 /* set to 1 to log save/restore */ #define DEB_CONT 0 /* set to 1 to log newcont/fetch_cont */ #define do_debug(x) \ x(exp) x(unev) x(val) x(didnt_get_output) x(didnt_output_name) x(fun) #define deb_enum(x) \ ndprintf(stdout, #x " = %s, ", x); void vs_print() { FIXNUM vs = val_status; int i; static char *vnames[] = {"VALUE_OK", "NO_VALUE_OK", "OUTPUT_OK", "STOP_OK", "OUTPUT_TAIL", "STOP_TAIL"}; static char *names[] = {"RUN", "STOP", "OUTPUT", "THROWING", "MACRO_RETURN"}; if (!varTrue(Redefp)) return; printf("Val_status = "); for (i=0; i<6; i++) { if (vs&1) { printf(vnames[i]); vs >>= 1; if (vs != 0) printf("|"); } else vs >>= 1; if (vs == 0) break; } if (vs != 0) printf("0%o", vs<<6); printf(", stopping_flag = %s\n", names[stopping_flag]); } void debprint(char *name) { if (!varTrue(Redefp)) return; printf("%s: ", name); do_debug(deb_enum) vs_print(); printf("current_unode=0x%x, output_unode=0x%x\n",current_unode, output_unode); } #define debprint2(a,b) if (varTrue(Redefp)) ndprintf(stdout,a,b) #else #define debprint(name) #define debprint2(a,b) #define DEB_STACK 0 #define DEB_CONT 0 #endif #ifdef HAVE_TERMIO_H #include #else #ifdef HAVE_SGTTY_H #include #endif #endif #if DEB_STACK NODE *restname, *restline; #define save(register) ( debprint2("saving " #register " = %s ", register), \ push(register, stack), \ push(make_intnode(__LINE__), stack), \ debprint2(" at line %s\n", car(stack)), \ push(make_static_strnode(#register), stack) ) #define restore(register) ( restname = car(stack), pop(stack), \ restline = car(stack), pop(stack), \ register = car(stack), pop(stack), \ ( (strcmp(getstrptr(restname), #register)) ? (\ debprint2("*** Restoring " #register " but saved %s",\ restname), \ debprint2(" at line %s! ***\n", restline) \ ) : 0), \ debprint2("restoring " #register " = %s ", register), \ debprint2(" at line %s\n", make_intnode(__LINE__)) ) #define save2(reg1,reg2) ( save(reg1), save(reg2) ) #define restore2(reg1,reg2) ( restore(reg2), restore(reg1) ) #else #define save(register) push(register, stack) #define restore(register) (register = car(stack), pop(stack)) #define save2(reg1,reg2) (push(reg1,stack),stack->n_obj=reg2) #define restore2(reg1,reg2) (reg2 = getobject(stack), \ reg1 = car(stack), pop(stack)) #endif /* saving and restoring FIXNUMs rather than NODEs */ #define numsave(register) numpush(register,&numstack) #define numrestore(register) (register=(FIXNUM)car(numstack), numstack=cdr(numstack)) #define num2save(reg1,reg2) (numpush(reg1,&numstack),numstack->n_obj=(NODE *)reg2) #define num2restore(reg1,reg2) (reg2=(FIXNUM)getobject(numstack), \ reg1=(FIXNUM)car(numstack), numstack=cdr(numstack)) #if DEB_CONT #define newcont(tag) debprint("Newcont = " #tag); \ numsave(cont); cont = (FIXNUM)tag #else #define newcont(tag) (numsave(cont), cont = (FIXNUM)tag) #endif /* These variables are all externed in globals.h */ CTRLTYPE stopping_flag = RUN; char *logolib, *helpfiles, *csls; FIXNUM dont_fix_ift = 0; /* These variables are local to this file. */ static int trace_level = 0; /* indentation level when tracing */ /* These first few functions are externed in globals.h */ void numpush(FIXNUM obj, NODE **stack) { NODE *temp = newnode(CONT); /*GC*/ temp->n_car = (NODE *)obj; temp->n_cdr = *stack; *stack = temp; } /* forward declaration */ NODE *evaluator(NODE *list, enum labels where); /* Evaluate a line of input. */ void eval_driver(NODE *line) { evaluator(line, begin_line); } /* Evaluate a sequence of expressions until we get a value to return. * (Called from erract.) */ NODE *err_eval_driver(NODE *seq, BOOLEAN recoverable) { val_status = (recoverable ? VALUE_OK : NO_VALUE_OK) | (val_status & (OUTPUT_OK|STOP_OK)); return evaluator(seq, begin_seq); } /* The logo word APPLY. */ NODE *lapply(NODE *args) { return make_cont(begin_apply, args); } /* The logo word ? . */ NODE *lqm(NODE *args) { FIXNUM argnum = 1, i; NODE *np = qm_list; if (args != NIL) argnum = getint(pos_int_arg(args)); if (stopping_flag == THROWING) return(UNBOUND); i = argnum; while (--i > 0 && np != NIL) np = cdr(np); if (np == NIL) return(err_logo(BAD_DATA_UNREC,make_intnode(argnum))); return(car(np)); } /* The rest of the functions are local to this file. */ /* Warn the user if a local variable shadows a global one. */ void tell_shadow(NODE *arg) { if (flag__caseobj(arg, VAL_STEPPED)) err_logo(SHADOW_WARN, arg); } /* Check if a local variable is already in this frame */ int not_local(NODE *name, NODE *sp) { for ( ; sp != var; sp = cdr(sp)) { if (compare_node(car(sp),name,TRUE) == 0) { return FALSE; } } return TRUE; } /* reverse a list destructively */ NODE *reverse(NODE *list) { NODE *ret = NIL, *temp; while (list != NIL) { temp = list; list = cdr(list); setcdr(temp, ret); ret = temp; } return ret; } /* nondestructive append */ NODE *append(NODE *a, NODE *b) { if (a == NIL) return b; return cons(car(a), append(cdr(a), b)); } /* nondestructive flatten */ NODE *flatten(NODE *a) { if (a == NIL) return NIL; return append(car(a), flatten(cdr(a))); } /* Reset the var stack to the previous place holder. */ void reset_args(NODE *old_stack) { for (; var_stack != old_stack; pop(var_stack)) { if (nodetype(var_stack) & NT_LOCAL) setflag__caseobj(car(var_stack), IS_LOCAL_VALUE); else clearflag__caseobj(car(var_stack), IS_LOCAL_VALUE); setvalnode__caseobj(car(var_stack), getobject(var_stack)); } } NODE *bf3(NODE *name) { NODE *string = cnv_node_to_strnode(name); return make_strnode(getstrptr(string)+3, getstrhead(string), getstrlen(string)-3, nodetype(string), strcpy); } NODE *deep_copy(NODE *exp) { NODE *val, **p, **q; FIXNUM arridx; if (exp == NIL) return NIL; else if (is_list(exp)) { val = cons(deep_copy(car(exp)), deep_copy(cdr(exp))); val->n_obj = deep_copy(exp->n_obj); settype(val, nodetype(exp)); } else if (nodetype(exp) == ARRAY) { val = make_array(getarrdim(exp)); setarrorg(val, getarrorg(exp)); for (p = getarrptr(exp), q = getarrptr(val), arridx=0; arridx < getarrdim(exp); arridx++, p++) *q++ = deep_copy(*p); } else val = exp; return val; } int in_eval_save = 0; void eval_save() { push(NIL, stack); int_during_gc = 0; in_eval_save = 1; settype(stack, STACK); stack->n_car = (NODE *)malloc(sizeof(regs)); if (car(stack) == NULL) { err_logo(OUT_OF_MEM_UNREC, NIL); } else { memcpy(car(stack), ®s, sizeof(regs)); } in_eval_save = 0; if (int_during_gc != 0) { delayed_int(); } } void eval_restore() { int_during_gc = 0; in_eval_save = 1; memcpy(®s, car(stack), sizeof(regs)); pop(stack); in_eval_save = 0; if (int_during_gc != 0) { delayed_int(); } } /* #ifdef OBJECTS NODE *val_eval_driver(NODE *seq) { val_status = VALUE_OK; return evaluator(seq, begin_seq); } #endif */ /* An explicit control evaluator, taken almost directly from SICP, section * 5.2. list is a flat list of expressions to evaluate. where is a label to * begin at. Return value depends on where. */ NODE *evaluator(NODE *list, enum labels where) { FIXNUM cont = 0; /* where to go next */ int i; BOOLEAN tracing = FALSE; /* are we tracing the current procedure? */ eval_save(); var = var_stack; newcont(all_done); newcont(where); goto fetch_cont; all_done: reset_args(var); eval_restore(); return(val); begin_line: this_line = list; val_status = NO_VALUE_OK; newcont(end_line); begin_seq: debprint("begin_seq"); make_tree(list); if (!is_tree(list)) { val = UNBOUND; goto fetch_cont; } unev = tree__tree(list); goto eval_sequence; end_line: if (val != UNBOUND) { if (NOT_THROWING) err_logo(DK_WHAT, val); } /* val = NIL; */ goto fetch_cont; /* ----------------- EVAL ---------------------------------- */ /* Get here for actual argument, from eval_sequence (non-tail), or from tail call. */ tail_eval_dispatch: tailcall = 1; eval_dispatch: debprint("eval_dispatch"); switch (nodetype(exp)) { case QUOTE: /* quoted literal */ val = /* deep_copy */ (node__quote(exp)); goto fetch_cont; case COLON: /* variable */ #ifdef OBJECTS val = varValue(node__colon(exp)); #else val = valnode__colon(exp); #endif while (val == UNBOUND && NOT_THROWING) val = err_logo(NO_VALUE, node__colon(exp)); goto fetch_cont; case CONS: /* procedure application */ if (tailcall == 1 && is_macro(car(exp)) && (is_list(procnode__caseobj(car(exp))) || isName(car(exp), Name_goto))) { /* tail call to user-defined macro must be treated as non-tail * because the expression returned by the macro * remains to be evaluated in the caller's context */ unev = NIL; goto non_tail_eval; } fun = car(exp); if (fun == Not_Enough_Node) { err_logo(TOO_MUCH, NIL); /* When does this happen? */ val = UNBOUND; goto fetch_cont; } if (flag__caseobj(fun, PROC_SPECFORM)) { argl = cdr(exp); goto apply_dispatch; } if (cdr(exp) != NIL) goto ev_application; else goto ev_no_args; case ARRAY: /* array must be copied */ val = deep_copy(exp); goto fetch_cont; default: val = exp; /* self-evaluating */ goto fetch_cont; } ev_no_args: /* Evaluate an application of a procedure with no arguments. */ argl = NIL; goto apply_dispatch; /* apply the procedure */ ev_application: /* Evaluate an application of a procedure with arguments. */ unev = cdr(exp); argl = NIL; eval_arg_loop: debprint("eval_arg_loop"); if (unev == NIL) goto eval_args_done; exp = car(unev); if (exp == Not_Enough_Node) { if (NOT_THROWING) err_logo(NOT_ENOUGH, NIL); goto eval_args_done; } arg_from_macro: if (nodetype(exp) != CONS) { /* Don't bother saving registers */ newcont(after_const_arg); /* if the exp isn't a proc call */ goto eval_dispatch; } eval_save(); save(current_unode); var = var_stack; tailcall = -1; didnt_output_name = NIL; didnt_get_output = cons_list(0, fun, ufun, this_line, END_OF_LIST); val_status = VALUE_OK; /* in case of apply or catch */ newcont(accumulate_arg); goto eval_dispatch; /* evaluate the current argument */ accumulate_arg: debprint("accumulate_arg"); /* Put the evaluated argument into the argl list. */ reset_args(var); restore(current_unode); last_call = fun; if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; } } if (stopping_flag == OUTPUT || STOPPING) { didnt_output_name = NIL; err_logo(DIDNT_OUTPUT, fun); } while (NOT_THROWING && val == UNBOUND) { val = err_logo(DIDNT_OUTPUT, NIL); } eval_restore(); if (stopping_flag == MACRO_RETURN) { if (val == NIL || val == UNBOUND || cdr(val) != NIL) { if (NOT_THROWING) { if (tree_dk_how != NIL && tree_dk_how != UNBOUND) err_logo(DK_HOW_UNREC, tree_dk_how); else err_logo(ERR_MACRO, val); } goto eval_args_done; } exp = car(val); stopping_flag = RUN; goto arg_from_macro; } after_const_arg: if (stopping_flag == THROWING) goto eval_args_done; push(val, argl); pop(unev); goto eval_arg_loop; eval_args_done: if (stopping_flag == THROWING) { val = UNBOUND; goto fetch_cont; } argl = reverse(argl); /* --------------------- APPLY ---------------------------- */ apply_dispatch: debprint("apply_dispatch"); /* Load in the procedure's definition and decide whether it's a compound * procedure or a primitive procedure. */ proc = procnode__caseobj(fun); if (is_macro(fun)) { num2save(val_status,tailcall); save2(didnt_get_output,current_unode); didnt_get_output = the_generation; /* (cons nil nil) */ /* We want a value, but not as actual arg */ newcont(macro_return); } if (proc == UNDEFINED) { /* 5.0 punctuationless variables */ if (!varTrue(AllowGetSet)) { /* No getter/setter allowed, punt */ val = err_logo(DK_HOW, fun); goto fetch_cont; } else if (argl == NIL) { /* possible var getter */ val = valnode__caseobj(fun); if (val == UNBOUND && NOT_THROWING) val = err_logo(DK_HOW, fun); else if (val != UNBOUND) { (void)ldefine(cons(fun, cons( cons(NIL,cons(cons(theName(Name_output), cons(make_colon(fun),NIL)), NIL)), NIL))); /* make real proc so no disk load next time */ setflag__caseobj(fun,PROC_BURIED); } goto fetch_cont; } else { /* var setter */ NODE *name = intern(bf3(fun)); if (valnode__caseobj(name) == UNBOUND && !(flag__caseobj(name, (HAS_GLOBAL_VALUE|IS_LOCAL_VALUE)))) { val = err_logo(DK_HOW, fun); goto fetch_cont; } (void)ldefine(cons(fun, cons( cons(Listvalue, cons(cons(Make, cons(make_quote(bf3(fun)), cons(Dotsvalue,NIL))), NIL)) ,NIL))); setflag__caseobj(fun,PROC_BURIED); argl = cons(bf3(fun), argl); if (NOT_THROWING) val = lmake(argl); goto fetch_cont; } } if (is_list(proc)) goto compound_apply; /* primitive_apply */ debprint("primitive_apply"); if (NOT_THROWING) { if ((tracing = flag__caseobj(fun, PROC_TRACED))) { for (i = 0; i < trace_level; i++) { print_space(stdout); } ndprintf(stdout, "( %s ", fun); if (argl != NIL) { arg = argl; while (arg != NIL) { print_node(stdout, maybe_quote(car(arg))); print_space(stdout); arg = cdr(arg); } } print_char(stdout, ')'); new_line(stdout); } val = (*getprimfun(proc))(argl); if (tracing && NOT_THROWING) { for (i = 0; i < trace_level; i++) { print_space(stdout); } print_node(stdout, fun); if (val == UNBOUND) ndprintf(stdout, " %t\n", message_texts[TRACE_STOPS]); else { ndprintf(stdout, " %t %s\n", message_texts[TRACE_OUTPUTS], maybe_quote(val)); } } } else val = UNBOUND; /* falls into fetch_cont */ #if DEB_CONT #define do_case(x) case x: debprint("Fetch_cont = " #x); goto x; #else #define do_case(x) case x: goto x; #endif fetch_cont: { enum labels x = (enum labels)cont; cont = (FIXNUM)car(numstack); numstack=cdr(numstack); switch (x) { do_list(do_case) default: abort(); } } /* ----------------- COMPOUND_APPLY ---------------------------------- */ compound_apply: debprint("compound_apply"); #ifdef mac check_mac_stop(); #endif #ifdef ibm check_ibm_stop(); #endif if ((tracing = flag__caseobj(fun, PROC_TRACED))) { for (i = 0; i < trace_level; i++) print_space(writestream); trace_level++; ndprintf(writestream, "( %s ", fun); } /* Bind the actuals to the formals */ lambda_apply: vsp = var_stack; /* remember where we came in */ for (formals = formals__procnode(proc); formals != NIL; formals = cdr(formals)) { parm = car(formals); if (nodetype(parm) == INT) break; /* default # args */ if (argl != NIL) { arg = car(argl); if (tracing) { print_node(writestream, maybe_quote(arg)); print_space(writestream); } } else arg = UNBOUND; if (nodetype(parm) == CASEOBJ) { if (not_local(parm,vsp)) { push(parm, var_stack); if (flag__caseobj(parm, IS_LOCAL_VALUE)) settype(var_stack, LOCALSAVE); var_stack->n_obj = valnode__caseobj(parm); setflag__caseobj(parm, IS_LOCAL_VALUE); } tell_shadow(parm); setvalnode__caseobj(parm, arg); if (arg == UNBOUND) err_logo(NOT_ENOUGH, fun); } else if (nodetype(parm) == CONS) { /* parm is optional or rest */ if (not_local(car(parm),vsp)) { push(car(parm), var_stack); if (flag__caseobj(car(parm), IS_LOCAL_VALUE)) settype(var_stack, LOCALSAVE); var_stack->n_obj = valnode__caseobj(car(parm)); setflag__caseobj(car(parm), IS_LOCAL_VALUE); } tell_shadow(car(parm)); if (cdr(parm) == NIL) { /* parm is rest */ setvalnode__caseobj(car(parm), argl); if (tracing) { if (argl != NIL) pop(argl); while (argl != NIL) { arg = car(argl); print_node(writestream, maybe_quote(arg)); print_space(writestream); pop(argl); } } else argl = NIL; break; } if (arg == UNBOUND) { /* use default */ eval_save(); save(current_unode); var = var_stack; tailcall = -1; list = cdr(parm); didnt_get_output = cons_list(0, fun, ufun, list, END_OF_LIST); didnt_output_name = NIL; if (NOT_THROWING) make_tree(list); else list = NIL; if (!is_tree(list)) { val = UNBOUND; goto set_args_continue; } unev = tree__tree(list); val = UNBOUND; exp = car(unev); pop(unev); if (unev != NIL) { err_logo(BAD_DEFAULT, parm); val = UNBOUND; goto set_args_continue; } newcont(set_args_continue); goto eval_dispatch; set_args_continue: if (stopping_flag == MACRO_RETURN) { if (val == NIL || val == UNBOUND || cdr(val) != NIL) { if (NOT_THROWING) err_logo(ERR_MACRO, val); } else { reset_args(var); exp = car(val); stopping_flag = RUN; didnt_get_output = cons_list(0, fun, ufun, list, END_OF_LIST); didnt_output_name = NIL; tailcall = -1; newcont(set_args_continue); goto eval_dispatch; } } restore(current_unode); last_call = fun; if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; } } if (stopping_flag == OUTPUT || STOPPING) { didnt_output_name = NIL; err_logo(DIDNT_OUTPUT, fun); } while (NOT_THROWING && val == UNBOUND) { val = err_logo(DIDNT_OUTPUT, NIL); } reset_args(var); eval_restore(); parm = car(formals); if (stopping_flag == THROWING) { val = UNBOUND; goto fetch_cont; } arg = val; } setvalnode__caseobj(car(parm), arg); } if (argl != NIL) pop(argl); } if (argl != NIL) { err_logo(TOO_MUCH, fun); } if (check_throwing) { val = UNBOUND; goto fetch_cont; } vsp = NIL; if ((tracing = !is_list(fun) && flag__caseobj(fun, PROC_TRACED))) { if (NOT_THROWING) print_char(writestream, ')'); new_line(writestream); save(fun); newcont(compound_apply_continue); } last_ufun = ufun; if (!is_list(fun)) ufun = fun; last_line = this_line; this_line = NIL; /* proc = (is_list(fun) ? anonymous_function(fun) : procnode__caseobj(fun)); */ /* If that's uncommented, begin_apply must get proc from fun, not exp */ list = bodylist__procnode(proc); /* get the body ... */ make_tree_from_body(list); if (!is_tree(list)) { val = UNBOUND; goto fetch_cont; } unev = tree__tree(list); if (NOT_THROWING) stopping_flag = RUN; output_node = UNBOUND; if (didnt_get_output == UNBOUND) val_status = NO_VALUE_OK | STOP_OK | STOP_TAIL; else if (didnt_get_output == NIL) val_status = NO_VALUE_OK | STOP_OK | STOP_TAIL | OUTPUT_OK | OUTPUT_TAIL; else val_status = OUTPUT_OK | OUTPUT_TAIL; if (didnt_output_name == NIL) didnt_output_name = fun; current_unode = cons(NIL,NIL); /* a marker for this proc call */ /* ----------------- EVAL_SEQUENCE ---------------------------------- */ /* Fall through from proc body, call from start or fsubr argument */ eval_sequence: debprint("eval_sequence"); /* Evaluate each expression in the sequence. Most of the complexity is in recognizing tail calls. */ if (!RUNNING) goto fetch_cont; if (nodetype(unev) == LINE) { if (the_generation != (generation__line(unev))) { /* something redefined while we're running */ int linenum = 0; this_line = tree__tree(bodylist__procnode(proc)); while (this_line != unev) { /* If redef isn't end of line, don't try to fix, but don't blow up either. (Maybe not called from here.) */ if (this_line == NULL) goto nofix; if (nodetype(this_line) == LINE) linenum++; this_line = cdr(this_line); } untreeify_proc(proc); make_tree_from_body(bodylist__procnode(proc)); unev = tree__tree(bodylist__procnode(proc)); while (--linenum >= 0) { do pop(unev); while (unev != NIL && nodetype(unev) != LINE); } } nofix: this_line = unparsed__line(unev); if (ufun != NIL && flag__caseobj(ufun, PROC_STEPPED)) { if (tracing) { int i = 1; while (i++ < trace_level) print_space(stdout); } print_node(stdout, this_line); (void)reader(stdin, " >>> "); } } exp = car(unev); pop(unev); if (exp != NIL && is_list(exp) && (is_tailform(procnode__caseobj(car(exp))))) { i = (int)getprimpri(procnode__caseobj(car(exp))); if (i == OUTPUT_PRIORITY) { if (cadr(exp) == Not_Enough_Node) { err_logo(NOT_ENOUGH,car(exp)); val = UNBOUND; goto fetch_cont; } didnt_output_name = NIL; if (val_status & OUTPUT_TAIL) { didnt_get_output = cons_list(0,car(exp),ufun,this_line, END_OF_LIST); fun = car(exp); exp = cadr(exp); val_status = VALUE_OK; goto tail_eval_dispatch; } else if (val_status & OUTPUT_OK) { goto tail_eval_dispatch; } else if (ufun == NIL) { err_logo(AT_TOPLEVEL,car(exp)); val = UNBOUND; goto fetch_cont; } else if (val_status & STOP_OK) { didnt_get_output = cons_list(0,car(exp),ufun,this_line, END_OF_LIST); val_status = VALUE_OK; exp = cadr(exp); newcont(op_want_stop); goto eval_dispatch; op_want_stop: if (NOT_THROWING) err_logo(DK_WHAT_UP, val); goto fetch_cont; } else if (val_status & VALUE_OK) { /* pr apply [output ?] [3] */ debprint("Op with VALUE_OK"); didnt_output_name = fun; goto tail_eval_dispatch; } else { debprint("Op with none of the above"); goto tail_eval_dispatch; } } else if (i == STOP_PRIORITY) { if (ufun == NIL) { err_logo(AT_TOPLEVEL,car(exp)); } else if (val_status & STOP_TAIL) { } else if (val_status & STOP_OK) { stopping_flag = STOP; output_unode = current_unode; } else if (val_status & OUTPUT_OK) { if (NOT_THROWING) { if (didnt_get_output == NIL || didnt_get_output == UNBOUND) { /* actually can happen: PRINT FOREACH ... will give didn't output message uplevel */ } else err_logo(DIDNT_OUTPUT, NIL); } } else { /* show runresult [stop] inside a procedure */ didnt_output_name = car(exp); if (NOT_THROWING) err_logo(DIDNT_OUTPUT, NIL); } val = UNBOUND; goto fetch_cont; } else { /* maybeoutput */ debprint("maybeoutput"); if (cadr(exp) == Not_Enough_Node) { err_logo(NOT_ENOUGH,car(exp)); val = UNBOUND; goto fetch_cont; } if (ufun == NIL) { err_logo(AT_TOPLEVEL,car(exp)); val = UNBOUND; goto fetch_cont; } if (val_status & OUTPUT_TAIL) { didnt_output_name = NIL; if (val_status & STOP_TAIL) { exp = cadr(exp); didnt_get_output = NIL; val_status = VALUE_OK | NO_VALUE_OK; } else { didnt_get_output = cons_list(0,car(exp),ufun, this_line,END_OF_LIST); exp = cadr(exp); val_status = VALUE_OK; } goto tail_eval_dispatch; } else if (val_status & OUTPUT_OK) { didnt_output_name = NIL; if (val_status & STOP_OK) { didnt_get_output = NIL; val_status = NO_VALUE_OK | VALUE_OK; exp = cadr(exp); newcont(after_maybeoutput); goto eval_dispatch; after_maybeoutput: if (val == UNBOUND) lstop(NIL); else loutput(cons(val, NIL)); goto fetch_cont; } else { goto eval_dispatch; } } else if (val_status & STOP_TAIL) { exp = cadr(exp); didnt_get_output = UNBOUND; val_status = NO_VALUE_OK; goto tail_eval_dispatch; } else if (val_status & STOP_OK) { exp = cadr(exp); didnt_get_output = UNBOUND; val_status = NO_VALUE_OK; newcont(after_maybeoutput); goto eval_dispatch; } else { goto tail_eval_dispatch; } } } if (unev == NIL) { /* falling off tail of sequence */ debprint("falling off"); if (val_status & NO_VALUE_OK) { if (val_status & VALUE_OK) /* from runresult */ didnt_get_output = NIL; else didnt_get_output = UNBOUND; } else if (val_status & VALUE_OK) { } else if (val_status & OUTPUT_OK) { next_stop_want_output: save(didnt_get_output); didnt_get_output = UNBOUND; val_status &= ~OUTPUT_TAIL; newcont(fall_off_want_output); goto tail_eval_dispatch; fall_off_want_output: restore(didnt_get_output); if (stopping_flag == OUTPUT) { goto fetch_cont; /* repeat body did output */ } if (NOT_THROWING && val != UNBOUND) { /* Don't allow just value expr w/o OUTPUT */ err_logo(DK_WHAT, val); } goto fetch_cont; } goto tail_eval_dispatch; } if (car(unev) != NIL && is_list(car(unev)) && /* next is STOP */ (is_tailform(procnode__caseobj(car(car(unev))))) && getprimpri(procnode__caseobj(car(car(unev)))) == STOP_PRIORITY) { if (val_status & STOP_TAIL) { didnt_get_output = UNBOUND; goto tail_eval_dispatch; } else if (val_status & STOP_OK) { goto non_tail_eval; } else if (val_status & OUTPUT_OK) { goto next_stop_want_output; } /* else treat as non-tail and the STOP will be caught later */ } non_tail_eval: debprint("non_tail_eval"); if (nodetype(exp) != CONS) { /* Don't bother saving registers */ newcont(after_constant); /* if the exp isn't a proc call */ goto eval_dispatch; } eval_save(); didnt_get_output = UNBOUND; /* tell EVAL we don't want a value */ tailcall = 0; if (nodetype(exp) == CONS && is_prim(procnode__caseobj(car(exp)))) { newcont(no_reset_args); /* primitive */ } else { var = var_stack; newcont(eval_sequence_continue); } goto eval_dispatch; eval_sequence_continue: reset_args(var); no_reset_args: /* allows catch "foo [local ...] to work */ eval_restore(); if (dont_fix_ift) { ift_iff_flag = dont_fix_ift-1; dont_fix_ift = 0; } debprint("eval_sequence_continue"); if (stopping_flag == MACRO_RETURN) { if (val != NIL && is_list(val) && (isName(car(val), Name_tag))) unev = cdr(val); /* from goto */ else unev = append(val, unev); val = UNBOUND; stopping_flag = RUN; if (unev == NIL) goto fetch_cont; } else { if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; goto fetch_cont; } } } after_constant: if (val != UNBOUND && NOT_THROWING) { err_logo(DK_WHAT, val); val = UNBOUND; } if (NOT_THROWING && unev == NIL) { goto fetch_cont; } goto eval_sequence; compound_apply_continue: /* Only get here if tracing */ restore(parm); /* saved from fun */ --trace_level; if (NOT_THROWING) { for (i = 0; i < trace_level; i++) print_space(writestream); print_node(writestream, parm); if (val == UNBOUND) ndprintf(writestream, " %t\n", message_texts[TRACE_STOPS]); else { ndprintf(writestream, " %t %s\n", message_texts[TRACE_OUTPUTS], maybe_quote(val)); } } goto fetch_cont; /* --------------------- MACROS ---------------------------- */ macro_return: restore2(didnt_get_output,current_unode); num2restore(val_status,tailcall); debprint("macro_return"); if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; } } while (!is_list(val) && NOT_THROWING) { val = err_logo(ERR_MACRO,val); } if (NOT_THROWING) { if (didnt_get_output != UNBOUND) didnt_output_name = fun; if (is_cont(val)) { newcont(cont__cont(val)); val = val__cont(val); goto fetch_cont; } if (tailcall <= 0) { list = val; make_tree(list); if (NOT_THROWING) { stopping_flag = MACRO_RETURN; if (!is_tree(list)) val = NIL; else val = tree__tree(list); } else val = UNBOUND; goto fetch_cont; } list = val; goto begin_seq; } val = UNBOUND; goto fetch_cont; #define RUNRESULT_OUTPUT_LEGAL 0 runresult_continuation: list = val; #if RUNRESULT_OUTPUT_LEGAL val_status |= VALUE_OK | NO_VALUE_OK; val_status &= ~(STOP_TAIL | OUTPUT_TAIL); #else val_status = VALUE_OK | NO_VALUE_OK | OUTPUT_OK | STOP_OK; /* output and stop are not okay, but we give our own err message */ #endif save(current_unode); newcont(runresult_followup); goto begin_seq; runresult_followup: restore(current_unode); debprint("runresult_followup"); if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; } } if (STOPPING || stopping_flag == OUTPUT) err_logo(RUNRES_STOP, NIL); if (val == UNBOUND) { val = NIL; } else { val = cons(val, NIL); } goto fetch_cont; repeat_continuation: list = cdr(val); num2save(repcount,user_repcount); repcount = getint(car(val)); user_repcount = 0; repeat_again: val = UNBOUND; if (repcount == 0) { repeat_done: num2restore(repcount,user_repcount); goto fetch_cont; } user_repcount++; save2(list,var); var = var_stack; num2save(repcount,user_repcount); num2save(val_status,tailcall); val_status &= ~(VALUE_OK|OUTPUT_TAIL|STOP_TAIL); if (tailcall == 0) val_status |= NO_VALUE_OK; /* embedded repeat */ newcont(repeat_followup); goto begin_seq; repeat_followup: if (val != UNBOUND && NOT_THROWING) { err_logo(DK_WHAT, val); } num2restore(val_status,tailcall); num2restore(repcount,user_repcount); reset_args(var); restore2(list,var); if (current_unode != output_unode) { debprint("rep_foll tailcall"); if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; goto repeat_done; } } if (repcount > 0) /* negative means forever */ --repcount; #ifdef mac check_mac_stop(); #endif #ifdef ibm check_ibm_stop(); #endif if (RUNNING) goto repeat_again; val = UNBOUND; goto repeat_done; catch_continuation: list = cdr(val); catch_tag = car(val); if (isName(catch_tag, Name_error)) { push(Erract, var_stack); if (flag__caseobj(Erract, IS_LOCAL_VALUE)) settype(var_stack, LOCALSAVE); var_stack->n_obj = valnode__caseobj(Erract); setflag__caseobj(Erract, IS_LOCAL_VALUE); setvalnode__caseobj(Erract, UNBOUND); } save2(didnt_output_name,didnt_get_output); num2save(val_status,tailcall); save2(current_unode,catch_tag); newcont(catch_followup); val_status &= ~(STOP_TAIL | OUTPUT_TAIL); goto begin_seq; catch_followup: restore2(current_unode,catch_tag); num2restore(val_status,tailcall); restore2(didnt_output_name,didnt_get_output); if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; goto fetch_cont; } } if (NOT_THROWING && val != UNBOUND && !(val_status & VALUE_OK)) err_logo(DK_WHAT, val); if (stopping_flag == THROWING && ((compare_node(throw_node, catch_tag, TRUE) == 0) || (isName(throw_node, Name_error) && isName(catch_tag, Name_error)))) { throw_node = UNBOUND; stopping_flag = RUN; val = output_node; } goto fetch_cont; #ifdef OBJECTS withobject_continuation: save2(didnt_output_name,didnt_get_output); num2save(val_status,tailcall); save2(current_unode,current_object); newcont(withobject_followup); current_object = car(val); newcont(cont__cont(cdr(val))); list = val = val__cont(cdr(val)); val_status &= ~(STOP_TAIL | OUTPUT_TAIL); goto fetch_cont; withobject_followup: restore2(current_unode,current_object); num2restore(val_status,tailcall); restore2(didnt_output_name,didnt_get_output); if (current_unode != output_unode) { if (STOPPING || RUNNING) output_node = UNBOUND; if (stopping_flag == OUTPUT || STOPPING) { stopping_flag = RUN; val = output_node; goto fetch_cont; } } if (NOT_THROWING && val != UNBOUND && !(val_status & VALUE_OK)) err_logo(DK_WHAT, val); goto fetch_cont; #endif /* OBJECTS */ goto_continuation: if (NOT_THROWING) { if (ufun == NIL) { err_logo(AT_TOPLEVEL, theName(Name_goto)); val = UNBOUND; goto fetch_cont; } proc = procnode__caseobj(ufun); list = bodylist__procnode(proc); unev = tree__tree(list); while (unev != NIL && !check_throwing) { if (nodetype(unev) == LINE) this_line = unparsed__line(unev); exp = car(unev); pop(unev); if (is_list (exp) && (isName(car(exp), Name_tag)) && (nodetype(cadr(exp)) == QUOTE) && compare_node(val, node__quote(cadr(exp)), TRUE) == 0) { val = cons(theName(Name_tag), unev); stopping_flag = MACRO_RETURN; goto fetch_cont; } } err_logo(BAD_DATA_UNREC, val); } val = UNBOUND; goto fetch_cont; begin_apply: /* This is for lapply. */ exp = car(val); while (nodetype(exp) == ARRAY && NOT_THROWING) exp = err_logo(APPLY_BAD_DATA, exp); argl = cadr(val); val = UNBOUND; while (!is_list(argl) && NOT_THROWING) argl = err_logo(APPLY_BAD_DATA, argl); if (NOT_THROWING && exp != NIL) { if (is_list(exp)) { /* template */ if (is_list(car(exp)) && cdr(exp) != NIL) { if (is_list(cadr(exp))) { /* procedure text form [[param ...] [instr ...] ...] */ proc = anonymous_function(exp); if (stopping_flag == THROWING) goto fetch_cont; tracing = 0; if (tailcall <= 0) { save(var); var = var_stack; newcont(after_lambda); } goto lambda_apply; } /* lambda form [[param ...] instr ...] */ formals = car(exp); if (tailcall <= 0) { save(var); var = var_stack; newcont(after_lambda); } /* numsave(tailcall); */ tailcall = 0; llocal(formals); /* bind the formals locally */ /* numrestore(tailcall); */ for ( ; formals != NIL && argl != NIL && NOT_THROWING; formals = cdr(formals), argl = cdr(argl)) setvalnode__caseobj(car(formals), car(argl)); if (formals != NIL) { err_logo(NOT_ENOUGH, exp); goto fetch_cont; } else if (argl != NIL) { err_logo(DK_WHAT, car(argl)); goto fetch_cont; } list = cdr(exp); goto lambda_qm; } else { /* question-mark form [instr ...] */ qm_list = argl; list = exp; lambda_qm: make_tree(list); if (list == NIL || !is_tree(list)) { goto fetch_cont; } unev = tree__tree(list); if (tailcall <= 0) { val_status &= ~(STOP_TAIL | OUTPUT_TAIL); save(var); var = var_stack; newcont(after_lambda); } goto eval_sequence; } } else { /* name of procedure to apply */ int min, max, n; NODE *arg; fun = intern(exp); if (procnode__caseobj(fun) == UNDEFINED && NOT_THROWING && fun != Null_Word) silent_load(fun, NULL); /* try ./.lg */ if (procnode__caseobj(fun) == UNDEFINED && NOT_THROWING && fun != Null_Word) silent_load(fun, logolib); /* try / */ proc = procnode__caseobj(fun); while (proc == UNDEFINED && NOT_THROWING) { val = err_logo(DK_HOW_UNREC, fun); } if (NOT_THROWING) { if (nodetype(proc) == CONS) { min = getint(minargs__procnode(proc)); max = getint(maxargs__procnode(proc)); } else { if (getprimdflt(proc) < 0) { /* special form */ err_logo(DK_HOW_UNREC, fun); /* can't apply */ goto fetch_cont; } else { min = getprimmin(proc); if (min == OK_NO_ARG) min = 0; max = getprimmax(proc); } } for (n = 0, arg = argl; arg != NIL; n++, arg = cdr(arg)); if (n < min) { err_logo(NOT_ENOUGH, NIL); } else if (n > max && max >= 0) { err_logo(TOO_MUCH, fun); } else { if (tailcall <= 0) { save(var); var = var_stack; newcont(after_lambda); } goto apply_dispatch; } } } } goto fetch_cont; after_lambda: reset_args(var); restore(var); goto fetch_cont; } ucblogo-5.5/Messages.fr0100644000161300001330000000463510274571571013051 0ustar bhdoe; French version of Berkeley Logo messages file 5.5 Logo : erreur interne fatale Plus assez de mémoire Débordement de pile Tortue en dehors des limites %p n'aime pas l'argument %s %p ne donne pas de valeur à %p Pas assez d'arguments pour %p %p n'aime pas l'argument %s Trop de choses entre les ( ) Vous ne dites pas ce qu'il faut faire de %s Trop de '(' %s n'a pas de valeur ')' inattendue Je ne connais pas la procédure %p Pas de CATCH correspondant à l'étiquette (tag) %p %p est déjà définie Arrêt... Déjà en train d'appliquer DRIBBLE Erreur système de fichiers: %p Supposant que vous voulez dire SINON (IFELSE) et non SI (IF) %p masquée dans un appel de procédure Throw "Error %p est une primitive Impossible d'utiliser POUR (TO) dans une procédure Je ne connais pas la procédure %p %p sans TEST ']' inattendu '}' inattendu Impossible d'initialiser le graphisme La macro retourne %s au lieu d'une liste Vous ne dites pas ce qu'il faut faire de %s Ne peux utiliser %p que dans une procédure APPLY n'accepte pas l'argument %s FIN (END) dans une instruction multi-ligne dans %p Plus de mémoire (fatal) %p FIN (END) dans une instruction multi-ligne Expression par défaut de l'argument optionnel erronée: %S Ne peux utiliser RETOURNE (OUTPUT) ou STOPPE (STOP) dans RUNRESULT Supposant que vous voulez dire '%p' et non %p Impossible d'ouvrir fichier %p Fichier %p déjà ouvert Fichier %p non ouvert Merci d'utiliser Logo. Bonne journée! Désolé, pas de shell sur le Mac. Tapez EXIT pour revenir à Logo dans %s\n%s ERRACT boucle Pause... arrête sort Fichier non trouvé: %t\n KEYP impossible, pas de FIONREAD sur ce système Mémoire insuffisante Impossible d'ouvrir ce fichier Fichier déjà ouvert Fichier non ouvert Pprop Bienvenue dans Berkeley Logo version %t Vous devez être dans une procédure pour utiliser RETOURNE (OUTPUT) ou STOPPE (STOP) Attention: mémoire insuffisante pour lancer le ramasse-miette Ramasse-miette désactivé - Enregistrez vos données et quittez! %s définie\n Faire %s %s pour %p\nfin\n\n Plist %s = %s\n Aide indisponible.\n Pas d'aide disponible pour %p.\n --plus-- vrai faux fin retourne stoppe goto étiquette si sinon pour .macro toplevel system error rien ; Outputs from SCREENMODE textscreen splitscreen fullscreen ; Outputs from PENMODE paint erase reverse ; Outputs from TURTLEMODE wrap fence window ; HELP turns infix operators +-*/=<> into these sum difference product quotient equalp lessp greaterp lessequalp greaterequalp notequalp ucblogo-5.5/evaluator.ps0100644000161300001330000037441107530516636013323 0ustar bhdoe%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: eva.dvi %%Pages: 1 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips eva.dvi -o eva.ps %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2002.08.20:1238 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: special.pro %! TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N /vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N /rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N /@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ /hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B /@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ /urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known {userdict/md get type/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale }if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState save N userdict maxlength dict begin/magscale true def normalscale currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts /psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict begin/SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N /@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X /yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 39158280 55380996 1000 600 600 (eva.dvi) @start %DVIPSBitmapFont: Fa cmr10 10 1 /Fa 1 50 df49 D E %EndDVIPSBitmapFont end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: A4 %%EndSetup %%Page: 1 1 1 0 bop -630 6302 a @beginspecial 0 @llx 0 @lly 604 @urx 767 @ury 6040 @rwi @setspecial %%BeginDocument: evaluator.eps %!PS-Adobe-2.0 EPSF-2.0 %%DocumentFonts: Times-Roman %%+ Times-Bold %%+ Symbol %%BoundingBox: 0 0 604 767 %%Title:evaluator.eps %%Creator: %%CreationDate: %%EndComments %%BeginProcSet: BeachHead 2 3 %%BeachHead - v2.3 Copyright 1991-1993 Silicon Beach Software, inc. userdict /BeachHead known userdict begin /BeachHead 140 dict def BeachHead end begin /ta exch def /BeachHead_version 2 def /isWinPS false def /c 75 string def /sa 75 string def /f false def /g false def /h false def /i false def /n true def /k 0.015 def /oldmatrix 6 array def /newmatrix 6 array def /_doTexturePat false def /_strtxtmatrix null def /nulld { counttomark {null def} repeat pop } bind def mark /l /m /o /q /r /u /v /w /_cwidths /wa /x /y /z /A /B /D /E/F /G /H /I /J /K /M /N /O /P /Q /R /S /T /V /W /X /Y /ba /ca /da /ea /fa /ga /ha /ia /ja /ka ta not{/la /ma}if /_strtxtmatrix nulld /ra 256 array def ra dup dup 0 /Times-Roman findfont /Encoding get 0 128 getinterval putinterval 39 /quotesingle put 96 /grave put /Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis /Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute/egrave /ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde/oacute/ograve /ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex/udieresis/dagger/degree/cent /sterling/section/bullet/paragraph/germandbls/registered/copyright/trademark/acute /dieresis/notequal/AE/Oslash/infinity/plusminus/lessequal/greaterequal/yen/mu/partialdiff /summation/product/pi/integral/ordfeminine/ordmasculine/Omega/ae/oslash/questiondown /exclamdown/logicalnot/radical/florin/approxequal/Delta/guillemotleft/guillemotright /ellipsis/blank/Agrave/Atilde/Otilde/OE/oe/endash/emdash/quotedblleft/quotedblright /quoteleft/quoteright/divide/lozenge/ydieresis/Ydieresis/fraction/currency/guilsinglleft /guilsinglright/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand /Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex/Idieresis/Igrave /Oacute/Ocircumflex/apple/Ograve/Uacute/Ucircumflex/Ugrave/dotlessi/circumflex/tilde /macron/breve/dotaccent/ring/cedilla/hungarumlaut/ogonek/caron ra 128 128 getinterval astore pop /va 256 array def ra va copy pop va 15{dup}repeat 161 /ring put 178 /Scaron put 182 /eth put 184 /Thorn put 185 /thorn put 195 /scaron put 198 /Eth put 222 /hyphen put 223 /twosuperior put 225 /threesuperior put 240 /onequarter put 249 /onehalf put 250 /periodcentered put 252 /cedilla put 253 /multiply put 254 /Yacute put version cvr 51 ge { va 245 /onesuperior put va 251 /threequarters put va 255 /yacute put } if /d { 0 1 74 { c exch 0 put } for dup c cvs pop c } bind def /qa { 0 1 74 { sa exch 0 put } for dup sa cvs pop sa 74 1 put } bind def /e { d 74 2 put } bind def /addoblique { /g true def } bind def /addheavy { /f true def } bind def /adduline { /h true def } bind def /findshadowfont { findoutlinefont BeachHead /i true put BeachHead /n true put } bind def /findoutlinefont { findbeachheadfont gof /n true def } bind def /findbeachheadfont { /f false def /g false def /h false def /i false def dup findfont dup /FontType get 0 ne { /Encoding get dup 161 get exch 162 get /cent eq exch /exclamdown eq and { userdict /BeachHead get begin qa FontDirectory sa known { pop sa findfont } { findfont dup length 1 add dict /o exch def { 1 index /FID ne 2 index /UniqueID ne and { o 3 1 roll put } { pop pop } ifelse } forall /FontName sa dup length string copy def o /Encoding isWinPS {va}{ra} ifelse put sa o definefont } ifelse end }{ findfont } ifelse }{ exch pop } ifelse } bind def /gof { userdict /BeachHead get begin dup /FontName get e FontDirectory c known { pop pop c findfont } { exch dup /FontType get 0 eq { dup maxlength 2 add dict begin { 1 index /FID ne 2 index /UniqueID ne and {def} {pop pop} ifelse }forall currentdict end dup dup /FDepVector get [ exch {gof} forall ] /FDepVector exch put exch e pop c exch definefont } { 12 dict begin dup /l exch def /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def 0 1 255 {Encoding exch /.notdef put} for dup exch maxlength 2 add dict begin { 1 index /FID ne 2 index /UniqueID ne and {def} {pop pop} ifelse }forall /PaintType 2 def /StrokeWidth 1 0 FontMatrix dtransform dup mul exch dup mul add sqrt .012 exch div def currentdict end /_dummy exch definefont /r exch def /m 1 string def /FontType 3 def /BuildChar { exch begin m 0 3 -1 roll put r setfont m stringwidth setcharwidth l setfont i { .05 -.05 moveto m show } if n { reversecolor 0 0 moveto m show reversecolor } if r setfont 0 0 moveto m show end } bind def currentdict end exch e pop c exch definefont } ifelse } ifelse end } bind def /EPSBegin { save userdict /BeachHead get begin /la exch def count /ma exch def end userdict /showpage {} put 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit [] 0 setdash newpath } bind def /EPSEnd { userdict /BeachHead get begin count ma sub dup 0 gt {{pop}repeat} {pop}ifelse la end restore } bind def /cimage { userdict /BeachHead get begin { {readstring} } { {readhexstring} } ifelse /u exch def /colorimage where { pop 4 index dup string /v exch def dup string /w exch def dup string /x exch def dup string /y exch def string /z exch def { currentfile v u pop } { currentfile w u pop } { currentfile x u pop } { currentfile y u pop currentfile z u pop pop } 5 -1 roll { true 4 A } { true 4 /colorimage load exec } ifelse } { 4 index dup string /z exch def 4 mul string /B exch def { currentfile B u pop pop currentfile z u pop } exch { transimage } { /image load exec } ifelse } ifelse end } bind def /bhshow { userdict /BeachHead get begin h { gsave dup stringwidth pop (_) stringwidth pop div 1 scale currentpoint (_) show moveto grestore } if gsave g { [1 0 .17 1 0 0] concat } if f { /_x1 12 k mul def /_y1 12 k mul def currentpoint 3 copy _y1 add exch _x1 add exch moveto show 3 copy _y1 add exch _x1 sub exch moveto show 3 copy _y1 sub exch _x1 add exch moveto show 3 copy _y1 sub exch _x1 sub exch moveto show moveto } if show grestore end } bind def /C { D { gsave E F 3 index idtransform translate G 1 4 index 4 index {H} /image load exec grestore /I 0 def /G 0 def /D false def } if } bind def /transimage { userdict /BeachHead get begin 2 index 8 ne { /image load exec } { 4 index cvi string /H exch def /J 0 string def /K 0 def /D false def /I 0 def /G 0 def 0 1 5 index 1 sub { /F exch def 0 1 6 index 1 sub { K J length ge { 1 index dup type /stringtype ne { exec } if /J exch def /K 0 def } if J K get /K K 1 add def dup 255 eq { pop pop C } { H I 3 -1 roll put /I I 1 add def /G G 1 add def D not { /E exch def /G 1 def /D true def } { pop } ifelse } ifelse } for C } for 5{pop}repeat } ifelse end } bind def /L { D { gsave E F 8 index idtransform translate I 1 8 9 index {M} {N} {O} {P} true 4 /colorimage load exec grestore /I 0 def /D false def } if } bind def /A { 9 index cvi dup string /M exch def dup string /N exch def dup string /O exch def string /P exch def /Q 0 string def /K 0 def /D false def /I 0 def /G 0 def 0 1 10 index 1 sub { /F exch def 0 1 11 index 1 sub { K Q length ge { 6 index exec /R exch def 5 index exec /S exch def 4 index exec /T exch def 3 index exec /Q exch def /K 0 def } if R K get S K get T K get Q K get /K K 1 add def dup 0 eq 2 index 0 eq and 3 index 0 eq and 4 index 0 eq and { 5{pop}repeat L } { M I 6 -1 roll put N I 5 -1 roll put O I 4 -1 roll put P I 3 -1 roll put /I I 1 add def D not { /E exch def /D true def } { pop } ifelse } ifelse } for L } for 10{pop}repeat } bind def /bps 8 string def /bpm [8 0 0 8 0 0] def /bpp { bps } def /overlaybackpat { userdict /BeachHead get begin gsave setrgbcolor bps copy pop dup 0 get 8 div floor cvi 8 mul 1 index 2 get 8 div floor cvi 8 mul 2 index 1 get 8 div floor cvi 8 mul 8 4 index 3 get 8 div floor cvi 8 mul { 2 index 8 3 index { 1 index gsave translate 8 8 scale 8 8 false bpm /bpp load imagemask grestore } for pop } for pop pop pop grestore end } bind def /U { userdict /BeachHead get begin /V exch def /W exch def countdictstack save V 2 add 2 roll count V sub /X exch def /W load end { exec } stopped userdict /BeachHead get begin /Y exch def count X sub { pop } repeat Y 3 1 roll restore countdictstack exch sub { end } repeat end } bind def /Z ( ) def /aa { moveto { ba setfont Z end gsave 0 setgray stringwidth grestore userdict /BeachHead get begin rmoveto /ca load null ne { /da da 1 add def da ea length 1 sub le { fa ea da get ca } if } { ax ay rmoveto fa ga eq { cx cy rmoveto } if } ifelse } stopped currentdict userdict /BeachHead get ne { userdict /BeachHead get begin }if } bind def /filltextpath2 { userdict /BeachHead get begin /p exch def /s exch def /ea exch def /fillProc exch def /ia exch def currentpoint ia i and { ea s p krnshow } if moveto i /i false def currentpoint /m 1 string def /ya 0 def /t 0 def /za 0 def ea { m 0 3 -1 roll put newpath t za moveto m true charpath fillProc t s ya get add /t exch def ya 1 add /ya exch def za s ya get add /za exch def ya 1 add /ya exch def } forall moveto /i exch def ia { n i /n false def /i false def ea s p krnshow /i exch def /n exch def } if end } bind def /filltextpath { userdict /BeachHead get begin /ea exch def dup type dup /integertype eq exch /realtype eq or { /ay exch def /ax exch def /ga exch def /cy exch def /cx exch def /ca null def } { /wa 0 def /ca exch def } ifelse /ha exch def /ia exch def ia { i get { gsave 0 setgray /ca load null ne { /ca load ea kshow /wa 0 def } { cx cy ga ax ay ea awidthshow } ifelse grestore } if } if gsave currentfont ia { begin r FontMatrix makefont l FontMatrix makefont end } { null exch } ifelse /ja exch def /ka exch def /ba currentfont def _doTexturePat { systemdict /makepattern known } { false }ifelse { matrix currentmatrix _strtxtmatrix null ne { _strtxtmatrix setmatrix } if 1 -1 scale txTrnsX txTrnsY translate settexturepat setmatrix /da 0 def ea { /fa exch def Z 0 fa put ja setfont currentpoint Z show aa {exit} if } forall } { 10 setlinewidth /da 0 def currentpoint newpath 0 dup dup dup moveto lineto closepath moveto ea { /fa exch def Z 0 fa put currentpoint ja setfont count 1 add dup 1 roll Z true { charpath } stopped count count -1 roll sub { pop } repeat currentpoint {ha} 0 U pop newpath 0 dup dup dup moveto lineto closepath moveto aa {exit} if } forall } ifelse grestore ka null ne { /wa 0 def gsave 0 setgray /da 0 def ea { /fa exch def Z 0 fa put ka setfont currentpoint Z show aa {exit} if } forall grestore } if /_doTexturePat false def /_strtxtmatrix null def end } bind def /reversecolor { 1 currentrgbcolor 1 index eq 3 1 roll eq and { currentgray sub } if setgray } bind def /ftpkproc { pop Z 0 3 -1 roll put Z stringwidth neg exch neg exch rmoveto userdict /BeachHead get begin _cwidths wa get /wa wa 1 add def _cwidths wa get /wa wa 1 add def rmoveto end } bind def /xa { userdict /BeachHead get begin pop pop Z 0 3 -1 roll put currentpoint Z bhshow moveto _cwidths pa get /pa pa 1 add def _cwidths pa get /pa pa 1 add def rmoveto end } bind def /na[256{0}repeat]def mark 161 176 173 185 176 165 177 177 178 163 179 179 181 109 182 182 183 229 184 213 185 112 186 242 189 87 195 214 197 187 198 68 214 184 215 224 240 240 counttomark 2 div cvi {na 3 1 roll put} repeat pop /krnshow { dup type dup /integertype ne exch /realtype ne and {12} if /Symbol findfont exch scalefont /oa exch def /ua currentfont def /pa 0 def systemdict /cshow known currentfont /FontType get 0 eq and { /_cwidths exch def /xa load cshow } { exch userdict /BeachHead get begin h { /h false def gsave dup stringwidth pop (_) stringwidth pop div 1 scale currentpoint (_) show moveto grestore } if end { dup na exch get dup 0 eq isWinPS or { pop Z 0 3 -1 roll put currentpoint Z userdict begin bhshow end moveto } { oa setfont Z 0 3 -1 roll put currentpoint Z bhshow moveto ua setfont pop } ifelse dup pa get /pa pa 1 add def 1 index pa get /pa pa 1 add def rmoveto } forall pop } ifelse } bind def /setcmykcolor where { pop /bhsetcmykcolor/setcmykcolor load def } { /bhsetcmykcolor { 4 1 roll 3{ 3 index add neg 1 add dup 0 lt {pop 0}if 3 1 roll }repeat setrgbcolor pop }bind def }ifelse end %%EndProcSet %%BeginProcSet: gr_id 2 0 % gr_id - v2 - Copyright 1993 Silicon Beach Software, Inc. userdict /gr_id known not { userdict begin /gr_id 100 dict def /gr_idb {gr_id begin} bind def /gr_e {end end} bind def gr_idb /nulld { counttomark {null def} repeat pop } bind def mark /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /A /B /C /D /E /F /G /H /I /J /K /L /M nulld /bd {bind def} bind def /g_ea [] def /g_mg 60 def /g_xg 250 def /setcmykcolor where { pop /bhsetcmykcolor/setcmykcolor load def } { /bhsetcmykcolor { 4 1 roll 3{ 3 index add neg 1 add dup 0 lt {pop 0}if 3 1 roll }repeat setrgbcolor pop }bind def }ifelse /g_ss { currentscreen /scrnproc exch def /scrnangle exch def /scrnfreq exch def /scrnproc load type dup /arraytype eq exch /packedarraytype eq or { /g_ng 72 scrnfreq div dup matrix defaultmatrix dtransform mul abs def g_ng g_mg lt { /scrnfreq scrnfreq g_mg g_ng div sqrt div def scrnfreq scrnangle /scrnproc load setscreen /g_ng g_mg def } if g_ng g_xg gt { /g_ng g_xg def } if } { /g_ng g_xg def } ifelse g_ea 0 setdash } bd /g_lf { gsave /noeoclip exch def dup /y1b exch def /y2b exch def dup /x2t exch def /x2b exch def dup /y1t exch def /y2t exch def dup /x1t exch def /x1b exch def /filloff exch def /filldir exch def /colorlist exch def noeoclip { clip } { eoclip } ifelse newpath g_ss filldir 0 eq { filloff 0 lt { x1t filloff add /x1t exch def x2b filloff sub /x2b exch def } { x1b filloff sub /x1b exch def x2t filloff add /x2t exch def } ifelse /x1start x1t def /y1start y1t def /x2start x1b def /y2start y1b def /xdist x2t x1t sub def /ydist 0 def } { filloff 0 lt { y2t filloff add /y2t exch def y1b filloff sub /y1b exch def } { y1t filloff sub /y1t exch def y2b filloff add /y2b exch def } ifelse /x1start x1t def /y1start y1t def /x2start x2t def /y2start y2t def /xdist 0 def /ydist y1b y1t sub def } ifelse colorlist { /colorrec exch def colorrec 0 get /cmykStart exch def colorrec 1 get /cmykEnd exch def colorrec 2 get /ramppercent exch def /cStart cmykStart 0 get def /mStart cmykStart 1 get def /yStart cmykStart 2 get def /kStart cmykStart 3 get def /cInc cmykEnd 0 get cStart sub g_ng div def /mInc cmykEnd 1 get mStart sub g_ng div def /yInc cmykEnd 2 get yStart sub g_ng div def /kInc cmykEnd 3 get kStart sub g_ng div def /xinc xdist ramppercent mul g_ng div def /yinc ydist ramppercent mul g_ng div def xinc yinc gt {xinc}{yinc}ifelse setlinewidth newpath 0 1 g_ng { pop cStart mStart yStart kStart bhsetcmykcolor newpath x1start y1start moveto x2start y2start lineto stroke cStart cInc add /cStart exch def mStart mInc add /mStart exch def yStart yInc add /yStart exch def kStart kInc add /kStart exch def x1start xinc add /x1start exch def y1start yinc add /y1start exch def x2start xinc add /x2start exch def y2start yinc add /y2start exch def } for } forall grestore } bd /g_bf { true g_f } bd /g_cf { false g_f } bd /g_f { gsave /doBoxFill exch def /noeoclip exch def /y2 exch def /x2 exch def /y1 exch def /x1 exch def /yoff exch def /xoff exch def /colorlist exch def noeoclip { clip } { eoclip } ifelse newpath g_ss /centerX x2 x1 add 2 div xoff add def /centerY y2 y1 add 2 div yoff add def /boxRadX centerX dup x1 exch sub abs exch x2 exch sub abs 2 copy lt {exch} if pop def /boxRadY centerY dup y1 exch sub abs exch y2 exch sub abs 2 copy lt {exch} if pop def centerX dup boxRadX sub /x1 exch def boxRadX add /x2 exch def centerY dup boxRadY sub /y1 exch def boxRadY add /y2 exch def colorlist { /colorrec exch def colorrec 0 get /cmykStart exch def colorrec 1 get /cmykEnd exch def colorrec 2 get /ramppercent exch def /cStart cmykStart 0 get def /mStart cmykStart 1 get def /yStart cmykStart 2 get def /kStart cmykStart 3 get def /cInc cmykEnd 0 get cStart sub g_ng div def /mInc cmykEnd 1 get mStart sub g_ng div def /yInc cmykEnd 2 get yStart sub g_ng div def /kInc cmykEnd 3 get kStart sub g_ng div def /brwidthY boxRadY ramppercent mul g_ng div def /brwidthX boxRadX ramppercent mul g_ng div def 0 1 g_ng { pop cStart mStart yStart kStart bhsetcmykcolor doBoxFill { newpath x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto closepath fill } { gsave newpath centerX centerY translate x2 centerX sub y2 centerY sub scale 0 0 1.4142 0 360 arc fill grestore } ifelse cStart cInc add /cStart exch def mStart mInc add /mStart exch def yStart yInc add /yStart exch def kStart kInc add /kStart exch def x1 brwidthX add /x1 exch def y1 brwidthY add /y1 exch def x2 brwidthX sub /x2 exch def y2 brwidthY sub /y2 exch def } for } forall grestore } bd /g_cvf { gsave /noeoclip exch def pop pop pop pop pop /dist exch def /colorlist exch def noeoclip { clip } { eoclip } ifelse g_ss g_c dist mul 72 div dup g_ng gt {pop}{/g_ng exch def} ifelse /g_ng g_ng round def /lwidth dist 2 mul def colorlist length 1 sub -1 0 { colorlist exch get /colorrec exch def colorrec 0 get /cmykEnd exch def colorrec 1 get /cmykStart exch def colorrec 2 get /ramppercent exch def /cStart cmykStart 0 get def /mStart cmykStart 1 get def /yStart cmykStart 2 get def /kStart cmykStart 3 get def /cInc cmykEnd 0 get cStart sub g_ng div def /mInc cmykEnd 1 get mStart sub g_ng div def /yInc cmykEnd 2 get yStart sub g_ng div def /kInc cmykEnd 3 get kStart sub g_ng div def /ldec dist ramppercent mul g_ng div 2 mul def 0 1 g_ng { pop cStart mStart yStart kStart bhsetcmykcolor lwidth setlinewidth gsave firstfill {fill /firstfill false def}{stroke} ifelse grestore cStart cInc add /cStart exch def mStart mInc add /mStart exch def yStart yInc add /yStart exch def kStart kInc add /kStart exch def /lwidth lwidth ldec sub def lwidth 0.001 le { /lwidth 0.001 def } if } for } for grestore } bd gr_e } if %%EndProcSet BeachHead begin/isWinPS false def end 1 setflat gsave newpath [1 0 0 -1 311.731 382.302] concat -100.864 -50.7439 moveto -100.864 -61.9913 lineto -130.865 -61.9913 lineto -130.865 -76.9656 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -100.864 -47.1078 moveto -97.7741 -54.8347 lineto -99.1074 -55.1982 -100.138 -55.3799 -100.864 -55.3799 curveto -101.591 -55.3799 -102.621 -55.1982 -103.955 -54.8347 curveto -100.864 -47.1078 lineto -100.864 -47.1078 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -178.38 -365.522 moveto -188.679 -365.522 lineto -188.679 48.4929 lineto -202.706 48.4929 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -174.743 -365.522 moveto -182.47 -368.612 lineto -182.834 -367.279 -183.016 -366.249 -183.016 -365.522 curveto -183.016 -364.795 -182.834 -363.765 -182.47 -362.432 curveto -174.743 -365.522 lineto -174.743 -365.522 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -266.48 -321.804 moveto -216.373 -321.804 lineto -216.373 -303.225 lineto -266.48 -303.225 lineto -266.48 -321.804 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 49.251 700.106] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Begin-Seq) [6.66 0 4.43 0 4.99 0 2.77 0 4.99 0 3.32 0 5.55 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -201.425 -335.015 moveto -201.425 -290.014 lineto -281.427 -290.014 lineto -281.427 -319.015 lineto -266.427 -335.015 lineto -201.425 -335.015 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 -274.741 moveto -241.426 -290.014 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 -271.104 moveto -238.336 -278.831 lineto -239.669 -279.195 -240.699 -279.377 -241.426 -279.377 curveto -242.153 -279.377 -243.183 -279.195 -244.516 -278.831 curveto -241.426 -271.104 lineto -241.426 -271.104 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 -338.742 moveto -241.426 -354.022 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 -335.106 moveto -238.336 -342.833 lineto -239.669 -343.197 -240.699 -343.378 -241.426 -343.378 curveto -242.153 -343.378 -243.183 -343.197 -244.516 -342.833 curveto -241.426 -335.106 lineto -241.426 -335.106 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -264.81 -376.811 moveto -218.042 -376.811 lineto -218.042 -358.232 lineto -264.81 -358.232 lineto -264.81 -376.811 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 50.92 755.113] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Evaluator) [6.10 0 4.99 0 4.43 0 2.77 0 4.99 0 4.43 0 2.77 0 4.99 0 3.32 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 -354.022 moveto -229.966 -354.022 -220.184 -355.34 -212.081 -357.976 curveto -203.977 -360.612 -199.926 -363.794 -199.926 -367.522 curveto -199.926 -371.25 -203.977 -374.432 -212.081 -377.068 curveto -220.184 -379.704 -229.966 -381.022 -241.426 -381.022 curveto -252.886 -381.022 -262.668 -379.704 -270.772 -377.068 curveto -278.875 -374.432 -282.927 -371.25 -282.927 -367.522 curveto -282.927 -363.794 -278.875 -360.612 -270.772 -357.976 curveto -262.668 -355.34 -252.886 -354.022 -241.426 -354.022 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -280.427 -271.013 moveto -240.426 -232.012 lineto -202.425 -271.013 lineto -280.427 -271.013 lineto closepath userdict begin BeachHead end begin 0 0 0 0 bhsetcmykcolor end gsave eofill grestore userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.328 -93.9026 moveto -240.926 -109.017 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.423 -90.3153 moveto -238.128 -97.9574 lineto -239.452 -98.3562 -240.476 -98.5652 -241.203 -98.5845 curveto -241.93 -98.6039 -242.964 -98.4496 -244.307 -98.1217 curveto -241.423 -90.3153 lineto -241.423 -90.3153 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -240.926 -157.745 moveto -240.926 -167.227 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -240.926 -154.108 moveto -237.835 -161.835 lineto -239.169 -162.199 -240.199 -162.381 -240.926 -162.381 curveto -241.652 -162.381 -242.682 -162.199 -244.016 -161.835 curveto -240.926 -154.108 lineto -240.926 -154.108 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -42.4263 251.414 moveto -42.5183 240.997 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -42.3943 255.034 moveto -39.3723 247.28 lineto -40.7087 246.928 -41.7404 246.756 -42.4673 246.762 curveto -43.1942 246.768 -44.2226 246.959 -45.5527 247.334 curveto -42.3943 255.034 lineto -42.3943 255.034 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -24.7214 -271.027 moveto -24.5183 -282.219 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -24.7868 -267.425 moveto -21.5568 -275.094 lineto -22.8833 -275.482 -23.9099 -275.682 -24.6367 -275.695 curveto -25.3634 -275.709 -26.3967 -275.546 -27.7364 -275.206 curveto -24.7868 -267.425 lineto -24.7868 -267.425 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 11.1391 -294.879 moveto 20.7152 -294.514 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 7.57266 -295.015 moveto 15.1762 -291.633 lineto 15.5902 -292.951 15.8111 -293.974 15.8388 -294.7 curveto 15.8665 -295.426 15.7242 -296.463 15.4118 -297.809 curveto 7.57266 -295.015 lineto 7.57266 -295.015 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 243.44 -42.5109 moveto 252.994 -42.5109 lineto 252.994 -98.0081 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 239.804 -42.5109 moveto 247.531 -39.4205 lineto 247.894 -40.7539 248.076 -41.784 248.076 -42.5109 curveto 248.076 -43.2377 247.894 -44.2678 247.531 -45.6012 curveto 239.804 -42.5109 lineto 239.804 -42.5109 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 253.715 -147.736 moveto 253.715 -208.511 lineto 238.213 -208.511 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 253.715 -144.1 moveto 256.805 -151.827 lineto 255.472 -152.191 254.442 -152.372 253.715 -152.372 curveto 252.988 -152.372 251.958 -152.191 250.625 -151.827 curveto 253.715 -144.1 lineto 253.715 -144.1 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 182.299 moveto 199.712 151.995 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 185.935 moveto 202.802 178.208 lineto 201.469 177.845 200.439 177.663 199.712 177.663 curveto 198.985 177.663 197.955 177.845 196.622 178.208 curveto 199.712 185.935 lineto 199.712 185.935 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 103.267 moveto 199.712 79.9974 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 106.903 moveto 202.802 99.176 lineto 201.469 98.8126 200.439 98.6309 199.712 98.6309 curveto 198.985 98.6309 197.955 98.8126 196.622 99.176 curveto 199.712 106.903 lineto 199.712 106.903 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -0.731934 moveto 199.712 -20.0103 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 2.90417 moveto 202.802 -4.8228 lineto 201.469 -5.18625 200.439 -5.36798 199.712 -5.36798 curveto 198.985 -5.36798 197.955 -5.18625 196.622 -4.8228 curveto 199.712 2.90417 lineto 199.712 2.90417 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -68.7383 moveto 199.712 -170.01 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -65.1022 moveto 202.802 -72.8292 lineto 201.469 -73.1927 200.439 -73.3744 199.712 -73.3744 curveto 198.985 -73.3744 197.955 -73.1927 196.622 -72.8292 curveto 199.712 -65.1022 lineto 199.712 -65.1022 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -250.74 moveto 199.712 -275.501 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -247.103 moveto 202.802 -254.83 lineto 201.469 -255.194 200.439 -255.376 199.712 -255.376 curveto 198.985 -255.376 197.955 -255.194 196.622 -254.83 curveto 199.712 -247.103 lineto 199.712 -247.103 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -324.229 moveto 199.712 -340.982 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -320.592 moveto 202.802 -328.319 lineto 201.469 -328.683 200.439 -328.865 199.712 -328.865 curveto 198.985 -328.865 197.955 -328.683 196.622 -328.319 curveto 199.712 -320.592 lineto 199.712 -320.592 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 137.99 284.877 moveto 137.99 259.491 lineto 97.7176 259.491 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 137.99 288.513 moveto 141.08 280.786 lineto 139.747 280.423 138.717 280.241 137.99 280.241 curveto 137.263 280.241 136.233 280.423 134.9 280.786 curveto 137.99 288.513 lineto 137.99 288.513 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -42.5185 301.277 moveto -42.5185 284.996 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -42.5185 304.913 moveto -39.4282 297.186 lineto -40.7616 296.823 -41.7916 296.641 -42.5185 296.641 curveto -43.2454 296.641 -44.2755 296.823 -45.6089 297.186 curveto -42.5185 304.913 lineto -42.5185 304.913 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -42.5183 192.269 moveto -42.5183 180.994 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -42.5183 195.905 moveto -39.4279 188.178 lineto -40.7613 187.815 -41.7914 187.633 -42.5183 187.633 curveto -43.2451 187.633 -44.2752 187.815 -45.6086 188.178 curveto -42.5183 195.905 lineto -42.5183 195.905 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 1.13129 166.65 moveto 20.7152 167.492 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -2.42651 166.497 moveto 5.16074 169.917 lineto 5.58109 168.6 5.80684 167.579 5.83801 166.852 curveto 5.86919 166.126 5.73183 165.089 5.42593 163.742 curveto -2.42651 166.497 lineto -2.42651 166.497 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 307.802 moveto 59.2164 297.993 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 311.438 moveto 62.3067 303.711 lineto 60.9734 303.347 59.9433 303.166 59.2164 303.166 curveto 58.4895 303.166 57.4594 303.347 56.1261 303.711 curveto 59.2164 311.438 lineto 59.2164 311.438 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 217.263 moveto 59.2164 205.993 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 220.899 moveto 62.3067 213.172 lineto 60.9734 212.809 59.9433 212.627 59.2164 212.627 curveto 58.4895 212.627 57.4594 212.809 56.1261 213.172 curveto 59.2164 220.899 lineto 59.2164 220.899 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 125.264 moveto 59.2164 109.035 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 128.9 moveto 62.3067 121.173 lineto 60.9734 120.809 59.9433 120.628 59.2164 120.628 curveto 58.4895 120.628 57.4594 120.809 56.1261 121.173 curveto 59.2164 128.9 lineto 59.2164 128.9 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2158 13.2688 moveto 59.2174 -1.69414 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2155 16.9047 moveto 62.3065 9.17804 lineto 60.9732 8.81447 59.9431 8.63264 59.2162 8.63258 curveto 58.4893 8.63252 57.4592 8.81415 56.1258 9.17746 curveto 59.2155 16.9047 lineto 59.2155 16.9047 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -49.7378 moveto 59.2164 -63.0069 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -46.1017 moveto 62.3067 -53.8287 lineto 60.9734 -54.1921 59.9433 -54.3738 59.2164 -54.3738 curveto 58.4895 -54.3738 57.4594 -54.1921 56.1261 -53.8287 curveto 59.2164 -46.1017 lineto 59.2164 -46.1017 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -143.736 moveto 59.2164 -156.014 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -140.1 moveto 62.3067 -147.827 lineto 60.9734 -148.19 59.9433 -148.372 59.2164 -148.372 curveto 58.4895 -148.372 57.4594 -148.19 56.1261 -147.827 curveto 59.2164 -140.1 lineto 59.2164 -140.1 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -204.742 moveto 59.2164 -215.017 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -201.106 moveto 62.3067 -208.833 lineto 60.9734 -209.197 59.9433 -209.378 59.2164 -209.378 curveto 58.4895 -209.378 57.4594 -209.197 56.1261 -208.833 curveto 59.2164 -201.106 lineto 59.2164 -201.106 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -245.745 moveto 59.2164 -256.013 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -242.109 moveto 62.3067 -249.836 lineto 60.9734 -250.199 59.9433 -250.381 59.2164 -250.381 curveto 58.4895 -250.381 57.4594 -250.199 56.1261 -249.836 curveto 59.2164 -242.109 lineto 59.2164 -242.109 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -336.742 moveto 59.2164 -346.917 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2164 -333.106 moveto 62.3067 -340.833 lineto 60.9734 -341.196 59.9433 -341.378 59.2164 -341.378 curveto 58.4895 -341.378 57.4594 -341.196 56.1261 -340.833 curveto 59.2164 -333.106 lineto 59.2164 -333.106 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -100.864 54.267 moveto -100.864 40.9934 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -100.864 57.9031 moveto -97.7741 50.1762 lineto -99.1074 49.8127 -100.138 49.631 -100.864 49.631 curveto -101.591 49.631 -102.621 49.8127 -103.955 50.1762 curveto -100.864 57.9031 lineto -100.864 57.9031 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -100.864 -7.73497 moveto -100.864 -20.0162 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -100.864 -4.09886 moveto -97.7741 -11.8258 lineto -99.1074 -12.1893 -100.138 -12.371 -100.864 -12.371 curveto -101.591 -12.371 -102.621 -12.1893 -103.955 -11.8258 curveto -100.864 -4.09886 lineto -100.864 -4.09886 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.865 -107.693 moveto -130.864 -163.01 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.865 -104.057 moveto -127.774 -111.784 lineto -129.108 -112.148 -130.138 -112.329 -130.865 -112.329 curveto -131.592 -112.329 -132.622 -112.148 -133.955 -111.784 curveto -130.865 -104.057 lineto -130.865 -104.057 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.864 -243.74 moveto -130.864 -254.47 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.864 -240.104 moveto -127.774 -247.831 lineto -129.107 -248.194 -130.138 -248.376 -130.864 -248.376 curveto -131.591 -248.376 -132.621 -248.194 -133.955 -247.831 curveto -130.864 -240.104 lineto -130.864 -240.104 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.864 -285.198 moveto -130.864 -308.015 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.864 -281.562 moveto -127.774 -289.289 lineto -129.107 -289.652 -130.138 -289.834 -130.864 -289.834 curveto -131.591 -289.834 -132.621 -289.652 -133.955 -289.289 curveto -130.864 -281.562 lineto -130.864 -281.562 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.864 -340.742 moveto -130.864 -352.021 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.864 -337.106 moveto -127.774 -344.833 lineto -129.107 -345.197 -130.138 -345.378 -130.864 -345.378 curveto -131.591 -345.378 -132.621 -345.197 -133.955 -344.833 curveto -130.864 -337.106 lineto -130.864 -337.106 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 281.254 moveto -241.425 262.981 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 284.89 moveto -238.335 277.163 lineto -239.668 276.799 -240.699 276.618 -241.425 276.618 curveto -242.152 276.618 -243.182 276.799 -244.516 277.163 curveto -241.426 284.89 lineto -241.426 284.89 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 214.253 moveto -241.426 202.998 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 217.889 moveto -238.335 210.162 lineto -239.669 209.799 -240.699 209.617 -241.426 209.617 curveto -242.152 209.617 -243.182 209.799 -244.516 210.162 curveto -241.426 217.889 lineto -241.426 217.889 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 154.269 moveto -241.426 134.99 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 157.905 moveto -238.335 150.178 lineto -239.669 149.815 -240.699 149.633 -241.426 149.633 curveto -242.152 149.633 -243.182 149.815 -244.516 150.178 curveto -241.426 157.905 lineto -241.426 157.905 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.568 104.301 moveto -241.207 86.9941 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.643 107.898 moveto -238.392 100.237 lineto -239.718 99.8463 -240.744 99.6431 -241.471 99.628 curveto -242.197 99.6128 -243.231 99.7731 -244.572 100.109 curveto -241.643 107.898 lineto -241.643 107.898 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 9.75002 moveto -241.425 -3.01331 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 13.386 moveto -238.335 5.65927 lineto -239.669 5.2957 -240.699 5.11388 -241.426 5.11382 curveto -242.152 5.11375 -243.183 5.29538 -244.516 5.65869 curveto -241.426 13.386 lineto -241.426 13.386 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.425 -51.741 moveto -241.427 -63.2238 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.424 -48.1052 moveto -238.335 -55.8326 lineto -239.669 -56.1959 -240.699 -56.3774 -241.426 -56.3773 curveto -242.152 -56.3772 -243.183 -56.1954 -244.516 -55.8317 curveto -241.424 -48.1052 lineto -241.424 -48.1052 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -81.5197 305.004 moveto -41.5185 344.005 lineto -3.51733 305.004 lineto -81.5197 305.004 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 20.2152 16.9956 moveto 60.2164 55.9968 lineto 98.2176 16.9956 lineto 20.2152 16.9956 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -114.018 -136.009 moveto -74.0164 -97.008 lineto -36.0153 -136.009 lineto -114.018 -136.009 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 289.995 -144.009 moveto 289.995 -99.0081 lineto 209.992 -99.0081 lineto 209.992 -128.009 lineto 224.993 -144.009 lineto 289.995 -144.009 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -266.539 -190.017 moveto -215.312 -190.017 lineto -215.312 -171.438 lineto -266.539 -171.438 lineto -266.539 -190.017 lineto closepath grestore gsave gsave %IncludeFont: Times-Bold userdict begin BeachHead end begin [1 0 0 -1 49.1919 568.319] concat /Times-Bold findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Begin-Seq) [6.66 0 4.43 0 4.99 0 2.77 0 5.55 0 3.32 0 5.55 0 4.43 0 5.55 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -240.926 -167.227 moveto -229.466 -167.227 -219.684 -168.545 -211.58 -171.181 curveto -203.477 -173.817 -199.425 -176.999 -199.425 -180.727 curveto -199.425 -184.455 -203.477 -187.637 -211.58 -190.273 curveto -219.684 -192.909 -229.466 -194.227 -240.926 -194.227 curveto -252.386 -194.227 -262.167 -192.909 -270.271 -190.273 curveto -278.374 -187.637 -282.426 -184.455 -282.426 -180.727 curveto -282.426 -176.999 -278.374 -173.817 -270.271 -171.181 curveto -262.167 -168.545 -252.386 -167.227 -240.926 -167.227 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -279.427 47.9929 moveto -241.426 86.9941 lineto -202.425 47.9929 lineto -240.426 9.99176 lineto -279.427 47.9929 lineto closepath userdict begin BeachHead end begin 0 0 0 0 bhsetcmykcolor end gsave eofill grestore userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -269.104 34.2235 moveto -212.748 34.2235 lineto -212.748 62.7624 lineto -269.104 62.7624 lineto -269.104 34.2235 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 46.6268 344.078] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 4.98225 8.13782 moveto [1 0 0 -1 0 0] concat (Last expr) [6.10 0 4.43 0 3.88 0 2.77 0 3.50 0 4.43 0 4.99 0 4.99 0 3.32 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 46.6268 344.078] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 18.0976 moveto [1 0 0 -1 0 0] concat (or tailform?) [4.99 0 3.32 0 3.50 0 2.77 0 4.43 0 2.77 0 2.77 0 3.32 0 4.99 0 3.32 0 7.77 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -281.005 -24.5234 moveto -293.005 -24.5234 lineto -293.005 351.477 lineto -241.005 351.477 lineto -241.005 329.477 lineto newpath -284.731 -24.5234 moveto -293.005 -24.5234 lineto -293.005 351.477 lineto -241.005 351.477 lineto -241.005 329.477 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -281.095 -24.5234 moveto -288.822 -27.6138 lineto -289.186 -26.2804 -289.368 -25.2503 -289.368 -24.5234 curveto -289.368 -23.7966 -289.186 -22.7665 -288.822 -21.4331 curveto -281.095 -24.5234 lineto -281.095 -24.5234 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -238.425 80.4929 moveto -223.219 80.4929 lineto -223.219 99.072 lineto -238.425 99.072 lineto -238.425 80.4929 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 77.3052 297.809] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -173.078 -374.811 moveto -88.6505 -374.811 lineto -88.6505 -356.232 lineto -173.078 -356.232 lineto -173.078 -374.811 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 142.652 753.113] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Tail-Eval-Dispatch) [6.10 0 4.43 0 2.77 0 2.77 0 3.32 0 6.10 0 4.99 0 4.43 0 2.77 0 3.32 0 7.21 0 2.77 0 3.88 0 4.99 0 4.43 0 2.77 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -174.653 -379.022 moveto -87.0764 -379.022 lineto -87.0764 -352.021 lineto -174.653 -352.021 lineto -174.653 -379.022 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.865 -352.021 moveto -119.405 -352.021 -109.623 -353.34 -101.519 -355.976 curveto -93.4156 -358.611 -89.3639 -361.794 -89.3639 -365.522 curveto -89.3639 -369.25 -93.4156 -372.432 -101.519 -375.068 curveto -109.623 -377.704 -119.405 -379.022 -130.865 -379.022 curveto -142.324 -379.022 -152.106 -377.704 -160.21 -375.068 curveto -168.313 -372.432 -172.365 -369.25 -172.365 -365.522 curveto -172.365 -361.794 -168.313 -358.611 -160.21 -355.976 curveto -152.106 -353.34 -142.324 -352.021 -130.865 -352.021 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -170.865 -337.015 moveto -90.864 -337.015 lineto -90.864 -308.015 lineto -170.865 -308.015 lineto -170.865 -337.015 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -170.865 -337.015 moveto -90.864 -337.015 lineto -90.864 -308.015 lineto -170.865 -308.015 lineto -170.865 -337.015 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -161.012 -331.805 moveto -100.717 -331.805 lineto -100.717 -313.226 lineto -161.012 -313.226 lineto -161.012 -331.805 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 154.719 710.106] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Tailcall) [6.10 0 4.43 0 2.77 0 2.77 0 4.43 0 4.43 0 2.77 0 2.77 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 154.719 710.106] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 30.4533 8.13782 moveto [1 0 0 -1 0 0] concat ( ) [3.50 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Symbol userdict begin BeachHead end begin [1 0 0 -1 154.719 710.106] concat /Symbol findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 33.9532 8.13782 moveto [1 0 0 -1 0 0] concat (\254) [9.85 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 154.719 710.106] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 43.8078 8.13782 moveto [1 0 0 -1 0 0] concat ( ) [3.50 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 154.719 710.106] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 47.3077 8.13782 moveto [1 0 0 -1 0 0] concat (1) [4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.865 -254.47 moveto -119.405 -254.47 -109.623 -255.788 -101.519 -258.424 curveto -93.4156 -261.06 -89.3639 -264.242 -89.3639 -267.97 curveto -89.3639 -271.698 -93.4156 -274.88 -101.519 -277.516 curveto -109.623 -280.152 -119.405 -281.47 -130.865 -281.47 curveto -142.324 -281.47 -152.106 -280.152 -160.21 -277.516 curveto -168.313 -274.88 -172.365 -271.698 -172.365 -267.97 curveto -172.365 -264.242 -168.313 -261.06 -160.21 -258.424 curveto -152.106 -255.788 -142.324 -254.47 -130.865 -254.47 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -165.063 -277.26 moveto -96.666 -277.26 lineto -96.666 -258.681 lineto -165.063 -258.681 lineto -165.063 -277.26 lineto closepath grestore gsave gsave %IncludeFont: Times-Bold userdict begin BeachHead end begin [1 0 0 -1 150.668 655.562] concat /Times-Bold findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Dispatch) [6.66 0 4.99 0 4.99 0 2.77 0 3.32 0 7.21 0 2.77 0 3.88 0 5.55 0 4.99 0 3.32 0 4.43 0 5.55 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -172.365 -281.47 moveto -89.3637 -281.47 lineto -89.3637 -254.47 lineto -172.365 -254.47 lineto -172.365 -281.47 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -151.48 -220.761 moveto -110.249 -220.761 lineto -110.249 -182.262 lineto -151.48 -182.262 lineto -151.48 -220.761 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 164.25 599.063] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 3.32817 8.13782 moveto [1 0 0 -1 0 0] concat (Literal) [6.10 0 2.77 0 2.77 0 4.43 0 3.32 0 4.43 0 2.77 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 164.25 599.063] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 18.0976 moveto [1 0 0 -1 0 0] concat (constant) [4.43 0 4.99 0 4.99 0 3.88 0 2.77 0 4.43 0 4.99 0 2.77 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 164.25 599.063] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2.1329 28.0574 moveto [1 0 0 -1 0 0] concat (or var?) [4.99 0 3.32 0 3.50 0 4.99 0 4.43 0 3.32 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -169.366 -240.013 moveto -92.3632 -240.013 lineto -92.3632 -163.01 lineto -169.366 -163.01 lineto -169.366 -240.013 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -169.366 -202.012 moveto -131.364 -163.01 lineto -92.3632 -202.012 lineto -130.364 -240.013 lineto -169.366 -202.012 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -165.608 -99.7554 moveto -96.1218 -99.7554 lineto -96.1218 -81.1763 lineto -165.608 -81.1763 lineto -165.608 -99.7554 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 150.122 478.057] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Ev-Application) [6.10 0 4.99 0 3.32 0 7.21 0 4.99 0 4.99 0 2.77 0 2.77 0 4.43 0 4.43 0 2.77 0 2.77 0 4.99 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -172.366 -103.966 moveto -89.3643 -103.966 lineto -89.3643 -76.9656 lineto -172.366 -76.9656 lineto -172.366 -103.966 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -130.865 -76.9656 moveto -119.405 -76.9656 -109.623 -78.2838 -101.52 -80.9197 curveto -93.4162 -83.5555 -89.3645 -86.7378 -89.3645 -90.4657 curveto -89.3645 -94.1936 -93.4162 -97.3759 -101.52 -100.012 curveto -109.623 -102.648 -119.405 -103.966 -130.865 -103.966 curveto -142.325 -103.966 -152.107 -102.648 -160.21 -100.012 curveto -168.314 -97.3759 -172.366 -94.1936 -172.366 -90.4657 curveto -172.366 -86.7378 -168.314 -83.5555 -160.21 -80.9197 curveto -152.107 -78.2838 -142.325 -76.9656 -130.865 -76.9656 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -100.865 -20.0162 moveto -89.4046 -20.0162 -79.6227 -21.3344 -71.5191 -23.9703 curveto -63.4156 -26.6062 -59.3639 -29.7884 -59.3639 -33.5163 curveto -59.3639 -37.2442 -63.4156 -40.4265 -71.5191 -43.0624 curveto -79.6227 -45.6983 -89.4046 -47.0165 -100.865 -47.0165 curveto -112.324 -47.0165 -122.106 -45.6983 -130.21 -43.0624 curveto -138.313 -40.4265 -142.365 -37.2442 -142.365 -33.5163 curveto -142.365 -29.7884 -138.313 -26.6062 -130.21 -23.9703 curveto -122.106 -21.3344 -112.324 -20.0162 -100.865 -20.0162 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -135.523 -42.8061 moveto -66.2063 -42.8061 lineto -66.2063 -24.227 lineto -135.523 -24.227 lineto -135.523 -42.8061 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 180.208 421.108] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Arg-Loop) [6.10 0 4.99 0 4.43 0 2.77 0 3.32 0 7.21 0 3.15 0 4.99 0 3.32 0 6.10 0 4.99 0 4.99 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -60.8632 -4.00801 moveto -60.8632 40.9934 lineto -140.866 40.9934 lineto -140.866 11.9925 lineto -125.865 -4.00801 lineto -60.8632 -4.00801 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -133.389 9.20314 moveto -68.3403 9.20314 lineto -68.3403 27.7822 lineto -133.389 27.7822 lineto -133.389 9.20314 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 182.342 369.099] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Dispatch) [6.10 0 4.99 0 4.43 0 2.77 0 3.32 0 7.21 0 2.77 0 3.88 0 4.99 0 4.43 0 2.77 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -139.366 95.9951 moveto -101.364 134.996 lineto -62.3632 95.9951 lineto -100.364 57.994 lineto -139.366 95.9951 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -115.668 82.2257 moveto -86.0603 82.2257 lineto -86.0603 110.765 lineto -115.668 110.765 lineto -115.668 82.2257 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 200.062 296.076] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (More) [8.88 0 4.99 0 3.32 0 4.43 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 200.062 296.076] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.369797 18.0976 moveto [1 0 0 -1 0 0] concat (args?) [4.43 0 3.15 0 4.99 0 3.88 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -207.856 48.5023 moveto -192.65 48.5023 lineto -192.65 67.0814 lineto -207.856 67.0814 lineto -207.856 48.5023 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 107.875 329.8] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -140.855 -35.5017 moveto -158.855 -35.5017 lineto -158.855 95.5023 lineto -138.855 95.5023 lineto newpath -144.582 -35.5017 moveto -158.855 -35.5017 lineto -158.855 95.5023 lineto -138.855 95.5023 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -140.945 -35.5017 moveto -148.672 -38.592 lineto -149.036 -37.2587 -149.218 -36.2286 -149.218 -35.5017 curveto -149.218 -34.7748 -149.036 -33.7447 -148.672 -32.4113 curveto -140.945 -35.5017 lineto -140.945 -35.5017 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -146.855 76.5017 moveto -131.649 76.5017 lineto -131.649 95.0808 lineto -146.855 95.0808 lineto -146.855 76.5017 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 168.876 301.8] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -150.854 -167.501 moveto -135.648 -167.501 lineto -135.648 -148.922 lineto -150.854 -148.922 lineto -150.854 -167.501 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 164.877 545.803] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -90.4452 -130.798 moveto -60.847 -130.798 lineto -60.847 -112.219 lineto -90.4452 -112.219 lineto -90.4452 -130.798 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 225.285 509.1] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (value) [4.99 0 4.43 0 2.77 0 4.99 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -114.018 -136.009 moveto -36.0153 -136.009 lineto -36.0153 -97.008 lineto -114.018 -97.008 lineto -114.018 -136.009 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -75.8547 -136.5 moveto -75.8547 -202.502 lineto -92.8552 -202.502 lineto newpath -75.8547 -140.227 moveto -75.8547 -202.502 lineto -92.8552 -202.502 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -75.8547 -136.591 moveto -72.7643 -144.318 lineto -74.0977 -144.682 -75.1278 -144.863 -75.8547 -144.863 curveto -76.5816 -144.863 -77.6116 -144.682 -78.945 -144.318 curveto -75.8547 -136.591 lineto -75.8547 -136.591 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -93.8552 -219.503 moveto -78.6492 -219.503 lineto -78.6492 -200.924 lineto -93.8552 -200.924 lineto -93.8552 -219.503 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 221.875 597.805] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 21.6898 -369.707 moveto 96.743 -369.707 lineto 96.743 -351.128 lineto 21.6898 -351.128 lineto 21.6898 -369.707 lineto closepath grestore gsave gsave %IncludeFont: Times-Bold userdict begin BeachHead end begin [1 0 0 -1 337.42 748.009] concat /Times-Bold findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Apply-Dispatch) [7.21 0 5.55 0 5.55 0 2.77 0 4.99 0 3.32 0 7.21 0 2.77 0 3.88 0 5.55 0 4.99 0 3.32 0 4.43 0 5.55 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 11.567 -373.918 moveto 106.866 -373.918 lineto 106.866 -346.917 lineto 11.567 -346.917 lineto 11.567 -373.918 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2169 -346.917 moveto 70.6769 -346.917 80.4588 -348.235 88.5623 -350.871 curveto 96.6658 -353.507 100.718 -356.689 100.718 -360.417 curveto 100.718 -364.145 96.6658 -367.327 88.5623 -369.963 curveto 80.4588 -372.599 70.6769 -373.917 59.2169 -373.917 curveto 47.757 -373.917 37.9751 -372.599 29.8716 -369.963 curveto 21.7681 -367.327 17.7164 -364.145 17.7164 -360.417 curveto 17.7164 -356.689 21.7681 -353.507 29.8716 -350.871 curveto 37.9751 -348.235 47.757 -346.917 59.2169 -346.917 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 20.7152 -295.014 moveto 58.7164 -256.013 lineto 97.7176 -295.014 lineto 59.7164 -333.015 lineto 20.7152 -295.014 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 39.9848 -303.804 moveto 78.448 -303.804 lineto 78.448 -285.224 lineto 39.9848 -285.224 lineto 39.9848 -303.804 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 355.715 682.105] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Macro?) [8.88 0 4.43 0 4.43 0 3.32 0 4.99 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 17.7157 -242.018 moveto 100.717 -242.018 lineto 100.717 -215.017 lineto 17.7157 -215.017 lineto 17.7157 -242.018 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2163 -215.017 moveto 70.6763 -215.017 80.4582 -216.335 88.5617 -218.971 curveto 96.6652 -221.607 100.717 -224.79 100.717 -228.517 curveto 100.717 -232.245 96.6652 -235.428 88.5617 -238.063 curveto 80.4582 -240.699 70.6763 -242.018 59.2163 -242.018 curveto 47.7564 -242.018 37.9744 -240.699 29.8709 -238.063 curveto 21.7674 -235.428 17.7157 -232.245 17.7157 -228.517 curveto 17.7157 -224.79 21.7674 -221.607 29.8709 -218.971 curveto 37.9744 -216.335 47.7564 -215.017 59.2163 -215.017 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 24.5734 -241.674 moveto 93.8594 -241.674 lineto 93.8594 -215.361 lineto 24.5734 -215.361 lineto 24.5734 -241.674 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 340.304 619.976] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 10.9888 8.13782 moveto [1 0 0 -1 0 0] concat (\(ap-dis-1\)) [3.32 0 4.43 0 4.99 0 3.32 0 4.99 0 2.77 0 3.88 0 3.32 0 4.99 0 3.32 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 340.304 619.976] concat /Times-Roman findbeachheadfont 7.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 16.6037 moveto [1 0 0 -1 0 0] concat (\(no such label really\)) [2.33 0 3.49 0 3.49 0 2.45 0 2.72 0 3.49 0 3.10 0 3.49 0 2.45 0 1.94 0 3.10 0 3.49 0 3.10 0 1.94 0 2.45 0 2.33 0 3.10 0 3.10 0 1.94 0 1.94 0 3.49 0 2.33 0 ] 7.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -57.9884 -267.334 moveto 8.41164 -267.334 lineto 8.41164 -245.734 lineto -57.9884 -245.734 lineto -57.9884 -267.334 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -24.7886 -245.734 moveto -15.6208 -245.734 -7.79543 -246.788 -1.31277 -248.897 curveto 5.16992 -251.005 8.41121 -253.551 8.41121 -256.534 curveto 8.41121 -259.516 5.16988 -262.062 -1.31277 -264.17 curveto -7.79547 -266.279 -15.6208 -267.333 -24.7886 -267.333 curveto -33.9564 -267.333 -41.7818 -266.279 -48.2645 -264.17 curveto -54.7471 -262.062 -57.9884 -259.516 -57.9884 -256.534 curveto -57.9884 -253.551 -54.7472 -251.005 -48.2645 -248.897 curveto -41.7818 -246.788 -33.9564 -245.734 -24.7886 -245.734 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -49.2523 -263.965 moveto -0.324463 -263.965 lineto -0.324463 -249.102 lineto -49.2523 -249.102 lineto -49.2523 -263.965 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [0.799988 0 0 -0.799988 265.678 643.067] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Macro-return) [8.88 0 4.43 0 4.43 0 3.32 0 4.99 0 3.32 0 3.32 0 4.43 0 2.77 0 4.99 0 3.32 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 19.2154 -201.015 moveto 99.2175 -201.015 lineto 99.2175 -156.014 lineto 19.2154 -156.014 lineto 19.2154 -201.015 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 27.0701 -192.784 moveto 91.3628 -192.784 lineto 91.3628 -164.245 lineto 27.0701 -164.245 lineto 27.0701 -192.784 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 342.801 571.086] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (get proc from) [4.99 0 4.43 0 2.77 0 3.50 0 4.99 0 3.32 0 4.99 0 4.43 0 3.50 0 3.32 0 3.32 0 4.99 0 7.77 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 342.801 571.086] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 7.2919 18.0976 moveto [1 0 0 -1 0 0] concat (name, etc.) [4.99 0 4.43 0 7.77 0 4.43 0 2.49 0 3.50 0 4.43 0 2.77 0 4.43 0 2.49 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 19.2154 -201.015 moveto 99.2175 -201.015 lineto 99.2175 -156.014 lineto 19.2154 -156.014 lineto 19.2154 -201.015 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 20.7152 -102.008 moveto 58.7164 -63.0069 lineto 97.7176 -102.008 lineto 59.7164 -140.009 lineto 20.7152 -102.008 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 34.6327 -110.798 moveto 83.8001 -110.798 lineto 83.8001 -92.2185 lineto 34.6327 -92.2185 lineto 34.6327 -110.798 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 350.363 489.099] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Primitive?) [5.55 0 3.32 0 2.77 0 7.77 0 2.77 0 2.77 0 2.53 0 4.85 0 4.43 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 19.2154 -46.0108 moveto 99.2175 -46.0108 lineto 99.2175 -1.0098 lineto 19.2154 -1.0098 lineto 19.2154 -46.0108 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 42.3876 -32.7999 moveto 76.0453 -32.7999 lineto 76.0453 -14.2208 lineto 42.3876 -14.2208 lineto 42.3876 -32.7999 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 358.118 411.102] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Call it) [6.66 0 4.43 0 2.77 0 2.77 0 3.50 0 2.77 0 2.77 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2163 109.035 moveto 70.6763 109.035 80.4582 107.717 88.5617 105.081 curveto 96.6652 102.445 100.717 99.2625 100.717 95.5346 curveto 100.717 91.8067 96.6652 88.6244 88.5617 85.9886 curveto 80.4582 83.3527 70.6763 82.0345 59.2163 82.0345 curveto 47.7564 82.0345 37.9744 83.3527 29.8709 85.9886 curveto 21.7674 88.6244 17.7157 91.8067 17.7157 95.5346 curveto 17.7157 99.2625 21.7674 102.445 29.8709 105.081 curveto 37.9744 107.717 47.7564 109.035 59.2163 109.035 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 24.1932 86.2449 moveto 94.2391 86.2449 lineto 94.2391 104.824 lineto 24.1932 104.824 lineto 24.1932 86.2449 lineto closepath grestore gsave gsave %IncludeFont: Times-Bold userdict begin BeachHead end begin [1 0 0 -1 339.924 292.057] concat /Times-Bold findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Macro-Return) [9.42 0 4.99 0 4.43 0 4.43 0 4.99 0 3.32 0 7.21 0 4.43 0 3.32 0 5.55 0 4.43 0 5.55 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 20.7152 166.992 moveto 58.7164 205.993 lineto 97.7176 166.992 lineto 59.7164 128.991 lineto 20.7152 166.992 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 24.7582 158.202 moveto 93.6747 158.202 lineto 93.6747 176.781 lineto 24.7582 176.781 lineto 24.7582 158.202 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 340.489 220.1] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (\324continuation\325?) [3.32 0 4.43 0 4.99 0 4.99 0 2.77 0 2.77 0 4.99 0 4.99 0 4.43 0 2.77 0 2.77 0 4.99 0 4.99 0 3.32 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 20.7152 258.991 moveto 58.7164 297.993 lineto 97.7176 258.991 lineto 59.7164 220.99 lineto 20.7152 258.991 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 37.6901 250.202 moveto 80.7427 250.202 lineto 80.7427 268.781 lineto 37.6901 268.781 lineto 37.6901 250.202 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 353.421 128.1] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (tail call?) [2.77 0 4.43 0 2.77 0 2.77 0 3.50 0 4.43 0 4.43 0 2.77 0 2.77 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 34.163 315.74 moveto 84.2699 315.74 lineto 84.2699 334.319 lineto 34.163 334.319 lineto 34.163 315.74 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 349.894 62.5621] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Begin-Seq) [6.66 0 4.43 0 4.99 0 2.77 0 4.99 0 3.32 0 5.55 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 17.7157 311.529 moveto 100.717 311.529 lineto 100.717 338.529 lineto 17.7157 338.529 lineto 17.7157 311.529 lineto closepath grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.2163 338.529 moveto 70.6763 338.529 80.4582 337.211 88.5617 334.575 curveto 96.6652 331.939 100.717 328.757 100.717 325.029 curveto 100.717 321.301 96.6652 318.119 88.5617 315.483 curveto 80.4582 312.847 70.6763 311.529 59.2163 311.529 curveto 47.7564 311.529 37.9744 312.847 29.8709 315.483 curveto 21.7674 318.119 17.7157 321.301 17.7157 325.029 curveto 17.7157 328.757 21.7674 331.939 29.8709 334.575 curveto 37.9744 337.211 47.7564 338.529 59.2163 338.529 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -82.5192 151.993 moveto -2.51729 151.993 lineto -2.51729 180.994 lineto -82.5192 180.994 lineto -82.5192 151.993 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -68.1164 157.204 moveto -16.9201 157.204 lineto -16.9201 175.783 lineto -68.1164 175.783 lineto -68.1164 157.204 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 247.614 221.098] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Preprocess) [5.55 0 3.32 0 4.43 0 4.99 0 3.32 0 4.99 0 4.43 0 4.43 0 3.88 0 3.88 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -2.51704 195.996 moveto -2.51704 240.997 lineto -82.5195 240.997 lineto -82.5195 211.996 lineto -67.519 195.996 lineto -2.51704 195.996 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -67.5717 209.207 moveto -17.4648 209.207 lineto -17.4648 227.786 lineto -67.5717 227.786 lineto -67.5717 209.207 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 248.159 169.095] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Begin-Seq) [6.66 0 4.43 0 4.99 0 2.77 0 4.99 0 3.32 0 5.55 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 7.48187 -307.819 moveto 7.48187 -282.219 lineto -56.5185 -282.219 lineto -56.5185 -298.717 lineto -44.5184 -307.819 lineto 7.48187 -307.819 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -43.4414 -302.45 moveto -5.59526 -302.45 lineto -5.59526 -287.587 lineto -43.4414 -287.587 lineto -43.4414 -302.45 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [0.799988 0 0 -0.799988 271.489 681.552] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (\(ap-dis-1\)) [3.32 0 4.43 0 4.99 0 3.32 0 4.99 0 2.77 0 3.88 0 3.32 0 4.99 0 3.32 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 14.2207 147.598 moveto 29.4267 147.598 lineto 29.4267 166.177 lineto 14.2207 166.177 lineto 14.2207 147.598 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 329.951 230.704] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 42.2216 198.6 moveto 57.4276 198.6 lineto 57.4276 217.179 lineto 42.2216 217.179 lineto 42.2216 198.6 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 357.952 179.702] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 58.222 292.602 moveto 73.4281 292.602 lineto 73.4281 311.181 lineto 58.222 311.181 lineto 58.222 292.602 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 373.953 85.6994] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 98.9889 287.994 moveto 138.99 326.995 lineto 176.991 287.994 lineto 98.9889 287.994 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 116.079 285.604 moveto 159.902 285.604 lineto 159.902 314.953 lineto 116.079 314.953 lineto 116.079 285.604 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 431.809 92.6979] concat /Times-Roman findbeachheadfont 7.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 5.69647 moveto [1 0 0 -1 0 0] concat (returned exp) [2.33 0 3.10 0 1.94 0 3.49 0 2.33 0 3.49 0 3.10 0 3.49 0 2.45 0 3.10 0 3.49 0 3.49 0 ] 7.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 431.809 92.6979] concat /Times-Roman findbeachheadfont 7.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 7.95279 12.6683 moveto [1 0 0 -1 0 0] concat (will be) [5.05 0 1.94 0 1.94 0 1.94 0 2.45 0 3.49 0 3.10 0 ] 7.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 431.809 92.6979] concat /Times-Roman findbeachheadfont 7.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 4.07269 19.6402 moveto [1 0 0 -1 0 0] concat (spliced in) [2.72 0 3.49 0 1.94 0 1.94 0 3.10 0 3.10 0 3.49 0 2.45 0 1.94 0 3.49 0 ] 7.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 94.2231 242.603 moveto 109.429 242.603 lineto 109.429 261.182 lineto 94.2231 261.182 lineto 94.2231 242.603 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 409.954 135.699] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 -340.982 moveto 211.172 -340.982 220.954 -342.3 229.058 -344.936 curveto 237.161 -347.572 241.213 -350.754 241.213 -354.482 curveto 241.213 -358.21 237.161 -361.392 229.058 -364.028 curveto 220.954 -366.664 211.172 -367.982 199.712 -367.982 curveto 188.252 -367.982 178.47 -366.664 170.367 -364.028 curveto 162.263 -361.392 158.212 -358.21 158.212 -354.482 curveto 158.212 -350.754 162.263 -347.572 170.367 -344.936 curveto 178.47 -342.3 188.252 -340.982 199.712 -340.982 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 157.183 -363.772 moveto 242.241 -363.772 lineto 242.241 -345.193 lineto 157.183 -345.193 lineto 157.183 -363.772 lineto closepath grestore gsave gsave %IncludeFont: Times-Bold userdict begin BeachHead end begin [1 0 0 -1 472.914 742.074] concat /Times-Bold findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Compound-Apply) [7.21 0 4.99 0 8.32 0 5.55 0 4.99 0 5.55 0 5.55 0 5.55 0 3.32 0 7.21 0 5.55 0 5.55 0 2.77 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 159.711 -320.502 moveto 239.713 -320.502 lineto 239.713 -275.501 lineto 159.711 -275.501 lineto 159.711 -320.502 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 166.267 -312.27 moveto 233.157 -312.27 lineto 233.157 -283.732 lineto 166.267 -283.732 lineto 166.267 -312.27 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 481.998 690.572] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 13.8424 8.13782 moveto [1 0 0 -1 0 0] concat (loop on) [2.77 0 4.99 0 4.99 0 4.99 0 3.50 0 4.99 0 4.99 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 481.998 690.572] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 18.0976 moveto [1 0 0 -1 0 0] concat (formal params) [3.32 0 4.99 0 3.32 0 7.77 0 4.43 0 2.77 0 3.50 0 4.99 0 4.43 0 3.32 0 4.43 0 7.77 0 3.88 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 161.211 -209.011 moveto 199.212 -170.01 lineto 238.213 -209.011 lineto 200.212 -247.013 lineto 161.211 -209.011 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 179.371 -227.761 moveto 220.053 -227.761 lineto 220.053 -189.262 lineto 179.371 -189.262 lineto 179.371 -227.761 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 495.102 606.063] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.824539 8.13782 moveto [1 0 0 -1 0 0] concat (missing) [7.77 0 2.77 0 3.88 0 3.88 0 2.77 0 4.99 0 4.99 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 495.102 606.063] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 18.0976 moveto [1 0 0 -1 0 0] concat (optional) [4.99 0 4.99 0 2.77 0 2.77 0 4.99 0 4.99 0 4.43 0 2.77 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 495.102 606.063] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 7.84569 28.0574 moveto [1 0 0 -1 0 0] concat (arg?) [4.43 0 3.15 0 4.99 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 212.423 -135.407 moveto 287.563 -135.407 lineto 287.563 -107.61 lineto 212.423 -107.61 lineto 212.423 -135.407 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 528.154 513.709] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 5.04567 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Dispatch) [6.10 0 4.99 0 4.43 0 2.77 0 3.32 0 7.21 0 2.77 0 3.88 0 4.99 0 4.43 0 2.77 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 528.154 513.709] concat /Times-Roman findbeachheadfont 9.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 17.5996 moveto [1 0 0 -1 0 0] concat (\(for default value\)) [2.99 0 2.99 0 4.49 0 2.99 0 3.15 0 4.49 0 3.99 0 2.99 0 3.99 0 4.49 0 2.49 0 2.49 0 3.15 0 4.49 0 3.99 0 2.49 0 4.49 0 3.99 0 2.99 0 ] 9.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 159.711 -65.0114 moveto 239.713 -65.0114 lineto 239.713 -20.0103 lineto 159.711 -20.0103 lineto 159.711 -65.0114 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 171.254 -56.7803 moveto 228.17 -56.7803 lineto 228.17 -28.2414 lineto 171.254 -28.2414 lineto 171.254 -56.7803 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 486.984 435.082] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.545609 8.13782 moveto [1 0 0 -1 0 0] concat (Bind param) [6.66 0 2.77 0 4.99 0 4.99 0 3.50 0 4.99 0 4.43 0 3.32 0 4.43 0 7.77 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 486.984 435.082] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 18.0976 moveto [1 0 0 -1 0 0] concat (to arg value) [2.77 0 4.99 0 3.50 0 4.43 0 3.15 0 4.99 0 3.50 0 4.99 0 4.43 0 2.77 0 4.99 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 161.211 40.9962 moveto 199.212 79.9974 lineto 238.213 40.9962 lineto 200.212 2.99503 lineto 161.211 40.9962 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 182.694 32.2067 moveto 216.73 32.2067 lineto 216.73 50.7857 lineto 182.694 50.7857 lineto 182.694 32.2067 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 498.425 346.095] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Done?) [7.21 0 4.99 0 4.99 0 4.43 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 159.711 106.994 moveto 239.713 106.994 lineto 239.713 151.995 lineto 159.711 151.995 lineto 159.711 106.994 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 166.176 120.205 moveto 233.248 120.205 lineto 233.248 138.784 lineto 166.176 138.784 lineto 166.176 120.205 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 481.907 258.097] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Get proc body) [7.21 0 4.43 0 2.77 0 3.50 0 4.99 0 3.32 0 4.99 0 4.43 0 3.50 0 4.99 0 4.99 0 4.99 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 199.712 213.027 moveto 211.172 213.027 220.954 211.708 229.057 209.072 curveto 237.161 206.437 241.213 203.254 241.213 199.526 curveto 241.213 195.798 237.161 192.616 229.057 189.98 curveto 220.954 187.344 211.172 186.026 199.712 186.026 curveto 188.252 186.026 178.47 187.344 170.367 189.98 curveto 162.263 192.616 158.211 195.798 158.211 199.526 curveto 158.211 203.254 162.263 206.437 170.367 209.072 curveto 178.47 211.708 188.252 213.027 199.712 213.027 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 165.804 190.237 moveto 233.621 190.237 lineto 233.621 208.816 lineto 165.804 208.816 lineto 165.804 190.237 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 481.534 188.065] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Sequence) [6.10 0 4.99 0 4.43 0 2.77 0 3.32 0 5.55 0 4.43 0 4.99 0 4.99 0 4.43 0 4.99 0 4.43 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 234.714 -223.469 moveto 249.92 -223.469 lineto 249.92 -204.89 lineto 234.714 -204.89 lineto 234.714 -223.469 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 550.445 601.771] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 185.713 -173.467 moveto 200.919 -173.467 lineto 200.919 -154.888 lineto 185.713 -154.888 lineto 185.713 -173.467 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 501.443 551.769] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 59.709 -68.4641 moveto 74.9151 -68.4641 lineto 74.9151 -49.885 lineto 59.709 -49.885 lineto 59.709 -68.4641 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 375.44 446.766] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 157.712 -356.47 moveto 122.712 -356.47 lineto 122.712 -102.462 lineto 99.7102 -102.462 lineto newpath 153.985 -356.47 moveto 122.712 -356.47 lineto 122.712 -102.462 lineto 99.7102 -102.462 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 157.621 -356.47 moveto 149.895 -359.56 lineto 149.531 -358.227 149.349 -357.197 149.349 -356.47 curveto 149.349 -355.743 149.531 -354.713 149.895 -353.38 curveto 157.621 -356.47 lineto 157.621 -356.47 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 94.7101 -117.463 moveto 109.916 -117.463 lineto 109.916 -98.8835 lineto 94.7101 -98.8835 lineto 94.7101 -117.463 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 410.441 495.764] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 41.7085 -262.467 moveto 56.9145 -262.467 lineto 56.9145 -243.888 lineto 41.7085 -243.888 lineto 41.7085 -262.467 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 357.439 640.769] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 17.7121 -362.022 moveto -70.7881 -362.272 lineto -70.7881 -230.272 lineto -12.7881 -230.272 lineto -12.7881 95.7275 lineto -62.7881 95.7275 lineto newpath 13.9904 -362.033 moveto -70.7881 -362.272 lineto -70.7881 -230.272 lineto -12.7881 -230.272 lineto -12.7881 95.7275 lineto -62.7881 95.7275 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 17.6213 -362.023 moveto 9.90306 -365.135 lineto 9.53586 -363.803 9.3512 -362.773 9.34915 -362.046 curveto 9.34711 -361.319 9.52591 -360.289 9.8856 -358.954 curveto 17.6213 -362.023 lineto 17.6213 -362.023 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 14.2205 -311.398 moveto 29.4265 -311.398 lineto 29.4265 -292.819 lineto 14.2205 -292.819 lineto 14.2205 -311.398 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 329.951 689.7] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -80.7822 255.103 moveto -0.780243 255.103 lineto -0.780243 284.104 lineto -80.7822 284.104 lineto -80.7822 255.103 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -80.7822 255.103 moveto -0.780243 255.103 lineto -0.780243 284.104 lineto -80.7822 284.104 lineto -80.7822 255.103 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -68.3233 260.314 moveto -13.2392 260.314 lineto -13.2392 278.893 lineto -68.3233 278.893 lineto -68.3233 260.314 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 247.407 117.988] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Postprocess) [5.55 0 4.99 0 3.88 0 2.77 0 4.99 0 3.32 0 4.99 0 4.43 0 4.43 0 3.88 0 3.88 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -65.5182 77.2455 moveto -50.3122 77.2455 lineto -50.3122 95.8245 lineto -65.5182 95.8245 lineto -65.5182 77.2455 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 250.212 301.056] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 200.216 75.5852 moveto 215.422 75.5852 lineto 215.422 94.1643 lineto 200.216 94.1643 lineto 200.216 75.5852 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 515.946 302.717] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Y) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 159.712 -300.482 moveto 145.712 -300.482 lineto 145.712 40.5178 lineto 160.712 40.5178 lineto newpath 155.985 -300.482 moveto 145.712 -300.482 lineto 145.712 40.5178 lineto 160.712 40.5178 lineto userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 159.621 -300.482 moveto 151.894 -303.573 lineto 151.531 -302.239 151.349 -301.209 151.349 -300.482 curveto 151.349 -299.755 151.531 -298.725 151.894 -297.392 curveto 159.621 -300.482 lineto 159.621 -300.482 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end gsave eofill grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat 149.712 41.5178 moveto 164.918 41.5178 lineto 164.918 60.0969 lineto 149.712 60.0969 lineto 149.712 41.5178 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 465.443 336.784] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (N) [7.21 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -267.1 293.212 moveto -215.752 293.212 lineto -215.752 321.751 lineto -267.1 321.751 lineto -267.1 293.212 lineto closepath userdict begin BeachHead end begin 0 0 0 0 bhsetcmykcolor end gsave eofill grestore grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 48.631 85.0902] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 1.36925 8.13782 moveto [1 0 0 -1 0 0] concat (Check for) [6.66 0 4.99 0 4.43 0 4.43 0 4.99 0 3.50 0 3.32 0 4.99 0 3.32 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 48.631 85.0902] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 18.0976 moveto [1 0 0 -1 0 0] concat (errors, etc.) [4.43 0 3.32 0 3.32 0 4.99 0 3.32 0 3.88 0 2.49 0 3.50 0 4.43 0 2.77 0 4.43 0 2.49 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -281.427 284.981 moveto -201.424 284.981 lineto -201.424 329.982 lineto -281.427 329.982 lineto -281.427 284.981 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -272.656 221.231 moveto -210.195 221.231 lineto -210.195 259.73 lineto -272.656 259.73 lineto -272.656 221.231 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 43.0741 157.07] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Maybe splice) [8.88 0 4.43 0 4.99 0 4.99 0 4.43 0 3.50 0 3.88 0 4.99 0 2.77 0 2.77 0 4.43 0 4.43 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 43.0741 157.07] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 1.11438 18.0976 moveto [1 0 0 -1 0 0] concat (macro return) [7.77 0 4.43 0 4.43 0 3.32 0 4.99 0 3.50 0 3.32 0 4.43 0 2.77 0 4.99 0 3.32 0 4.99 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 43.0741 157.07] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 6.92119 28.0574 moveto [1 0 0 -1 0 0] concat (into Unev) [2.77 0 4.99 0 2.77 0 4.99 0 3.50 0 7.21 0 4.99 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -281.427 217.98 moveto -201.424 217.98 lineto -201.424 262.981 lineto -281.427 262.981 lineto -281.427 217.98 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -281.427 217.98 moveto -201.424 217.98 lineto -201.424 262.981 lineto -281.427 262.981 lineto -281.427 217.98 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.5 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -201.424 157.996 moveto -201.424 202.998 lineto -281.427 202.998 lineto -281.427 173.997 lineto -266.426 157.996 lineto -201.424 157.996 lineto closepath userdict begin BeachHead end begin 0 0 0 0 bhsetcmykcolor end gsave eofill grestore userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -275.344 171.207 moveto -210.295 171.207 lineto -210.295 189.786 lineto -275.344 189.786 lineto -275.344 171.207 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 40.3865 207.094] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Dispatch) [6.10 0 4.99 0 4.43 0 2.77 0 3.32 0 7.21 0 2.77 0 3.88 0 4.99 0 4.43 0 2.77 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -241.426 134.99 moveto -229.966 134.99 -220.184 133.672 -212.081 131.036 curveto -203.977 128.4 -199.926 125.218 -199.926 121.49 curveto -199.926 117.762 -203.977 114.58 -212.081 111.944 curveto -220.184 109.308 -229.966 107.99 -241.426 107.99 curveto -252.886 107.99 -262.668 109.308 -270.772 111.944 curveto -278.875 114.58 -282.927 117.762 -282.927 121.49 curveto -282.927 125.218 -278.875 128.4 -270.772 131.036 curveto -262.668 133.672 -252.886 134.99 -241.426 134.99 curveto closepath userdict begin BeachHead end begin 0 0 0 0 bhsetcmykcolor end gsave eofill grestore userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -274.505 112.2 moveto -208.347 112.2 lineto -208.347 130.779 lineto -274.505 130.779 lineto -274.505 112.2 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 41.2254 266.102] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Non-Tail-Eval) [7.21 0 4.99 0 4.99 0 3.32 0 6.10 0 4.43 0 2.77 0 2.77 0 3.32 0 6.10 0 4.99 0 4.43 0 2.77 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -272.247 -39.7833 moveto -209.604 -39.7833 lineto -209.604 -11.2444 lineto -272.247 -11.2444 lineto -272.247 -39.7833 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 43.4832 418.085] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Pop one expr) [5.55 0 4.99 0 4.99 0 3.50 0 4.99 0 4.99 0 4.43 0 3.50 0 4.43 0 4.99 0 4.99 0 3.32 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 43.4832 418.085] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 5.07312 18.0976 moveto [1 0 0 -1 0 0] concat (from Unev) [3.32 0 3.32 0 4.99 0 7.77 0 3.50 0 7.21 0 4.99 0 4.43 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -280.927 -48.0143 moveto -200.924 -48.0143 lineto -200.924 -3.01331 lineto -280.927 -3.01331 lineto -280.927 -48.0143 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -276.233 -86.0135 moveto -205.618 -86.0135 lineto -205.618 -67.4345 lineto -276.233 -67.4345 lineto -276.233 -86.0135 lineto closepath grestore gsave gsave %IncludeFont: Times-Bold userdict begin BeachHead end begin [1 0 0 -1 39.4972 464.315] concat /Times-Bold findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Eval-Sequence) [6.66 0 4.99 0 4.99 0 2.77 0 3.32 0 5.55 0 4.43 0 5.55 0 5.55 0 4.43 0 5.55 0 4.43 0 4.43 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -240.926 -63.2238 moveto -229.466 -63.2238 -219.684 -64.542 -211.58 -67.1779 curveto -203.477 -69.8138 -199.425 -72.996 -199.425 -76.7239 curveto -199.425 -80.4518 -203.477 -83.6341 -211.58 -86.27 curveto -219.684 -88.9059 -229.466 -90.2241 -240.926 -90.2241 curveto -252.386 -90.2241 -262.167 -88.9059 -270.271 -86.27 curveto -278.374 -83.6341 -282.426 -80.4518 -282.426 -76.7239 curveto -282.426 -72.996 -278.374 -69.8138 -270.271 -67.1779 curveto -262.167 -64.542 -252.386 -63.2238 -240.926 -63.2238 curveto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 2 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -267.934 -145.786 moveto -213.917 -145.786 lineto -213.917 -117.248 lineto -267.934 -117.248 lineto -267.934 -145.786 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 47.7968 524.088] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 8.13782 moveto [1 0 0 -1 0 0] concat (Parse Logo) [5.41 0 4.43 0 3.32 0 3.88 0 4.43 0 3.50 0 6.10 0 4.99 0 4.99 0 4.99 0 ] 10.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 47.7968 524.088] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 4.63745 18.0976 moveto [1 0 0 -1 0 0] concat (into Lisp) [2.77 0 4.99 0 2.77 0 4.99 0 3.50 0 6.10 0 2.77 0 3.88 0 4.99 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -280.927 -154.018 moveto -200.924 -154.018 lineto -200.924 -109.017 lineto -280.927 -109.017 lineto -280.927 -154.018 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -56.0199 368.996 moveto -56.0199 377.996 lineto -72.0201 377.996 lineto -72.0201 372.196 lineto -69.0201 368.996 lineto -56.0199 368.996 lineto closepath userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0.25 setlinewidth 0 setlinecap 0 setlinejoin stroke grestore gsave newpath [1 0 0 -1 311.731 382.302] concat -167.851 348.516 moveto 165.999 348.516 lineto 165.999 382.302 lineto -167.851 382.302 lineto -167.851 348.516 lineto closepath grestore gsave gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 147.879 29.786] concat /Times-Roman findbeachheadfont 14.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 46.0851 11.3929 moveto [1 0 0 -1 0 0] concat (UCBLogo evaluator simpli\336ed \337owchart) [10.10 0 9.33 0 9.33 0 8.54 0 6.99 0 6.99 0 6.99 0 4.90 0 6.21 0 6.99 0 6.21 0 3.88 0 6.99 0 6.21 0 3.88 0 6.99 0 4.65 0 4.90 0 5.43 0 3.88 0 10.88 0 6.99 0 3.88 0 3.88 0 7.77 0 6.21 0 6.99 0 4.90 0 7.77 0 6.99 0 10.10 0 6.21 0 6.99 0 6.21 0 4.65 0 3.88 0 ] 14.00 krnshow end grestore gsave %IncludeFont: Times-Roman userdict begin BeachHead end begin [1 0 0 -1 147.879 29.786] concat /Times-Roman findbeachheadfont 10.00 scalefont setfont userdict begin BeachHead end begin 0 0 0 1 bhsetcmykcolor end 0 23.3447 moveto [1 0 0 -1 0 0] concat (\(Procedure-call boxes imply data stack allocation as well as control \337ow.\)) [3.32 0 5.55 0 3.32 0 4.99 0 4.43 0 4.43 0 4.99 0 4.99 0 3.32 0 4.43 0 3.32 0 4.43 0 4.43 0 2.77 0 2.77 0 3.50 0 4.99 0 4.99 0 4.85 0 4.43 0 3.88 0 3.50 0 3.50 0 3.50 0 3.50 0 3.50 0 3.50 0 3.50 0 2.77 0 7.77 0 4.99 0 2.77 0 4.99 0 3.50 0 4.99 0 4.43 0 2.77 0 4.43 0 3.50 0 3.88 0 2.77 0 4.43 0 4.43 0 4.99 0 3.50 0 4.43 0 2.77 0 2.77 0 4.99 0 4.43 0 4.43 0 2.77 0 2.77 0 4.99 0 4.99 0 3.50 0 4.43 0 3.88 0 3.50 0 7.21 0 4.43 0 2.77 0 2.77 0 3.50 0 4.43 0 3.88 0 3.50 0 4.43 0 4.99 0 4.99 0 2.77 0 3.32 0 4.99 0 2.77 0 3.50 0 5.55 0 4.99 0 7.21 0 2.49 0 3.32 0 ] 10.00 krnshow end grestore grestore gsave newpath [1 0 0 -1 311.731 382.302] concat grestore %%EndDocument @endspecial 1299 5449 a Fa()p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF ucblogo-5.5/Messages0100644000161300001330000000524310274571501012430 0ustar bhdoe; UCBLogo message file version 5.5 ; Error messages -- position in this file corresponds to error number ; Lines starting with semicolon don't count in the line numbering ; and may be added at will. Logo: Fatal Internal Error. out of space stack overflow turtle out of bounds %p doesn't like %s as input %p didn't output to %p not enough inputs to %p %p doesn't like %s as input too many inputs to %p You don't say what to do with %s too many ('s %s has no value unexpected ')' I don't know how to %p Can't find catch tag for %p %p is already defined Stopping... Already dribbling File system error: %p Assuming you mean IFELSE, not IF %p shadowed by local in procedure call Throw "Error %p is a primitive Can't use TO inside a procedure I don't know how to %p %p without TEST unexpected ']' unexpected '}' couldn't initialize graphics Macro returned %s instead of a list You don't say what to do with %s Can only use %p inside a procedure APPLY doesn't like %s as input END inside multi-line instruction in %p Logo: Out of Memory. %p END inside multi-line instruction Bad default expression for optional input: %s Can't use OUTPUT or STOP inside RUNRESULT Assuming you meant '%p', not %p I can't open file %p File %p already open File %p not open ; Variable name %s is defined both dynamically and in current object ; Non-error messages (no numeric error code for these) Thank you for using Logo. Have a nice day. Sorry, no shell on the Mac. Type EXIT to return to Logo. in %s\n%s Erract loop Pausing... stops outputs File not found: %t\n Can't KEYP, no FIONREAD on this system Not enough memory I can't open that file File already open File not open Pprop Welcome to Berkeley Logo version %t You must be in a procedure to use OUTPUT or STOP. Warning: Not enough memory to run garbage collector. GC disabled - Save important data and exit! %s defined\n Make %s %s to %p\nend\n\n Plist %s = %s\n No help available.\n No help available on %p.\n --more-- ; Logo special words, used mostly in Logo-generated messages ; TRUE and FALSE are generated by predicates and accepted by IF etc. true false ; End of a procedure end ; Some names of primitives treated specially in the evaluator ; (You still have to COPYDEF them to match any changes here.) output stop goto tag if ifelse to .macro ; Special CATCH tags toplevel system error ; How no-value prints in error messages nothing ; Outputs from SCREENMODE textscreen splitscreen fullscreen ; Outputs from PENMODE paint erase reverse ; Outputs from TURTLEMODE wrap fence window ; HELP turns infix operators +-*/=<> into these sum difference product quotient equalp lessp greaterp lessequalp greaterequalp notequalp ; Object stuff name class self licenseplate initlist exist ucblogo-5.5/Messages.sp0100644000161300001330000000462710274571650013063 0ustar bhdoe; Spanish version of Berkeley Logo messages file 5.5 Logo: Error Interno Fatal. no hay espacio desborde de pila tortuga fuera de los límites a %p no le gustó recibir %s %p no entregó nada a %p %p necesita recibir más cosas a %p no le gustó recibir %s demasiadas cosas entre paréntesis () No dices qué debo hacer con %s demasiados paréntesis '(' %s no tiene un valor todavía paréntesis ')' inesperado no sé cómo realizar %p no puedo encontrar la etiqueta LANZA para %p %p ya está definida Parando... DRIBBLE está activado Error del sistema de archivos: %p Asumo que querías decir SIOTRO, no SI %p cubierta por local en llamada a procedimiento ATRAPA "Error %p es una primitiva No puedes usar PARA dentro de un procedimiento no se cómo realizar %p %p sin PRUEBA corchete ']' inesperado llave '}' inesperada no pude inicializar gráficas Macro entregó %s en lugar de una lista No dices qué debo hacer con %s Solo puedes usar %p dentro de un procedimiento a APLICA no le gustó recibir %s FIN dentro de una instrucción multi-línea en %p Logo: Falta de Memoria. %p FIN dentro de una instrucción multi-línea Mala expresión por defecto para parámetro opcional: %s No puedes usar RESPUESTA o ALTO dentro de ACTIVARESULTADO Asumo que querías decir '%p', no %p No puedo abrir archivo %p Archivo %p ya está abierto Archivo %p no está abierto Gracias por usar Logo. Que tengas un buen día. Lo lamento, no hay 'shell' en la Mac. Escribe EXIT para retornar a Logo. en %s\n%s Lazo ERRACT Pausando... se detuvo responde Archivo no encontrado: %t\n No se puede usar TECLAP, no hay FIONREAD en este sistema No hay suficiente memoria No puedo abrir ese archivo Archivo ya está abierto Archivo no está abierto Pprop Bienvenido a Berkeley Logo versión %t Debes estar dentro de un procedimiento para usar REPUESTA o ALTO. Advertencia: No hay suficiente memoria para ejecutar el recolector de basura. GC deshabilitado - Guarda información importante a disco y sal! %s definido\n DA %s %s PARA %p\nFIN\n\n Plista %s = %s\n No hay ayuda disponible.\n No hay ayuda disponible para %p.\n --más-- cierto falso fin respuesta alto saltoa etiqueta si siotro para .macro toplevel sistema error nada ; Outputs from SCREENMODE textscreen splitscreen fullscreen ; Outputs from PENMODE paint erase reverse ; Outputs from TURTLEMODE wrap fence window ; HELP turns infix operators +-*/=<> into these sum difference product quotient equalp lessp greaterp lessequalp greaterequalp notequalp ucblogo-5.5/configure0100755000161300001330000017214610276423334012656 0ustar bhdoe#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.10 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-x use the X Window System" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' if test -e /bin/gmake -o -e /usr/bin/gmake ; then themake=gmake else themake=make fi # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.10" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LANG+set}" = set; then LANG=C; export LANG; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=coms.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes if test "${CFLAGS+set}" != set; then echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_gcc_g=yes else ac_cv_prog_gcc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 if test $ac_cv_prog_gcc_g = yes; then CFLAGS="-g -O" else CFLAGS="-O" fi fi else GCC= test "${CFLAGS+set}" = set || CFLAGS="-g" fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:667: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:682: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then echo "$ac_t""yes" 1>&6 ISC=yes # If later tests want to check for ISC. cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF if test "$GCC" = yes; then CC="$CC -posix" else CC="$CC -Xp" fi else echo "$ac_t""no" 1>&6 ISC= fi # If we find X, set shell vars x_includes and x_libraries to the # paths, otherwise set no_x=yes. # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" : fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=NO ac_x_libraries=NO rm -fr conftestdir if mkdir conftestdir; then cd conftestdir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat > Imakefile <<'EOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' EOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. case "$ac_im_incroot" in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; esac case "$ac_im_usrlibdir" in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; esac fi cd .. rm -fr conftestdir fi if test "$ac_x_includes" = NO; then # Guess where to find include files, by looking for this one X11 .h file. test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:791: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* # We can compile using X headers with no special include directory. ac_x_includes= else echo "$ac_err" >&5 rm -rf conftest* # Look for the header file in a standard set of common directories. for ac_dir in \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ /usr/X11/include \ /usr/include/X11 \ /usr/local/X11/include \ /usr/local/include/X11 \ \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ \ /usr/include \ /usr/local/include \ /usr/unsupported/include \ /usr/athena/include \ /usr/local/x11r5/include \ /usr/lpp/Xamples/include \ \ /usr/openwin/include \ /usr/openwin/share/include \ ; \ do if test -r "$ac_dir/$x_direct_test_include"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest* fi # $ac_x_includes = NO if test "$ac_x_libraries" = NO; then # Check for the libraries. test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries= else rm -rf conftest* LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ /usr/X11R6/lib \ /usr/X11R5/lib \ /usr/X11R4/lib \ \ /usr/lib/X11R6 \ /usr/lib/X11R5 \ /usr/lib/X11R4 \ \ /usr/local/X11R6/lib \ /usr/local/X11R5/lib \ /usr/local/X11R4/lib \ \ /usr/local/lib/X11R6 \ /usr/local/lib/X11R5 \ /usr/local/lib/X11R4 \ \ /usr/X11/lib \ /usr/lib/X11 \ /usr/local/X11/lib \ /usr/local/lib/X11 \ \ /usr/X386/lib \ /usr/x386/lib \ /usr/XFree86/lib/X11 \ \ /usr/lib \ /usr/local/lib \ /usr/unsupported/lib \ /usr/athena/lib \ /usr/local/x11r5/lib \ /usr/lpp/Xamples/lib \ \ /usr/openwin/lib \ /usr/openwin/share/lib \ ; \ do for ac_extension in a so sl; do if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest* fi # $ac_x_libraries = NO if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$ac_t""$have_x" 1>&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. X_CFLAGS="$X_CFLAGS -DX_DISPLAY_MISSING" else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would be nice to have a more robust check for the -R ld option than # just checking for Solaris. # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" if test "`(uname) 2>/dev/null`" = SunOS && uname -r | grep '^5' >/dev/null; then X_LIBS="$X_LIBS -R $x_libraries" fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for -lICE""... $ac_c" 1>&6 ac_lib_var=`echo ICE'_'IceConnectionNumber | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lICE $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" else echo "$ac_t""no" 1>&6 fi LDFLAGS="$ac_save_LDFLAGS" # Check for system-dependent libraries X programs must link with. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for -ldnet""... $ac_c" 1>&6 ac_lib_var=`echo dnet'_'dnet_ntoa | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" else echo "$ac_t""no" 1>&6 fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for -ldnet_stub""... $ac_c" 1>&6 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" else echo "$ac_t""no" 1>&6 fi fi # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Not sure which flavor of 386 UNIX this is, but it seems harmless to # check for it. echo $ac_n "checking for -lnsl""... $ac_c" 1>&6 ac_lib_var=`echo nsl'_'t_accept | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" else echo "$ac_t""no" 1>&6 fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT 2.0. # But -lsocket is broken on IRIX, according to simon@lia.di.epfl.ch. if test "`(uname) 2>/dev/null`" != IRIX; then echo $ac_n "checking for -lsocket""... $ac_c" 1>&6 ac_lib_var=`echo socket'_'socket | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lsocket" else echo "$ac_t""no" 1>&6 fi fi fi fi echo $ac_n "checking for -lm""... $ac_c" 1>&6 ac_lib_var=`echo m'_'atan | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo m | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi echo $ac_n "checking for -lBSD""... $ac_c" 1>&6 ac_lib_var=`echo BSD'_'signal | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lBSD $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo BSD | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi echo $ac_n "checking for -lbsd""... $ac_c" 1>&6 ac_lib_var=`echo bsd'_'signal | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo bsd | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi tcap=no echo $ac_n "checking for -ltermcap""... $ac_c" 1>&6 ac_lib_var=`echo termcap'_'tgetstr | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_LIBTERMCAP 1 EOF LIBS="$LIBS -ltermcap" tcap=yes else echo "$ac_t""no" 1>&6 fi if test $tcap = no; then echo $ac_n "checking for -ltermlib""... $ac_c" 1>&6 ac_lib_var=`echo termlib'_'tgetstr | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltermlib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_LIBTERMLIB 1 EOF LIBS="$LIBS -ltermlib" tcap=yes else echo "$ac_t""no" 1>&6 fi fi if test $tcap = no; then echo $ac_n "checking for -lcurses""... $ac_c" 1>&6 ac_lib_var=`echo curses'_'tgetstr | tr './+\055' '__p_'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_LIBCURSES 1 EOF LIBS="$LIBS -lcurses" tcap=yes else echo "$ac_t""no" 1>&6 fi fi # If we cannot run a trivial program, we must be cross compiling. echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_cross=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_cross=no else ac_cv_c_cross=yes fi fi rm -fr conftest* fi echo "$ac_t""$ac_cv_c_cross" 1>&6 cross_compiling=$ac_cv_c_cross echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1496: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF { (eval echo configure:1561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then : else ac_cv_header_stdc=no fi fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_hdr in sgtty.h termio.h unistd.h string.h do ac_safe=`echo "$ac_hdr" | tr './\055' '___'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1593: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for size_t""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "size_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 # if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then # echo $ac_n "(cached) $ac_c" 1>&6 # else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { return 0; } int t() { int i; ; return 0; } EOF if { (eval echo configure:1672: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void cat >> confdefs.h <> confdefs.h <&6 cat >> confdefs.h <&6 cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif /* void (*signal (int, RETSIGTYPE (*)(int))); */ int main() { return 0; } RETSIGTYPE t(int foo) { int i; signal(SIGINT,t); return 0; } EOF if { (eval echo configure:1672: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <&6 else rm -rf conftest* cat >> confdefs.h <&6 fi for ac_func in usleep srandom sigvec sigsetmask matherr drem irint bcopy memcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { return 0; } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "$ac_pattern" >/dev/null 2>&1; then rm -rf conftest* ac_cv_prog_gcc_traditional=yes else rm -rf conftest* ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "$ac_pattern" >/dev/null 2>&1; then rm -rf conftest* ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi if test "$no_x" != yes; then LIBS="$LIBS -lX11" fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.10" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@X_CFLAGS@%$X_CFLAGS%g s%@X_PRE_LIBS@%$X_PRE_LIBS%g s%@X_LIBS@%$X_LIBS%g s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g s%@MAKE@%$themake%g CEOF EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust relative srcdir, etc. for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file fi; done rm -f conftest.subs # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"} for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out cp $ac_given_srcdir/$ac_file_in conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. # Maximum number of lines to put in a single here document. ac_max_here_lines=12 rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1