|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T v
Length: 9419 (0x24cb) Types: TextFile Names: »vars.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Life/vars.c«
#ifdef SCCS static char *sccsid = "@(#)vars.c 1.11 2/2/85"; static char *cpyrid = "@(#)Copyright (C) 1985 by D Bell"; #endif #include "life.h" enum vars { /* ordering of variables */ v_minx, v_miny, v_maxx, v_maxy, v_cells, v_cx, v_cy, v_px, v_py, v_vminx, v_vmaxx, v_vminy, v_vmaxy, v_vcells, v_vx, v_vy, v_sminx, v_smaxx, v_sminy, v_smaxy, v_scells, v_gen, v_scale, v_freq, v_born, v_died, v_endlist }; /* * Table of multi-character variables. These are arranged in this table * in rows of 3 so that you can see what the display will look like for * the listvariables routine. */ struct vartab { char *v_name; /* name of variable */ enum vars v_type; /* variable id */ } vartab[] = { "cx", v_cx, "vx", v_vx, "px", v_px, "cy", v_cy, "vy", v_vy, "py", v_py, "minx", v_minx, "vminx", v_vminx, "sminx", v_sminx, "maxx", v_maxx, "vmaxx", v_vmaxx, "smaxx", v_smaxx, "maxy", v_maxy, "vmaxy", v_vmaxy, "smaxy", v_smaxy, "miny", v_miny, "vminy", v_vminy, "sminy", v_sminy, "cells", v_cells, "vcells", v_vcells, "scells", v_scells, "gen", v_gen, "born", v_born, "died", v_died, "scale", v_scale, "freq", v_freq, NULL, v_endlist }; static char *curcp; /* current character to parse */ static long lowervars[26]; /* lower case single-char variable values */ static long uppervars[26]; /* upper case single-char variable values */ /* * Return the value of a multiple character variable name. This can be * either a single character name, or else one of a fixed set of multi- * character names. All variable names must start with either a letter * or a dollar sign followed by a letter. */ getvariable(cp) register char *cp; /* name of variable */ { register struct vartab *vp; /* variable pointer */ if (*cp == '$') cp++; /* skip any dollar sign */ if (cp[1] == '\0') { /* single character name */ return(getvariable1(*cp)); } if (((*cp < 'a') || (*cp > 'z')) && ((*cp < 'A') || (*cp > 'Z'))) { error("Bad variable name"); } for (vp = vartab; ; vp++) { /* find name in table */ if (vp->v_name == NULL) error("Unknown variable"); if (strcmp(vp->v_name, cp) == 0) break; } return(getvariablebytype(vp->v_type)); /* get value */ } /* * Return the value of a variable given its enum value. */ getvariablebytype(type) enum vars type; /* variable type to get */ { register struct object *obj; /* current object */ register long value; /* value to return */ register long *ptr; /* pointer to minmax value */ register long *sptr; /* another one */ long sign; /* sign for result */ long minrow, maxrow, mincol, maxcol; /* results of minmax */ obj = curobj; value = 0; sign = 1; ptr = NULL; sptr = NULL; switch (type) { /* collect value */ case v_cx: value = obj->o_curcol; break; case v_cy: value = -obj->o_currow; break; case v_px: value = obj->o_pcol; break; case v_py: value = -obj->o_prow; break; case v_vx: value = (obj->o_mincol + obj->o_maxcol) / 2; break; case v_vy: value = -(obj->o_minrow + obj->o_maxrow) / 2; break; case v_vminx: value = obj->o_mincol; break; case v_vmaxx: value = obj->o_maxcol; break; case v_vminy: value = -obj->o_maxrow; break; case v_vmaxy: value = -obj->o_minrow; break; case v_vcells: value = markregion(obj, MARK_ANY, obj->o_minrow, obj->o_maxrow, obj->o_mincol, obj->o_maxcol); break; case v_cells: value = obj->o_count; break; case v_gen: value = obj->o_gen; break; case v_born: value = obj->o_born; break; case v_died: value = obj->o_died; break; case v_freq: value = frequency; break; case v_scale: value = obj->o_scale; break; case v_minx: ptr = &mincol; break; case v_maxx: ptr = &maxcol; break; case v_miny: ptr = &maxrow; sign = -1; break; case v_maxy: ptr = &minrow; sign = -1; break; case v_scells: value = countmarks(obj, MARK_SEE); break; case v_sminx: sptr = &mincol; break; case v_smaxx: sptr = &maxcol; break; case v_sminy: sptr = &maxrow; sign = -1; break; case v_smaxy: sptr = &minrow; sign = -1; break; } /* * Call proper minmax routines if we need to */ if (ptr && (minmax(obj, &minrow, &maxrow, &mincol, &maxcol) == 0)) value = *ptr; if (sptr&&(markminmax(obj,MARK_SEE,&minrow,&maxrow,&mincol,&maxcol)==0)) value = *sptr; return(sign * value); } /* * Return the value of a single character variable name (a-z or A-Z). */ getvariable1(ch) register int ch; /* variable character */ { if ((ch >= 'a') && (ch <= 'z')) return(lowervars[ch - 'a']); if ((ch >= 'A') && (ch <= 'Z')) return(lowervars[ch - 'A']); error("Bad variable name"); } /* * Set the value of a variable name. Multi-character names cannot be set. */ setvariable(cp, value) register char *cp; /* name of variable to set */ { if (*cp == '$') cp++; /* skip any dollar sign */ if (cp[1] != '\0') { error("Cannot set multi-character variables"); } setvariable1(*cp, value); /* do it */ } /* * Set the value of a single-character variable (a-z or A-Z). */ setvariable1(ch, value) register int ch; /* variable character */ { if ((ch >= 'a') && (ch <= 'z')) { lowervars[ch - 'a'] = value; return; } if ((ch >= 'A') && (ch <= 'Z')) { lowervars[ch - 'A'] = value; return; } error("Bad variable name"); } /* * Display the current values of the variables. Show all multi-character * variable values, and those single character variables which have a * nonzero value. The output is given three variables per line. */ listvariables() { register struct vartab *vp; /* variable table pointer */ register long *var; /* simple variable pointer */ register int count; /* counter for formatting */ dpywindow(0, -1, 0, -1); dpyprintf("Variable names and values:"); count = 0; for (vp = vartab; vp->v_name; vp++) { dpyprintf("%s%s\t%d", (count++ % 3) ? "\t\t" : "\n", vp->v_name, getvariablebytype(vp->v_type)); } count = 0; /* create blank line */ for (var = uppervars; var < &uppervars[26]; var++) { if (*var == 0) continue; if (count == 0) dpychar('\n'); dpyprintf("%s%c\t%d", (count++ % 3) ? "\t\t" : "\n", 'A' + (var - uppervars), *var); } for (var = lowervars; var < &lowervars[26]; var++) { if (*var == 0) continue; if (count == 0) dpychar('\n'); dpyprintf("%s%c\t%d", (count++ % 3) ? "\t\t" : "\n", 'a' + (var - lowervars), *var); } dpyprintf("\n\nMany names starting with 'v' refer to visible cells\n"); dpyprintf("Many names starting with 's' refer to selected cells\n"); spacewait(); /* wait for space before clearing */ } /* * Evaluate an expression and return its value. The expression can * contain numbers, variables, the normal arithmetic operators, and * parenthesized expressions. The usual precedence rules are used. */ getexpression(str) register char *str; /* string to parse */ { long value; /* resulting value */ while (*str == ' ') str++; if (*str == '\0') error("Null expression"); curcp = str; value = parsesum(); if (*curcp != '\0') error("Bad expression"); return(value); } /* Parse the sum of products */ parsesum() { register long value; /* value to return */ while (*curcp == ' ') curcp++; switch (*curcp) { /* check for uninary operators */ case '-': curcp++; value = -parseproduct(); break; case '+': curcp++; /* proceed into default case */ default: value = parseproduct(); } while (1) switch (*curcp++) { case '+': /* sum of products */ value += parseproduct(); continue; case '-': /* difference of products */ value -= parseproduct(); continue; case ' ': /* space */ continue; default: /* end of sum */ curcp--; return(value); } } /* Parse the product of terms */ parseproduct() { register long value; /* value to return */ register long value2; /* temporary value */ value = parseterm(); while (1) switch (*curcp++) { case '*': /* product of terms */ value *= parseterm(); continue; case '/': /* division of terms */ value2 = parseterm(); if (value2 == 0) error("division by zero"); value /= value2; continue; case '%': /* modulo of terms */ value2 = parseterm(); if (value2 == 0) error("division by zero"); value %= value2; continue; case ' ': /* space */ continue; default: /* end of product */ curcp--; return(value); } } /* Parse a single term */ parseterm() { register long value; /* value to return */ register int ch; /* current character */ while (*curcp == ' ') curcp++; ch = *curcp; if ((ch >= '0') && (ch <= '9')) { /* number */ value = 0; do value = (value * 10) + *curcp++ - '0'; while ((*curcp >= '0') && (*curcp <= '9')); return(value); } if (ch == '(') { /* parenthesized expression */ curcp++; while (*curcp == ' ') curcp++; if (*curcp == ')') error("Null expression"); value = parsesum(); while (*curcp == ' ') curcp++; if (*curcp != ')') error("Unmatched parenthesis"); *curcp++; return(value); } if (ch == ')') error("Unmatched parenthesis"); return(parsename()); } /* * Parse a variable name and return its value. */ parsename() { register char *cp; /* current character */ register long value; /* value of variable */ char oldch; /* old character after name */ cp = curcp; if (*cp == '$') cp++; while (((*cp >= 'a') && (*cp <= 'z')) || ((*cp >= 'A') && (*cp <= 'Z')) || ((*cp >= '0') && (*cp <= '9'))) cp++; oldch = *cp; *cp = '\0'; value = getvariable(curcp); *cp = oldch; curcp = cp; return(value); }