To run a NeuronC program simply type:
neurc file.n or ncv file.n (equiv to "nc -v file.n | vid") or ndv file.n (equiv to "nc -d 1 -v file.n | vid")This prints the time and voltage/current records as a plot on the console screen. The "neurc" program is actually a command (C-shell) file which consists of:
nc -v $argv | vid (for default display) or nc -v $argv | vid -X -w 1.8 (for X11 displays)That is, neurc runs the command "nc" followed by any file names you may have place after "neurc", and pipes the plot output to the "vid" program which displays it.
The "ncv" and "ndv" commands are similar to the "neurc" command except that they are not scripts, but a links (second names for) to "nc". Whenever "nc" finds itself called "ncv", it will attempt to generate an X window and display the output from nc.
The "nc" command has several command line switches:
-d n set display mode (equivalent to setting "disp = n"). 1 = allow display of neural circuit with "display" statement. 2 = allow display of compartments with "display comps" statement. 4 = allow display of connections with "display comps". 8 = allow display of nodes with "display nodes". 16 = allow display of stimulus with "display stim". -p n set print mode (equivalent to setting "prmap=1". 1 = display compartments and their connections as conductances and capacitances. 2 = display compartments as spheres with their Rm's, and channel conductances as densities. -l n set "lamcrit" variable. Allows you to run a circuit model with different compartment "condensation" without the need for editing. -f no file name on graph -n no node numbers on graph -F no labels on graph (i.e. no file name, node nums, calib), however tic numbers are displayed. -W n tic label char width in terms of screen size (screen is 1.0 x 1.0). -r n random number seed. Allows you to set the seed to a certain value. Random sequence will always be the same for a particular seed value. If "n" is negative, then the seed is randomized (derived from the process number) so that a different sequence is used every time. The seed value actually used in this case is printed (in text mode) in the output file so that it may be specified at a later time if necessary to produce the same sequence. --<var> n set variable from command line. <var> is name of variable that is used in program, "n" is value to set. Value can be numeric or string. -s <var> n Set variable from command line. Same as "--<var>" above. -t text mode (outputs numbers). This is the same as setting "vidmode=0" in a program, but the -t switch overrides the "vidmode" value of 1 (default mode). -v video mode (outputs plots on screen). Overrides the "vidmode" value of 0. This switch must be used with a graphics driver (either vid or drawpic) because it causes nc to output graphics characters which aren't properly printed on the text screen. -w n set line width for "display" statement to n. -y n debug with value "n". 1 = printouts of subroutine calls. 2,4 = gives information about the numerical integration. Combinations are possible: a debug value of 7 means include the information from debug 1,2 and 4 values. -R Output symbolic scene for input to "povray" ray-tracer. Use in conjunction with "-d 1" switch.You can run the "nc" command in several ways:
1) neurc file.n (run model, same as "nc -v file.n | vid") 2) nc -t file.n (run model, prints text on screen ) ( Used for "debugging" a model.) 3) nc -t file.n > file.r (saves a run file for later) ( Used for running long simulations. ) 4) nc -v file.n | vid (run model and display graphics on vid screen) 5) nd file.n | vid (display neural circuit anatomy on vid screen) 6) nc -d 1 file.n | vid (same as "nd file.n | vid") 7) plotmod file.n | vid (Displays graph or picture from file. ) 8) plotmod file.n | 8by11 (Draws graph or picture on color plotter. ) 9) nc -d 1 -R file.n > file.pov (Draws scene for "povray" ray-tracer. ) 10) file.n ¦ vid (run file.n as shell script file: see below ) 11) nc -I file.n (Runs nc as interpreter without simulator } 12) ncv file.n ( same as "nc -I": no simulator }You can 1) run "nc" from a command file "neurc" to plot graphs on the screen; 2) run "nc" without graphics output so that the recording data is printed as a list of numbers on the screen; 3) create a file out of these numbers; 4) send the graphics output to the video screen manually (use the -v switch); or 5) send the graphics output to a pen plotter ("drawpic" draws pictures on the plotter).
Since nc is an interpreter, you can use nc as a calculator to make quick calculations. An expression typed on the keyboard gets evaluated and printed immediately. You can run nc this way simply by typing:
ncfollowed by the "enter" key.
You can "include" files with predefined functions and use the functions as you would a calculator key. For instance the function "lambda" returns the space constant of a cable with a defined diameter and specific membrane resistance (Rm):
proc lambda (Rm,dia) { Ri = 100; return (sqrt ((Rm/Ri) * (dia/4))); };You could write this function in a file called "lambda.m", and then "include" this file whenever you wanted to make use of the function:
nc include "lambda.m" lambda (5000,2);Nc prints out the answer immediately.
nc file1.n > file1.r nc file2.n > file2.r or file1 > file1.r (If you make file1 a "nc shell" script,) file2 > file2.r ( see "Automatic Execution". )This has the advantage that the ".r" files (run files) are always the same name as the simulation scripts. However, this way you will end up with a lot of simulation scripts, and really the file names don't give you any way no idea of what parameters were changed. You can always run "diff" to find the differences, but that gets frustrating when you just want to find one run where you changed a particular parameter.
A better way to run simulations with different parameters is to maintain only one simulation script file. Then run "nc" from a script file, setting parameters on the command line:
#! /bin/tcsh -f # # Batch file "runsim-1" # nc -s ssize 5 file.n >& file1.r nc -s ssize 10 file.n >& file2.r nc -s ssize 50 file.n >& file3.r nc -s nostim 1 file.n >& file4.r nc -s nostim 1 -s ssize 5 file.n >& file5.r nc -s nostim 1 -s ssize 10 file.n >& file6.rThis batch file has the advantage that you can see exactly how you made all the ".r" files, and you can run it over again if necessary if you need to make a basic change in the "file.n" script. The ">&" in each line tells the shell to place both the standard output and the standard error in the output file.
The ".r" files produced by such a batch file will contain numbers that you can plot with the "plotmod" program:
plotmod -p 2-5 file4.r | vid (to see on the X screen) plotmod -p 2-5 file4.r | vid -c (to make into a .ps file)Or you can analyze the ".r" files with another script, like this:
------------------------------------------------------- #! /bin/csh -f # # conversion from temporal to spatial plots # # parameters: # # hzpn start stop center scale offset file # # # hz284: 60 x 60 array of cones # # hzpn 1 16 820 1 0 hz284s.r > hz284s.pn hzp 1 16 820 1 0 hz284s.r > hz284s.p hzpn 1 16 820 1 0 hz284sx.r > hz284sx.pn hzp 1 16 820 1 0 hz284sx.r > hz283sx.p -------------------------------------------------------In the above script, "hzpn" and "hzp" are commands that take the parameters listed and produce an analysis file on their standard output. It's easy to write such commands in "nc" script format, or with "awk" or "perl". "nc" can read in a numerical file into an array, and "awk" can process lines and do arithmetic on columns, much like a spreadsheet (see "man awk"). A typical analysis command:
------------------------------------------------------- # hzpn # # awk 'NR==1 { k=1; scal = 6*scale; drift = 0; limit=220} $1 == "#x" { x[k]= (center-$3-xoffset)*scal; k++;} $1 == 0.04 { for (i=start; i<=stop; i++) d[i] = $(i+1) - drift;} $1 == 0.10 { for (i=start; i<=stop; i++) avg[i] = $(i+1);} $1 == 0.105 { for (i=start; i<=stop; i++) avg[i] += $(i+1); $1 == 0.105 { for (i=start; i<=stop; i++) avg[i] += $(i+1); END { max = -1000; for (i=start; i<=stop; i++) { d[i] -= avg[i]/2; if (max < d[i]) max = d[i]; } for (i=start; i<=stop; i++) { if (x[i]<=limit) printf "%3g %-8.4g\n", x[i], d[i]/max; else printf "%3g %-8.4g\n", limit, d[i]/max; } } ' start=$1 stop=$2 center=$3 scale=$4 xoffset=$5 $6 -------------------------------------------------------Note the single quotes just after "awk" and after the awk script before the command line arguments.
The "povray" (Persistence of Vision) ray-tracer interprets a symbolic description of a 3D scene to produce a realistic surface-rendering of it that includes accurate 3D shapes, surface textures, light sources, shadows, and reflections. The "povray" distribution is available in the same location as the "nc" distribution. A binary distribution is available for Linux but the source code compiles on most Unix systems. You can run povray with command-line switches to generate pictures of any (x,y) dimension, for any output file name, or for display on the X11 screen. Its files are in ".tga" (targa) format by default. You can view these files with "xli" and you can view, convert, and print them with Adobe Photoshop.
"nc -d 1 -R" produces a file that contains a "camera" statement and a list of objects like "spheres", "cylinders", and other shapes. Since spheres and cylinders are similar to the "nc element" definitions of "sphere" and "cable", these symbolic objects are declared directly in the povray format. Other "nc" elements, such as photoreceptors, are a little more complex so they are predefined in the "nc.doc" standard include file (included in the ".pov" file produced by "nc"). You can redefine the shapes of such predefined elements by commenting out the existing definition and writing your own. The "nc" output file will use your definition instead, possibly modifying color and size, and positioning your objects correctly. The "nc.doc" file also contains default definitions of the light sources, surface texture, and background. You can readily modify these to your taste. For more information about "povray", read the "pov/doc/povray.doc" file in the "povray" distribution.
The ".pov" file produced by "nc" describes a standard camera location and rotates all the objects with respect to the standard reference frame. Each object is sized, translated and rotated (in that order), so the scene looks as if the camera rotated instead. Although it is possible to move the camera location (and this is the best way to look closely at details of the neural circuit), the objects in the ".pov" file are pre-rotated according to the rotation commands given "nc" in its input file. The reason for this scheme is to allow several display statements in the "nc" input file to produce different rotations and translations for different neural elements, which is sometimes useful for displaying a neural circuit (e.g. "pulling-apart" a circuit to show the separate neurons).
setenv POVRAYOPT -l/usr/src/ray/pov/includeYou can put this line in your .cshrc Cshell startup file, or a similar file can be placed in you ksh or sh .profile startup file.
Set up the a test scene from your neural circuit, and establish the general outline and the desired rotation by viewing the scene with:
nc -d 1 -v file.n | vidThen generate the ".pov" file with:
nc -d 1 -R file.n > file.povLook at this test scene by rendering it small so it displays fairly fast:
povray -h100 -w100 -ifile.pov -ofile.tga +dxThe "+dx" tells povray to display the scene on the X11 display. You can also view the ".tga" file afterwards. When you have the correct scene and viewing position, render the scene with:
povray -h800 -w800 -ifile.pov -ofile.tga +dx
If your scene has a non-square aspect ratio, you can save rendering time by modifying the
up <0, 1, 0> right <1, 0, 0>statement in the camera definition in the ".pov" file created by "nc -R", and then creating an output file with a corresponding rectangular shape. For example, if your neural circuit scene is wide and not very tall, you might make a 2:1 aspect ratio by defining:
up <0, .5, 0> right <1, 0, 0>and then creating the corresponding picture with:
povray -h400 -w800 -ifile.pov -ofile.tga +dxIf you forget and don't change both of these aspect ratio declarations your picture will be distorted so spheres look squashed flat.
See the "povray.doc" file for more information about the aspect ratio. It is fruitful and lots of fun to experiment with the light source, texture, and background features.
stim file filename;This is a statement in the NeuronC file which names a text file "filename" to contain a list of stimulus events. Stim calculates all the stimuli, blurs them, finds what intensity and wavelength exists at each rod or cone at each stimulus time, and writes the list into the stimulus event file. Stim and NeuronC both use the same NeuronC program to define the neural circuit and stimuli, but Stim creates the file and NeuronC reads from the file. Once a stimulus file is generated, it need not be remade each time a new NeuronC model is run; if a new NeuronC program defines the same pattern of photoreceptors, it may refer to the same stimulus file.
The "stim file" statement tells NeuronC to ignore any other light stimulus statements and get its stimuli instead from the file. NeuronC cannot blur stimuli and ignores "blur" in a "stim" statement. If the "stim file" statement is omitted, NeuronC will understand stimulus statements but will ignore the "blur" parameter in them.
Example of how to use "stim":
File that generates model (call it "file1"): . . statements that make rods or cones . . . stim file file1.t; stimulus generation statements (i.e. "stim spot ...") run; To make stimulus, first run "stim" and then run "nc": stim file1 (this creates "file1.t") nc -t file1 >file1.r (uses "file.t" as stim file,) (creates "file1.r")
nc -t file.n >file.r plotmod file.r | vidThe ".r" file contains the numerical plot records. These may be plotted on the screen exactly as NeuronC would have if the "vidmode" variable was set (=1). Plotmod has several command line switches:
-a draws graphs with automatic scaling from simple ascii text files. -c x use char "x" to plot points on line. -C x use char "x" to plot points, no lines. -e n set xmin to "n" -E n set xmax to "n" -m n set ymin to "n" -M n set ymax to "n" -w n set char size for data points on line to "n", in terms of screen size. Must set size before "-c" switch. -W n tic label char width in terms of screen size (screen is 1.0 x 1.0). -f no file name on graph -n no node numbers on graph -F no labels on graph (i.e. no file name, node nums, calib), however tic numbers are displayed. -d draws plots with dashes (use for monochrome or xerox) -t text mode (outputs numbers, not graphics) -r "row" mode. Numbers for a variable are on one line. -p n display plot "n" (n= 1 to 32) selectively (multiple -p n switches for several plots) -p a-b (n can also be a range in the format "a-b") -y input data has only "y" values, no "x" value. -Y draw multiple Y axes in graph, on left. -R draw multiple Y axes on right.Example:
plotmod -p 2 -p 3 -p 4 file.r | vid plotmod -p 2-4 file.r | viddraws 3 plots from the "file.r" recording data file generated by a previous nc simulation run.
x y1 y2 y3 . . . x y1 y2 y3 . . . x y1 y2 y3 . . .That is, each line in the file normally contains an x value and one or more y values. Plotmod will also graph single y values without an x value on the line. In this case, the x value used to plot the y value is the line number. The values are all read into "plotmod", the minimum and maximum values are calculated, and the graph is scaled appropriately. Labels may be added using the "labels" command, or with the graphics primitives available in "nc".
x x x x x . . . y1 y1 y1 y1 y1 . . . y2 y2 y2 y2 y2 . . . y3 y3 y3 y3 y3 . . .
plotmod -a -c ' ' -c o -C x datafile | vidThis would label the second 2 plots from "datafile". The first plot would have no character labels, the second would have "o"'s on top of the plot line, and the third would have "x"'s with no lines.
Vid command line switches are:
-a make "PostScript" file on stdout: "vid -a > file" -c make color "PostScript" file on stdout: "vid -c > file" -l make "postscript" raster file on stdout. -e use Enhanced Graphics Adapter -h use monochrome Hercules board -t use Tektronix 4014 type display terminal -X use X-windows for graphics display -d name define name of X-windows screen to display on -k invert screen (upside down). -m n use "n" as mag, default 1.0. -p n use "n" as color (16 colors). -B n use "n" as background color. -r rotate picture sideways 90 deg. -w n use "n" as size of X-window. -x n use "n" as x offset (default 8192) This defines center of picture. -y n use "n" as y offset (default 8192) This defines center of picture. -v don't erase screen when first starting video graphics mode.Example:
nc -t file1 | vid (="neurc file1") nc -t file2 | vid -v (don't erase screen)Vid normally erases the screen when you first run it, but you can tell it not to with the "-v" switch listed above. Vid normally doesn't erase its picture when it is finished displaying. To get back to text mode you use the "t" (or "textmod") command. This doesn't erase the graphics screen, so you can run vid several times with as many text commands in between as you want. For instance:
vid file1 (make first picture on screen) t ls -l cd otherdir vid -v file2 (superimpose 2nd picture on first)
-e EGA driver. -h Hercules driver. -v Change from text mode back to video (restore a previous picture)"textmod" is normally run (aliased) to run as the command "t".
-c sort output by pen color (waits until the end to draw) -m n use "n" as mag, default 1.0 -p n use following number as plotter pen number. This overrides any pens defined in the picture file -r rotate picture sideways 90 deg -s n use "n" as speed for plotter (cm/sec). 4 cm/sec default. -x n use "n" as x offset (default 7500). This is the center of the picture, calibrated in thousandths of an inch. One cm = 400 units. -y n use "n" as y offset (default 5000). Calibrated as "x" above. -w wait after using each pen, to allow paper to be changed. -z save individual pen files after exit; use with "-c" above.Ibmflt is normally used from a command file, which is set up to draw pictures of the correct size and centering for the paper used. The command "8by11" runs the plotter for the widely used 8" x 11" paper. For the HP 7221 plotter, the "8by11" command looks like:
hpflt -x 4700 -y 4000 -m .8 $argv | hplot ( = 8by11 )To get "hard-copy" output, you can run "nc" like this:
nc -v file1 | ibmflt | iplotOr you can make a data file which can then be displayed or printed afterwards:
nc -v file1 > file1.r (create graphics file) vid fil1.r (graphics display on screen) 8by11 file1.r (hard copy on plotter)
Posit command line switches:
-i non-interrupt mode -f make ".p" output files from input -m Use following number as mag, default 1.0 -p Use following number as plotter pen number. This overrides any pens defined in the picture file. -x Use following number as x offset (default 5000) This is the center of the picture, calibrated in thousandths of an inch. One cm = 400 units -y Use following number as y offset (default 5000) Calibrated as "-x" above.Example 1:
posit -f -x 1000 -y 7000 file1.h -x 4000 y -6000 file2This creates file1.p and file2.p with (x,y) offsets from existing ".h" files which had already been hidden.
-c char char is point label -C char char is point label; no connecting lines -f filename "filename" is a file containing a list of points; filename "-" means standard input; maximum of 8 filenames allowed. -g num num is grid style; 0-> solid grid; 1-> dotted grid; 2-> no grid but solid maxima; 3-> no grid(default) -l "label" label for x axis -L "label" label for y axis -m val min for y axis -M val max for y axis -p num num is pen/dash style when doing multiple graphs with the -f switch: 0-> dashes only (default); 1-> pen changes and dashes; 2-> pen changes only -t num num is the tic style of x-axis: 0 -> many tics, few numbers (default); 1 -> few tics, few numbers; 2 -> many tics, many numbers; 3 -> few tics, many numbers -T num num is the tic style of y-axis: 0 -> many tics, few numbers (default); 1 -> few tics, few numbers; 2 -> many tics, many numbers; 3 -> few tics, many numbers; -o make x axis logarighmic (bug in axis labeling) -O make y axis logarighmic (bug in axis labeling) -v num point label char size, 1=small, 7=large; -w num x axis char size for label, 1=small, 7=large; -W num y axis char size for label, 1=small, 7=large;You can run graph interactively by typing "graph | vid" and then entering a set of points, one x,y point pair per line (x and y separated by spaces not commas), and a CTRL-D to stop entering data and display the graph. You can also make a text file with an editor and run "graph < file | vid" which causes graph to get its input from the file instead of the keyboard.
graph -f file1 -f file2 -f file3and the first one will be a solid line, the second will be a dotted line, and the third will be a dashed line. If you want colors, use the "-p" switch.
If you want to have control over the scale of the plot (so that it isn't always drawn as a square which fills the page) you can use the "-m" and "-M" switches for the y-axis, and you can include some dummy extra points to extend the x-axis, one for each end.
For instance:
0 0 extends left side to 0 data points 10 0 extends right side to 10You can use the "grp" comand to run graph automatically on several file names:
grp file1 file2 file3 | vid"grp" is a C-shell command file which contains something like:
# set pen = 1 #set axis = set axis = "-T 3 -t 0" set min = #set min = "-m -.1" set max = #set max = "-M 1.2" if ($#argv == 1) then graph -p $pen $axis $min $max -f $1 else if ($#argv == 2) then graph -p $pen $axis $min $max -f $1 -f $2 ( and so on up to 8: "-f 1 ... -f $8" ) endif
ch x change char size to x. ci x make circle with radius x. erase erase screen. flag shape size draw flag as in "filter" in mpict(5). fo x change text font to x. fr name move to frame "name". include name include file "name". move x [,] y move pen to (x,y). draw x [,] y draw to (x,y). line x1[,]y1[,]x2[,]y2 draw line segment from (x1,y1) to (x2,y2). o x make dashed line of type x. or x set origin of frame to (x,y). pen num change pen to "num". rd x [,] y relative draw to (x,y). rm x [,] y relative move to (x,y). rl x [,] y relative line. ro x rotate x degrees. rt x rotate text x degrees. size x set size of picture to "x". text x [,] y "text" write "text" starting at (x,y). u "text" write "text" at current position. q,x quit to shellAll "labels" commands can be abbreviated to their first letter; for example, "m x y" means "move x,y". Commands having the same first letter need two letters.
Example:
c .05 p 3 t .7 .9 /Right Side/ move .7 .8 flag char E 12 move .4 .7 flag tri 4 i elephantThis command sequence writes "Right Side" starting at location (0.7,0.9) with a character size of .05 using pen 3, then writes two flags, and then runs the file "elephant" which could have other label commands in it (e.g. it could draw an elephant).
The labels program normally draws lines inside the standard video screen, which is defined to have its lower left corner at the point (0,0) and its upper right corner at (1.0, 1.0). Anything outside this square viewing window is not displayed. You may redefine the size of the window using the "size" command by giving a factor with which to scale the standard screen. You may also create sub-pictures within the standard picture which can be rotated, translated and scaled with respect to the standard picture. Each sub-picture (frame) can have its own sub-pictures, much like the UNIX file system. You move from one frame to another by using the "frame" command (".." is parent frame, "/" is root).
name default unit meaning of variable ---------------------------------------------------------------- Simulation variables double complam 0.1 fraction of space constant per compartment double lamcrit 0.3 fraction of complam for minimum size compartment double timinc 1e-4 sec time step for numeric integration in comps(sec) double stiminc 1e-4 sec time step for synapses (sec) double endexp 50e-3 sec time for end of experiment double crit 1e-8 V criterion for convergence for time step double relax .15 over-relaxation constant (0 to 0.4) double relincr .002 relaxation increment double synaptau 1 synaptic time constant multiplier (0.1 => faster) int euler 0 use Euler integration (0=CN, 1=Euler) int implicit 0 use implicit integration (0=CN, 1=implicit) int scatter 0 use light scatter with light blur function int debug 0 turn on debugging features "-y" (0=none,7=many) int debugz 0 type of debugging features "-z" (0=none,7=many) long int rseed 123456 random number seed. double time 0 absolute time at start (may be negative) double version 5.0415 current (latest) version number double tempcel 6.3 deg C temperature for voltage-sensitive channels. double djnoise 0 Johnson noise for all Rm's (on if > 0) int ncomps 0 Number of compartments int time 0 absolute time in simulation Plot variables double plmax .04 V default maximum for plot on graph double plmin -.07 V default minimum for plot on graph double ploti .001 sec time step for plot increment (sec) int plsep 0 draw separate graphs (0=all in one, 1=sep) int dashfl 0 draw graph with dashes (0=solid, 1=dash) int vidmode 0 flag for numerical output (0=text, 1=graphics) int prmap 0 flag for print connection map (1 = display compartments and connections) (2 = display compartments as spheres with rm) int disp 0 flag for display circuit (0 = no display) (1 = display circuit with "display" statement) (2 = display compartments) (4 = display connections betw. compartments) (8 = display nodes) (16 = display stimulus) Ion concentrations and batteries External concentrations (from Ames Medium) double dnao 0.143 M External sodium concentration double dko 0.0036 M External potassium concentration double dclo 0.1254 M External chloride concentration double dcao 0.0023 M External calcium concentration Internal concentrations (calculated at 37 deg C) double dnai 0.0125 M Internal sodium concentration double dki 0.1408 M Internal potassium concentration double dcli 0.0091 M Internal chloride concentration double dcai 50e-9 M Internal calcium concentration Batteries (calculated at 37 deg C) double vk -.098 V potassium battery voltage double vna .065 V sodium battery voltage double vcl -.07 V chloride leakage battery voltage double calcnernst 0.6 =1 -> calculate vrevs from ion concentrations =0 -> calculate ion concs from Nernst potentials Relative permeabililties double dpkna 0.1 relative permeability of K in Na channels double dpcana 0.05 relative permeability of Ca in Na channels double dpnak 0.03 relative permeability of Na in K channels double dpcak 0.001 relative permeability of Ca in K channels double dpnaca 0.001 relative permeability of Na in Ca channels double dpkca 0.001 relative permeability of K in Ca channels Biophysical constants double dcap 1e-6 fd/cm2 default membrane capacitance double dri 200 ohm cm default axial resistance double drg 5e6 ohm um2 default gap junction resistance double drm 40000 ohm cm2 default membrane resistance ohm cm2 double dfta .2 msec default pre-synaptic time const. double dsfa 2 default pre-synaptic number of filters. double dftb .2 msec default post-rel time const. double dsfb 0 default post-rel number of filters. double dsvn 5 default synaptic vesicle rel site number double dvsz 100 default synaptic vesicle size double dst -.04 V default synaptic threshold double dsc "expon" default synaptic curve (expon=533) double dskd 1 default synaptic half-max saturation gain double dshd 1 default synaptic binding Hill coeff double dsvn 10 default synaptic vesicle number double dsvd .001 sec default synaptic vesicle duration double dscd .01 sec default synaptic channel duration double dmaxsyn 200e-12 S default maximum cond for synapse double dstr 100e-6 M default synaptic neurotrans conc double dgkd 0.1 default synaptic half-max cGMP saturation (kd) double dsn 2 default synaptic gain, linear or exponential double dsg 1 default synaptic cGMP gain double dmaxrod 35e-12 S default maximum dark conductance for rod double dmaxcon 1.4e-9 S default maximum dark conductance for cone double dnadens 0.25 S/cm2 default density for Na chans (S/cm2) double dkdens 0.0707 S/cm2 default density for K chans (S/cm2) double dcadens .005 S/cm2 default density of Ca V-gated channel double dcavoff 0.018 V Q10 for voffset due to cao (additive) double dcasurfp 0.18 V Ca surface potential (mult dcavoff) double ddca 2e-6 cm2/sec diffusion const for Ca in cytoplasm double dcabnd 10.0 default ratio of bound to free calcium double dcabti 30e-6 M default Ca buffer total in first shell double dcabt 3e-6 M default Ca buffer total in shells double dcabf 1e8 /M/sec default Ca buffer forw rate to Ca.B double dcabr 100 /sec default Ca buffer reverse rate to Ca.B double dcashell 10 default Number of Ca diffusion shells double dcapkm .2e-6 M default 1/2 sat conc. of Ca pump double dcavmax 5e-6 mA/cm2 default vmax for Ca pump double dcakex 5e-9 A/mM4/cm2 default rate for Na/Ca exchanger double dcaoffs 0 V default activation offset for Ca chans double dcataum 1 default activation tau mult for Ca chans double dcatauh 1 default inactivation tau mult for Ca chans double dkcataum 1 default activation tau mult for KCa channel double dkcatauh 1 default inactivation tau mult for KCa channel double dnataud 0.16 default tau mult for Na noise in 2-state model double dktaud 0.6 default tau mult for K noise in 2-state model double dqm 2 default Q10 for Na activation (am, bm) double dqh 3 default Q10 for Na inactivation (ah, bh) double dqn 3 default Q10 for K activation (an, bn) double dqca 3 default Q10 for Ca activation (ac, bc) double dqd 3 default Q10 for KA inactivation (ad, bd) double dqkca 3 default Q10 for Kca activation (a, b) double dqsyn 3 default Q10 for synaptic chans (ampa, etc) double dqcavmax 2 default Q10 for Ca pump double dqcab 2 default Q10 for Ca buffer double dqc 1.4 default Q10 for unitary channel conductances double dnmdamg 2e-3 M default external [Mg++] for NMDA chans double dmaxna 1e-9 S default cond of Na voltage-gated chans double dmaxk 2e-10 S default cond of K voltage-gated chans double dmaxca 100e-12 S default cond of Ca voltage gated chans double dnaoffsm 0 V default activation offset for Na chans double dnaoffsh 0 V default inactivation offset for Na chans double dnataum 1 default inactivation offset for Na chans double dnatauh 1 default inactivation offset for Na chans double dkoffs 0 V default activation offset for K chans double dktaum 1 default inactivation offset for K chans double dktauh 1 default inactivation offset for K chans double dgjoff 0.015 V default gap junction voltage offset double dgjtau 1 default activation tau for gap junctions double dgjnv 0.2 default non-voltage sensitive fract of gj cond double dbd1 1 default voltage multiplier for BK chan alpha double dbd2 1 default voltage multiplier for BK chan beta double dbk1 1e-6 default Ca multiplier for BK chan alpha double dbk3 1e-6 default Ca multiplier for BK chan beta double dsd1 0 default voltage multiplier for SK chan alpha double dsd2 0 default voltage multiplier for SK chan beta double dsk1 1e-7 default Ca multiplier for SK chan alpha double dsk3 1e-7 default Ca multiplier for SK chan beta double dscu 25e-12 S default unitary conductance of channels double dnau 12e-12 S default unitary cond of Na chans (= 22pS @ 22deg) double dku 12e-12 S default unitary cond of K chans double dkcabu 5.7e-12 S default unitary cond of BK chans double dkcasu 68e-12 S default unitary cond of SK chans double dcalu 7.6e-12 S default unitary cond of Ca L-type chan (= 20pS @35deg) double dcatu 3e-12 S default unitary cond of Ca T-type chan (= 8 pS @35deg) double dampau 25e-12 S default unitary cond of AMPA chans double dcgmpu 25e-12 S default unitary cond of cGMP chans double dsyntau 1 default time constant for synaptic chans
Armstrong, C.M., and Matteson, D.R. (1984) Sequential models of sodium channel gating. Current Topics in Membranes and Transport. 22: 331-352. Attwell, D., Werblin, F.S., and Wilson, M. (1982) The properties of single cones isolated from the tiger salamander retina. J. Physiol. 328: 259-283. Attwell, D., Mobbs, P., Tessier-Lavigne, M., and Wilson, M. (1987) Neurotransmitter-induced currents in retinal bipolar cells of the axolotl, Ambystoma Mexicanum. J. Physiol. 387: 125-161. Baylor, D., and Nunn, B.J. (1986) Electrical properties of the light-sensitive conductance of rods of the salamander Ambystoma tigrinum. J. Physiol. 371: 115-145. Belgum, J.H., and Copenhagen, D.R. (1988) Synaptic transfer of rod signals to horizontal and bipolar cells in the retina of the toad (Bufo Marinus). J. Physiol. 396: 225-245. Carnevale, N.T., and Lebeda, F.J. (1987) Numerical analysis of electrotonus in multicompartmental neuron models. J. Neurosci. Meth. 19: 69-87. Ellias, S.A., and Stevens, J.K., (1980) The dendritic varicosity: a mechanism for electrically isolating the dendrites of cat retinal amacrine cells? Brain Res. 196: 365-372. Falk, G., and Fatt, P. (1972) Physical changes induced by light in the rod outer segment of vertebrates. In Handbook of Sensory Physiology, vol VII/1. Photochemsitry of Vision, ed. Dartnall, H.J.A., p200-244. Berlin: Springer. Hines, M. (1989) A program for simulation of nerve equations with branching connections. Int. J. Bio- Med. Comput. 24: 55-68. Hodgkin, A.L., and Huxley, A.F. (1952) A quantitative description of membrane current and its application to conduction and excitation in nerve. J. Physiol. 117: 500-544. Jack, J.J.B., Noble, D., and Tsien, R.W. (1983) Electric Current Flow in Excitable Cells. Clarendon Press, Oxford, UK. Joyner, R.W., Westerfield, M., Moore, J.W., and Stockbridge, N. (1978) A numerical method to model excitable cells. Biophys. J. 22: 155-170. Kernighan, B.W., and Pike, R. (1984) The UNIX programming environment. Prentice-Hall, Englewood Cliffs, N.J. Koch, C., and Poggio, T. (1985) A simple algorithm for solving the cable equation in dendritic trees of arbitrary geometry. J. Neurosci. Meth. 12: 303-315. Koch, C., and Segev, I. (eds) (1989) Methods in Neuronal Modeling. MIT Press, Cambridge, MA. Korn, H., Mallet, A., Triller, A., and Faber, D.S. (1982) Transmission at a central synapse. II. Quantal description of release with a physical correlate for binomial n. J. Neurophys. 48: 679-707. Lamb, T.D., and Simon, E.J. (1976) The relation between intercellular coupling and electrical noise in turtle photoreceptors. J. Physiol. 263: 257-286. Moore, J.W., and Ramon, F., (1974) On numerical Integration of the Hodgkin and Huxley equations for a membrane action potential. J. Theor. Biol. 45: 249-273. Nawy, S., and Copenhagen, D.R. (1987) Multiple classes of glutamate receptor in depolarizing biploar cells in retina. Nature 325: 56-58. Perkel, D.H., and Mulloney, B. (1978) Electrotonic properties of neurons: steady-state compartmental model. J. Neurophysiol.41: 621-639. Perkel, D.H., Mulloney, B. and Budelli, R.W. (1981) Quantitative methods for predicting neuronal behavior. Neuroscience 6: 823-837. Pugh, E., and Altman, J., (1988) A role for calcium in adaptation. Nature 334: 16-17. Rall, W. (1959) Branching dendritic trees and motoneuron membrane resistivity. Exp. Neurol. 1: 491-527. Rall, W. (1967) Distinguishing theoretical synaptic potentials computed for different soma-dendritic distributions of synaptic input. J. Neurophysiol. 30: 1138-1168.
1) simulation of cable (tcomp2) /* variables with special meanings: */ vidmode=1; /* video mode turned on */ timinc = 1e-4; /* simulation time step 100 microsec */ endexp = .05; /* end of experiment */ complam=.1; /* fraction of lambda per compartment */ relax = .15; /* relaxation constant for matrix solve */ crit=1e-8; /* criterion for stopping time step */ ploti = .001; /* time increment for plotting during run */ drm = 5000; /* default Rm changed to new value */ seg = 353; /* new variable for cable segment length */ conn 1 to 2 cable length seg dia 1; /* cable segments */ conn 2 to 3 cable length seg dia 1; conn 3 to 4 cable length seg dia 1; conn 4 to 5 cable length seg dia 1; conn 5 to 6 cable length seg dia 1; conn 6 to 7 cable length seg dia 1; conn 7 to 8 cable length seg dia 1; conn 8 to 9 cable length seg dia 1; conn 9 to 10 cable length seg dia 1; stim node 1 vclamp -.01 start 0 dur 1; /* voltage clamp stimulus */ plot V[1] max 0 min -.07; /* plots during run */ plot V[2] max 0 min -.07; plot V[3] max 0 min -.07; plot V[4] max 0 min -.07; plot V[5] max 0 min -.07; plot V[6] max 0 min -.07; plot V[7] max 0 min -.07; run; 2) Cable with voltage clamp (tcomp3) vidmode=1; timinc = 1e-4; crit = 1e-8; complam=.1; endexp=.5; ploti = endexp/200; relax=0.57; conn 1 to 2 cable length 150 dia .2; conn 2 to 3 cable length 150 dia .4; stim node 1 vclamp -.02 start .002 dur .2; plot V[2],V[1]; run; 3) Test of cables connected to spheres. Transient stimulus at end of cable. (tcomp4) debug=0; vidmode=0; plmax 0 timinc = 4e-6; plsep = 0; euler = 1; at 1 sphere dia 10; conn 1 to 2 cable length 10 dia 1; at 2 sphere dia 10; conn 2 to 3 cable length 10 dia 1; at 3 sphere dia 10; stim node 1 vclamp -.01 start 0 dur .002; plot V[3],V[2],V[1]; run; 4) Same as 3) but longer cables vidmode=1; endexp = .02; at 1 sphere dia 10; conn 1 to 2 cable length 100 dia 1; at 2 sphere dia 10; conn 2 to 3 cable length 100 dia 1; at 3 sphere dia 10; stim node 1 vclamp .04 start 0 dur .001; stim node 3 vclamp -.07 start 0 dur .001; plot V[3],V[2],V[1]; run; 5) Test of linear synapse (tcomp7) vidmode=1; timinc = 5e-5; crit = 1e-5; endexp = .02; at 1 sphere dia 10; conn 1 to 2 synapse linear 2 maxcond 1e-9 thresh -.04; at 2 sphere dia 10; stim node 1 vclamp .04 start 0 dur .005; plot V[2],V[1]; run; 6) Test of expon synapse (tcomp7a) vidmode=1; timinc = 5e-5; crit = 1e-5; endexp = .02; at 1 sphere dia 10; conn 1 to 2 synapse open expon 10 maxcond 1e-9 thresh -.04; at 2 sphere dia 10; stim node 1 vclamp .04 start 0 dur .005; plot V[2],V[1]; run; 7) test of voltage clamp (tcomp8) vidmode=1; endexp = .02; at 1 sphere dia 10; conn 1 to 2 synapse linear .5 maxcond 4e-9 thresh -.07; at 2 sphere dia 10; stim node 1 vclamp -.02 start 0 dur .002; stim node 1 vclamp .01 start .002 dur .002; stim node 1 vclamp -.02 start .004 dur .008; plot V[2],V[1]; run; 8) Test of current clamp (tcomp9) vidmode=1; endexp = .05; at 1 sphere dia 10; conn 1 to 2 synapse expon 5 thresh -.08; at 2 sphere dia 10; conn 2 to 3 synapse expon 5 thresh -.08; at 3 sphere dia 10; stim node 1 cclamp 5e-11 start .004 dur .02; plot V[3],V[2],V[1]; run; 9) Test of reciprocal synapse (tcomp11) vidmode=1; endexp = .05; plmax = -.00; plmin = -.06; at 1 sphere dia 5; conn 1 to 2 cable length 50 dia 1.5 rm 5000; at 2 sphere dia 5; conn 2 to 3 synapse linear thresh -.06; conn 3 to 2 synapse linear thresh -.06; conn 3 to 5 cable length 10 dia .1; conn 5 to 6 cable length 10 dia .5; conn 6 to 7 cable length 10 dia 2; at 7 sphere dia 30; conn 7 to 8 cable length 50 dia 5; stim node 1 cclamp 5e-11 start .002 dur .02; plot V[6],V[5],V[3],V[2],V[1]; run; 10) Test of synapse onto horiz cell (tcomp12) vidmode=1; plmax = -.03; plmin = -.08; endexp = .05; at 1 sphere dia 5; conn 1 to 2 cable length 50 dia 1.5 rm 5000; at 2 sphere dia 5; conn 2 to 3 synapse linear 1 thresh -.06; /* conn 3 to 2 synapse linear 1 thresh -.06; */ conn 3 to 5 cable length 10 dia .1; conn 5 to 6 cable length 10 dia .5; conn 6 to 7 cable length 10 dia 2; at 7 sphere dia 30; conn 7 to 8 cable length 50 dia 5; stim node 1 cclamp 1e-11 start .002 dur .02; stim node 5 cclamp 1e-10 start 0 dur .03; plot V[6],V[5],V[3],V[2],V[1]; run; 11) Test of gap junction and instability (tcomp13) /* must make time constant longer than 5 x timinc */ vidmode=0; timinc = 2e-4; plmax = -.03; plmin = -.08; endexp = .05; dcap = 1e-6; drg=5e4; at 1 sphere dia 10; at 1 cap 2e-11; conn 1 to 2 gj 1; at 2 sphere dia 10; stim node 1 cclamp 1e-10 start .002 dur .02; plot V[1],V[2]; run; 12) /* test of rod */ (tcomp14) vidmode=1; timinc = 1e-4; plmax = -.01; plmin = -.06; endexp = .10; ploti = endexp / 200; rodrm = 5000; at 1 sphere dia 5 rm rodrm; /* rod anatomy */ at 1 rod (0,0); conn 1 to 2 cable length 50 dia 1.5 rm rodrm; at 2 sphere dia 5 rm rodrm; /* synapse from rod to horiz */ conn 2 to 3 synapse linear 1 thresh -.06; conn 3 to 5 cable length 10 dia .1; conn 5 to 6 cable length 10 dia .5; conn 6 to 7 cable length 10 dia 2; at 7 sphere dia 30; conn 7 to 8 cable length 50 dia 5; stim rod 1 inten 1e4 start .008 dur .002; plot V[6],V[5],V[3],V[2],V[1]; run; 13) Test of current recording from voltage clamp (tcomp16) vidmode=1; plmax = .02; plmin = -.02; endexp = .02; ploti = endexp / 200; vcl = 0; at 1 load 1e6; at 1 cap 1e-9; stim node 1 cclamp 1e-8 start .002 dur .002; stim node 1 cclamp 2e-8 start .004 dur .004; stim node 1 vclamp .01 start .001 dur .005; plot V[1]; plot I[1] max 1e-7 min -1e-7; run; 14) Test of voltage clamp current recording from a rod with simultaneous voltage recording (tcomp17) /* calibrate at flash intensity of 20e3 for 1e-3 sec, then at 500e3 for tail length */ vidmode=1; timinc = 1e-4; plsep = 1; plmax = -.01; plmin = -.06; endexp = 2.50; ploti = endexp / 200; rodrm=5000; at 1 sphere dia 1 rm rodrm; /* rod anatomy */ at 1 rod (0,0); at 2 sphere dia 10 rm rodrm; /* rod anatomy */ at 2 rod (0,0); flash=20e3; stim rod 1 inten flash start .009 dur .001; stim node 1 vclamp -.06 start .008 dur 1.5; stim rod 2 inten flash start .009 dur .001; plot I[1] max 0e-12 min -60e-12; plot V[2] max 0 min -.08; run; 15) Test of voltage clamp current recording from a rod with simultaneous voltage recording. (tcomp18) /* calibrate at 1 photon for 1 msec for 8e-12 A peak response */ vidmode=0; timinc = 1e-4; plmax = -.01; plmin = -.06; endexp = 1.5; ploti = endexp / 200; dmaxrod=35e-11; rodrm=5000; at 1 sphere dia 1 rm rodrm; /* rod anatomy */ at 1 rod (0,0); /*at 2 sphere dia 1 rm rodrm; /* rod anatomy */ /*at 2 rod (0,0); */ /* synapse from rod to horiz */ flash=100e3; stim rod 1 inten flash start .009 dur .001; stim node 1 vclamp -.06 start .008 dur 1.5; /* stim rod 2 inten flash start .009 dur .001; */ plot I[1] max 35e-12 min 0e-12; /*plot V[1] max .04 min -.06; */ run; 16) Test of voltage clamp current recording from a cone with simultaneous voltage recording. (tcomp20) /* calibrate at inten 100e3 for 1e-3 dur to give 8e-12 A peak response */ vidmode=1; plmax = -.01; plmin = -.06; endexp = 1.0; ploti = endexp / 200; dmaxcon = 35e-12; include cone.m; n=mcone (0,0,1); n=mcone (0,0,2); flash= 2000e3; stim cone 1 inten flash start .009 dur .001; stim node 1 vclamp -.06 start .008 dur 1.5; stim cone 2 inten flash start .009 dur .001; plot I[1] max 3.5e-10 min 0e-12; plot V[2] max -.020 min -.050; plot V[2] max .04 min -.06; run; 17) Test of rod; same as tcomp15 but uses "rod.m" (tcomp21) vidmode=0; plmax = .0; plmin = -.06; endexp = 1.0; ploti = endexp/200; drm = 10000; relax= 0.57; pois = 0; include "rod.m"; /* */ n = 100; n = mrod(0,0,n+1); conn n to 6 cable length 10 dia .1; conn 6 to 7 cable length 10 dia .5; conn 7 to 8 cable length 10 dia 2; at 8 sphere dia 30; conn 8 to 9 cable length 50 dia 5; /* */ stim rod 101 inten 1e3 start .009 dur .001; /*stim node 101 vclamp -.06 start .005 dur 1; */ /*plot I[101] max 40e-12 min 0; */ plot V[8],V[7],V[101]; /* */ run; 18) Saturation test of 10 cones (tcomp23) plmax = .0; plmin = -.06; endexp = .4; ploti = .001; fdur = .002; istart = 500*1/fdur; for (i=0; i<10; i++) { at i sphere dia 2 rm 10000; at i cone (0,0); stim cone i inten istart*(2^i) start .02 dur fdur; /* */ stim node i vclamp -.03 start 0 dur .4; /* */ plot I[i] max 10e-12 min -40e-12; }; /* for */ plot L[0] max istart*20 min -istart; run; 19) Transfer function for synapse. (tcomp24) vidmode=1; crit = 1e-8; endexp = 1; ploti=.0001; at 1 sphere dia 10; conn 1 to 2 synapse open expon 5 maxcond 1e-9 thresh -.04; at 2 sphere dia 10; conn 1 to 3 synapse open linear 2 maxcond 1e-9 thresh -.04; at 3 sphere dia 10; /* plot V[1] max .04 min -.07; plot V[2] max .04 min -.07; */ stimlen = .015; graph X max .04 min -.08; /* volts */ graph Y max .04 min -.08; /* psp (volts) (expon) */ graph Y max .04 min -.08; /* psp (volts) (linear) */ graph init; /* draw axes */ /* stim node 2 vclamp -.07 start 0 dur 1; /* */ for (i=0,vc=-.045; vc<-.01; vc+=.001,i++) { stim node 1 vclamp vc start i * stimlen dur stimlen; /* */ step stimlen; /* wait for equilbration */ graph (V[1], V[2], V[3]); /* graph result */ }; 20) /* 3 varicosities on single dendrite (varic1.n) */ /* demonstration of electrotonic decay */ vidmode=1; endexp = .012; plmax = -.01; ploti = endexp / 100; disp=0; drm = 3000; at 1 sphere dia 3; conn 1 to 2 cable length 10 dia 0.1; at 2 sphere dia 3; conn 2 to 3 cable length 10 dia 0.1; at 3 sphere dia 3; at 4 sphere dia 3; at 5 sphere dia 3; conn 4 to 1 synapse expon 5 maxcond .51e-9 thresh -.04; conn 5 to 2 synapse expon 5 maxcond .51e-9 thresh -.04; stim node 4 vclamp -.03 start 0 dur .008; stim node 5 vclamp -.03 start .004 dur .008; plot V[5],V[4],V[3],V[2],V[1]; run; 21) Functions defining parts of neural circuits. /* cone function (cone.m) */ func mcone (xpos,ypos,n) { conerm = 3000; at [n] cone (xpos,ypos); /*conn [n] to [n][1] cable dia 10 length 10 ri 5000 rm 1e4;/* 5 x rod os area*/ at [n] sphere dia 16 rm 500000; /* 5 x rod o.s. area */ /*conn [n] to [n+1]cable dia .1 length .2 rm conerm; /* connecting cilium */ at [n] sphere dia 3 rm conerm; conn [n] to [n][1] cable dia 1 length 50 rm conerm; at [n][1] sphere dia 5 rm conerm; return (1); /* return minor node num for cone pedicle */ }; /* procedure to connect cones with gap junctions (congj.m) */ proc congj(xi,xj,xh,xk) { source = conarr[xi][xj][0]; /* source cone */ sz = conarr[xi][xj][1]; dest = conarr[xh][xk][0]; /* dest cone */ dz = conarr[xh][xk][1]; found=0; for (zi=0; zi=arrsiz) continue; if (h<0 || h>=arrsiz) continue; if (i==h && j==k) continue; congj (i,j,h,k); }; for (hztype=0; hztype<2; hztype++) { if (hztype == 0) { /* B-type Hz */ hznum = 6; hzsiz = 10; hznode = 5000; hzoff = hzsiz/2.828; }; if (hztype == 1) { /* A-type Hz */ hznum = hzmax; hzsiz = 14; hznode = 6000; hzoff = hzsiz/2; }; hzcount = 0; hzst = hzsiz/2; for (hzly=hzst,j=0; j =arrsiz) continue; if (y<0 || y>=arrsiz) continue; cnode = conarr[x][y][0]; ped2 = conarr[x][y][1]; htip1 = cnode; htip2 = conarr[x][y][2]++; htip3 = conarr[x][y][2]++; conn [cnode][ped2] to (htip1,htip2) synapse linear 2 maxcond 1e-9 thresh -.050 vrev -.01; if (hztype == 0) { conn [htip1][htip2] to (cnode,ped2) synapse linear 2 maxcond 7e-10 thresh -.055 vrev -.08; } else if (hztype == 1) { conn [htip1][htip2] to (cnode,ped2) synapse linear 2 maxcond 1e-9 thresh -.055 vrev -.08; }; conn [htip1][htip2] to [htip1][htip3] cable dia .1 length 10 rm hbrm vrev hzrev vrest hrest; conn [htip1][htip3] to [hznode] cable dia 2 length 20 rm hbrm vrev hzrev vrest hrest; }; at [hznode] sphere dia 30 rm hbrm vrev hzrev vrest hrest; if (hztype > 0) { hzarr[i][j][0] = hzcount; hzarr[i][j][1] = hznode; }; }; print "# hzcount",hzcount; }; /* for (hztype; ;) */ /* make gap junctions betw A hz cells */ for (i=0; i =hznum) continue; if (h<0 || h>=hznum) continue; if (i==h && j==k) continue; conhz (i,j,h,k); }; stim file hz53.t; stim center (150,90); stim backgr 100 start 0; stim spot 1 loc (150,90) blur 22 inten 2.5e9 start 0.05 dur .001; plot V[475][1] max -.04 min -.07; plot V[474][1] max -.04 min -.07; plot V[473][1] max -.04 min -.07; plot V[472][1] max -.04 min -.07; plot V[471][1] max -.04 min -.07; plot V[470][1] max -.04 min -.07; plot V[469][1] max -.04 min -.07; plot V[468][1] max -.04 min -.07; plot V[467][1] max -.04 min -.07; plot V[465][1] max -.04 min -.07; plot V[460][1] max -.04 min -.07; plot V[455][1] max -.04 min -.07; plot V[450][1] max -.04 min -.07; plot V[5023] max -.04 min -.07; plot V[5022] max -.04 min -.07; plot V[5021] max -.04 min -.07; plot V[5020] max -.04 min -.07; plot V[5019] max -.04 min -.07; plot V[5018] max -.04 min -.07; plot V[5000] max -.04 min -.07; plot V[6003] max -.04 min -.07; run;
NeuronC syntax listing
Terminals and non-terminals The following table (Table 1 below) is the syntax for NeuronC (see "nc.y" for an up-to-date version) in the format for the UNIX language-generator, YACC (yet another compiler-compiler). "Non- terminals" to the left of colons represent grammatical structures recognized by NeuronC; after them is a list of constituent structures, called rules; the "|" (logical "or") in front of a rule means the rule is a possible alternate. If the syntax is not followed exactly, the NeuronC parser identifies the first error and prints its line and character. Extra spaces (more than those needed to separate words) are ignored, as are newlines (line feeds or the "enter" key). In the table below, words in upper case are called "terminals" meaning that they character strings recognized by the lexical analyzer directly from their spelling. They are upper case in the syntax listing for clarity only; in a NeuronC program, they are normally lower case. Curly braces "{}" enclose "C" language statements for the action to be taken when the parser has identified a particular grammatical structure. The action is normally a sequence of pseudo-code to be compiled into a run-time program, which defines calls to "C" language subroutines. Curly braces after a rule contain the action taken when the parser recognizes the rule; you can ignore this. Comments are inside the familiar "/* comment */". A NeuronC program is a "list" in the following table. The first rule for "list" is "/* nothing */" which means that a blank line is acceptable (no error), although it does nothing. One of the possible alternatives to "list" is: list: /* nothing */ . . . | list stmt listerm { code(STOP); return 1; } In other words, "list" can also mean a list followed by a "stmt" and then a "listerm". "listerm" is defined as a semicolon for the "end of line" character, as in the "C" language. Thus "nothing", followed by a single statement, followed by a semicolon is an acceptable NeuronC program. Looking for the definition of the non-terminal "stmt", we see that it includes the definition of all neural elements: stmt: . . . | elemlist { } The description of a neural element must start with a keyword that defines the element's node connection(s), either "at" or "connect", and then may include other keywords to describe geometry or membrane parameters: elemlist: connect {} | elemlist geometry {} | elemlist membrtype {} ; "geometry" in turn describes the type of neural element, and may include parameters specific to that element type. Note that many grammatical structures are self-referential (the same word on left and right of the colon) and are therefore recursive. This allows more flexibility in describing neural elements because in these cases a parameter list need not be specified in any particular order. For example, an "elemlist" can be any of: "connect geometry" "connect geometry" "connect geometry membrane" "connect membrane geometry" Table 1 NeuronC syntax %{ #include#include "nc.h" #define code2(c1,c2) code(c1); code(c2) #define code3(c1,c2,c3) code(c1); code(c2); code(c3) #define code4(c1,c2,c3,c4) code(c1); code(c2); code(c3); code(c4) extern int indef, inlocal, argcount, formal, fname; %} %union { Symbol *sym; /* symbol table pointer */ Inst *inst; /* machine instructions */ int narg; /* number of arguments */ char *name; /* name of file */ } %token NUMBER STRING PRINT PRINTF %token CONST VAR BLTIN UNDEF WHILE IF ELSE %token FUNCTION PROCEDURE RETURN FUNC PROC READ FREAD %token FOR BREAK CONTINUE EDIT INCLUDE COMNDLINE SYSTEM FOREACH %token INCROP DECROP PFIELD ARG LOCAL LOCALVAR DIM ARRAY FFT PFFT %token FNAME SFILE PLOT V I L S MAX MIN %token DISPLAY GRAPH INIT PEN RESTART %token X Y Z XLOC YLOC ZLOC FA0 FA1 FA2 FA3 FA4 FB0 FB1 FB2 FB3 FB4 %token GMOVE GDRAW GRMOVE GRDRAW GPEN GFRAME GROT GCSIZ GDASH GTEXT %token ELEMENT EXCEPT RANGE SIZE DSCALE COLOR HIDE %token XROT YROT ZROT CALIBLIN %token CABLE SPHERE GJ SYNAPSE LOAD RESISTOR AXIALRES MATCHING %token ROD CONE MAXCOND CENTER RECT WAVEL SUN XENON PIGM PATHL ATTF %token STIM BAR SPOT SINE WIDTH LOC DUR START INTEN BACKGR BLUR FILT %token LENGTH DIA RADIUS VCLAMP CCLAMP GNDBATT BATT GNDCAP CAP NODE %token CHAN HH NA K TYPE DENSITY RM RI RG CM OPAMP BUF %token CONNECT AT TO EDIST EFRAC NDIST ONLY NUMCONN NODE1 NODE2 %token CHNOISE PHOTNOISE VESNOISE TIMEC1 NFILT1 TIMEC2 NFILT2 N %token OPEN CLOSE THRESH VREV VREST DELAY IGAIN KD LINEAR EXPON %token RUN STEP ERASE ALL MODIFY ENAME PLACE CPLAM OFFSET PUT %type cexpr commaexpr expr stmt asgn prlist prflist stmtlist stmtls %type cond while if begin end defn txtflist %type for forexpr var foreach elemtype %type elemlist geometry %type stimulus stimlist stimtype stimloc stimstart stimdur stiminten %type stimblur stimfile stimwave stimcenter graphlist graphtype maxmin %type cableparam sphereparam membrtype connect chantype noisetype %type synaptype receptype plotype displist disptype rotatype %type elemfield nodefield elemnum plotlist %type procname listerm arrname %type arglist parglist formarg localvar vararg prfargs %type dimlist nodenum snode %type filename %right '=' %right ADDEQ SUBEQ MULEQ DIVEQ %left OR AND XOR BITAND BITOR %left GT GE LT LE EQ NE %left '+' '-' %left '*' '/' %left UNARYMINUS NOT %right '^' %% list: /* nothing */ | list listerm { code(STOP); return 1; } | list defn listerm { code(STOP); return 1; } | list asgn listerm { code2(expop,STOP); return 1; } | list stmt listerm { code(STOP); return 1; } | list expr listerm { code2(print, STOP); return 1; } | list error listerm { yyerrok; } ; listerm: ';' {} ; elemlist: connect {} | elemlist geometry {} | elemlist membrtype {} | elemlist ENAME var { code2(xmod,(Inst)$2); } | elemlist MODIFY expr { code2(xmod,(Inst)$2); } ; geometry: CABLE cableparam { $$=$2; } | SPHERE sphereparam { $$=$2; } | synaptype { $$=$1; } | CHAN chantype { $$=$2; } | receptype { $$=$1; } | GJ expr { $$=$2; code(gj); } | LOAD expr { $$=$2; code(rload); } | RESISTOR expr { $$=$2; code(resistor); } | CAP expr { $$=$2; code(rcap); } | GNDCAP expr { $$=$2; code(gcap); } | BATT expr { $$=$2; code(rbatt); } | GNDBATT expr { $$=$2; code(gbatt); } | BUF { $$=(Inst *)code(vbuf); } ; cableparam: LENGTH expr { $$=$2; code2(xcable,(Inst)$1); } | DIA expr { $$=$2; code2(xcable,(Inst)$1); } | CPLAM expr { $$=$2; code2(xcable,(Inst)$1); } | cableparam LENGTH expr { code2(xcable,(Inst)$2); } | cableparam DIA expr { code2(xcable,(Inst)$2); } | cableparam CPLAM expr { code2(xcable,(Inst)$2); } ; sphereparam: expr { code2(sphere,(Inst)0); } | DIA expr { $$=$2; code2(sphere,(Inst)$1); } ; chantype: HH { $$=(Inst *)code2(xchan,(Inst)$1);} | NA { $$=(Inst *)code2(xchan,(Inst)$1);} | K { $$=(Inst *)code2(xchan,(Inst)$1);} | chantype TYPE expr { code2(xchan,(Inst)$2); } | chantype VREV expr { code2(xchan,(Inst)$2); } | chantype THRESH expr { code2(xchan,(Inst)$2); } | chantype DELAY expr { code2(xchan,(Inst)$2); } | chantype MAXCOND expr { code2(xchan, (Inst)$2); } | chantype DENSITY expr { code2(xchan, (Inst)$2); } | chantype noisetype { } ; membrtype: chantype { } | RM expr { $$=$2; code(rm); } | RI expr { $$=$2; code(ri); } | RG expr { $$=$2; code(rg); } | CM expr { $$=$2; code(mcap); } | VREV expr { $$=$2; code(mvrev); } | VREST expr { $$=$2; code(mvrest); } | membrtype chantype { } | membrtype RM expr { code(rm); } | membrtype RI expr { code(ri); } | membrtype RG expr { code(rg); } | membrtype VREV expr { code(mvrev); } | membrtype VREST expr { code(mvrest); } ; connect: AT begin nodenum { $$=$2; code2(conn1,(Inst)$3); } | AT begin nodenum LOC parglist /* args backwards here: */ { $$=$2; code3(conn1l,(Inst)$5,(Inst)$3); } | AT begin nodenum ':' elemnum OFFSET expr PUT nodenum { $$=$2; code3(conn1m,(Inst)$9, (Inst)$3); } | CONNECT begin nodenum TO nodenum /* args backwards here */ { $$=$2; code2(conn2d,(Inst)$5); code2(conn2s,(Inst)$3); } | CONNECT begin nodenum LOC parglist TO nodenum { $$=$2; code2(conn2d,(Inst)$7); code3(conn2sl,(Inst)$5,(Inst)$3); } | CONNECT begin nodenum TO nodenum LOC parglist { $$=$2; code3(conn2dl,(Inst)$7,(Inst)$5); code2(conn2s,(Inst)$3); } /* args backwards here: */ | CONNECT begin nodenum LOC parglist TO nodenum LOC parglist { $$=$2; code3(conn2dl,(Inst)$9,(Inst)$7); code3(conn2sl,(Inst)$5,(Inst)$3); } ; synaptype: SYNAPSE begin { $$=$2; } | synaptype OPEN { code2(synapse,(Inst)$2); } | synaptype CLOSE { code2(synapse,(Inst)$2); } | synaptype VREV expr { code2(synapse,(Inst)$2); } | synaptype THRESH expr { code2(synapse,(Inst)$2); } | synaptype TIMEC1 expr { code2(synapse,(Inst)$2); } | synaptype NFILT1 expr { code2(synapse,(Inst)$2); } | synaptype TIMEC2 expr { code2(synapse,(Inst)$2); } | synaptype NFILT2 expr { code2(synapse,(Inst)$2); } | synaptype IGAIN expr { code2(synapse,(Inst)$2); } | synaptype MAXCOND expr { code2(synapse,(Inst)$2); } | synaptype KD expr { code2(synapse,(Inst)$2); } | synaptype LINEAR { code2(synapse,(Inst)$2); } | synaptype EXPON expr { code2(synapse,(Inst)$2); } | synaptype noisetype { } ; noisetype: CHNOISE { $$=(Inst *)code2(noise,(Inst)$1); } | VESNOISE { $$=(Inst *)code2(noise,(Inst)$1); } | noisetype N expr { code2(noise,(Inst)$2); } | noisetype DUR expr { code2(noise,(Inst)$2); } ; receptype: ROD begin parglist { $$=$2;code3(recept,(Inst)$1,(Inst)$3);} | CONE begin parglist { $$=$2;code3(recept,(Inst)$1,(Inst)$3);} | receptype MAXCOND expr { code2(recparm, (Inst)$2); } | receptype DIA expr { code2(recparm, (Inst)$2); } | receptype PIGM expr { code2(recparm, (Inst)$2); } | receptype PATHL expr { code2(recparm, (Inst)$2); } | receptype ATTF expr { code2(recparm, (Inst)$2); } | receptype FILT expr { code2(recparm, (Inst)$2); } | receptype PHOTNOISE { code2(recparm, (Inst)$2); } ; stimulus: stimlist {} | stimulus stimlist {} ; stimlist: stimtype {} | stimloc {} | stimcenter {} | stimstart {} | stimdur {} | stimwave {} | stiminten {} | stimblur {} | stimfile {} ; stimtype: BAR expr { $$=$2; code2(xstim,(Inst)$1); } | SPOT expr { $$=$2; code2(xstim,(Inst)$1); } | RECT begin arglist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3); } | ROD expr { $$=$2; code3(xstim,(Inst)$1,(Inst)1);} | ROD begin dimlist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3);} | CONE expr { $$=$2; code3(xstim,(Inst)$1,(Inst)1);} | CONE begin dimlist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3);} | NODE expr { $$=$2; code3(xstim,(Inst)$1,(Inst)1);} | NODE begin dimlist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3);} ; stimloc: LOC begin parglist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3); } ; stimcenter: CENTER begin parglist {$$=$2;code3(xstim,(Inst)$1,(Inst)$3); } ; stimstart: START expr { $$=$2; code2(xstim,(Inst)$1); } ; stimdur: DUR expr { $$=$2; code2(xstim,(Inst)$1); } ; stimwave: WAVEL expr { $$=$2; code3(xstim,(Inst)$1,(Inst)0); } | WAVEL SUN { $$=(Inst *)code3(xstim,(Inst)$1,(Inst)$2); } | WAVEL XENON { $$=(Inst *)code3(xstim,(Inst)$1,(Inst)$2); } ; stiminten: INTEN expr { $$=$2; code2(xstim,(Inst)$1); } | BACKGR expr { $$=$2; code2(xstim,(Inst)$1); } | VCLAMP expr { $$=$2; code2(xstim,(Inst)$1); } | CCLAMP expr { $$=$2; code2(xstim,(Inst)$1); } ; stimblur: BLUR expr { $$=$2; code2(xstim,(Inst)$1); } ; stimfile: SFILE {fname=1;} filename {fname=0;$$=(Inst *)code3(xstim,(Inst)$1, (Inst)$3);} ; asgn: var '=' expr { code(assign); } | var ADDEQ expr { code(addeq); } | var SUBEQ expr { code(subeq); } | var MULEQ expr { code(muleq); } | var DIVEQ expr { code(diveq); } ; stmt: expr { code(expop); } | LOCAL { inlocal=1; } localvar {inlocal=0; defnonly("local"); $$=(Inst *)code2(local,(Inst)$3);} | RETURN { defnonly("return"); code(procret); } | RETURN expr {defnonly("return"); $$=$2; code(funcret); } | PROCEDURE begin parglist { $$=$2; code3(call, (Inst)$1, (Inst)$3); } | PRINT prlist { $$ = $2; code(crlf); } | PRINTF '(' prflist ')' { $$ = $3; } | for '(' forexpr ';' forexpr ';' forexpr ')' stmt end { ($1)[1] = (Inst)$5; /* body of loop */ ($1)[2] = (Inst)$7; /* body of loop */ ($1)[3] = (Inst)$9; /* body of loop */ ($1)[4] = (Inst)$10; } /* end expr */ | BREAK end { $$ = (Inst *)code(breakcode); } | CONTINUE end { $$ = (Inst *)code(contcode); } | while cond stmt end { ($1)[1] = (Inst)$3; /* body of loop */ ($1)[2] = (Inst)$4; } /* end, if cond fails */ | if cond stmt end { /* else-less if */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[3] = (Inst)$4; } /* end, if cond fails */ | if cond stmt end ELSE stmt end { /* if with else */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[2] = (Inst)$6; /* elsepart */ ($1)[3] = (Inst)$7; } /* end, if cond fails */ | foreach stmt end { /* look through all nodes */ ($1)[2] = (Inst)0; ($1)[3] = (Inst)0; ($1)[4] = (Inst)0; ($1)[5] = (Inst)0; ($1)[6] = (Inst)$2; /* body of loop */ ($1)[7] = (Inst)$3; } /* end, when done */ | foreach NODE snode end stmt end { /* look through all nodes */ ($1)[2] = (Inst)1; ($1)[3] = (Inst)$3; ($1)[4] = (Inst)0; ($1)[5] = (Inst)0; ($1)[6] = (Inst)$5; /* body of loop */ ($1)[7] = (Inst)$6; } /* end, when done */ | foreach NODE snode snode end stmt end { ($1)[2] = (Inst)2; ($1)[3] = (Inst)$3; ($1)[4] = (Inst)$4; ($1)[5] = (Inst)0; ($1)[6] = (Inst)$6; /* body of loop */ ($1)[7] = (Inst)$7; } /* end, when done */ | foreach NODE snode snode snode end stmt end { ($1)[2] = (Inst)3; ($1)[3] = (Inst)$3; ($1)[4] = (Inst)$4; ($1)[5] = (Inst)$5; ($1)[6] = (Inst)$7; /* body of loop */ ($1)[7] = (Inst)$8; } /* end, when done */ | stmtlist { } | EDIT { fname=1; } filename { fname=0; edit ($3); } | INCLUDE {fname=1;} filename { fname=0; $$=(Inst *)code2(pushfil,(Inst)$3); } | COMNDLINE { system ((char *)$1); } | SYSTEM STRING { system ((char *)$2); } | elemlist { } | STIM stimulus { $$=$2; code2(xstim, (Inst)$1); } | PLOT plotlist { $$=$2; } | PLOT plotype begin nodenum maxmin { $$=$3; code3(vplotm,(Inst)$2,(Inst)$4); } | PLOT S var maxmin { $$=$3; code2(vplot,(Inst)$2); } | DISPLAY displist { $$=$2; code2(dispnod,(Inst)$1); } | GRAPH graphlist { $$=$2; } | GMOVE begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GDRAW begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GRMOVE begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GRDRAW begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GPEN begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GROT begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GCSIZ begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GDASH begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GFRAME STRING { $$=(Inst *)code3(gplot,(Inst)$1,(Inst)$2); } | GTEXT '(' txtflist ')'{ $$=$3; } | FREAD begin '('{fname=1;} filename {fname=0;} ',' VAR ',' vararg ')' { $$=$2; code4(xfread,(Inst)$5,(Inst)$8,(Inst)$10); } | DIM begin arrname dimlist {$$=$2;code3(darray,(Inst)$3,(Inst)$4);} | FFT begin '(' ARRAY ')' { $$=$2; code3(dofft,(Inst)$1,(Inst)$4); } | PFFT begin '(' ARRAY ')' { $$=$2; code3(dofft,(Inst)$1,(Inst)$4); } | ERASE ARRAY { $$=(Inst *)code2(erarr,(Inst)$2); } | ERASE ALL { erase(); } | RUN { $$ = (Inst *)code2(modrun,(Inst)$1); } | STEP expr { $$ = $2; code2(modrun,(Inst)$1); } ; plotype: V { } | I { } | L { } | FA0 { } | FA1 { } | FA2 { } | FA3 { } | FA4 { } | FB0 { } | FB1 { } | FB2 { } | FB3 { } | FB4 { } plotlist: plotype begin nodenum { $$=$2; code3(vplot,(Inst)$1,(Inst)$3); } | plotlist ',' plotype nodenum { $$=$1; code3(vplot,(Inst)$3,(Inst)$4); } ; graphlist: graphtype { $$=$1; } | graphlist graphtype { $$=$1; } ; graphtype: begin parglist { $$ = $1; code3 (grph,0L,(Inst)$2);} | INIT { $$ = (Inst *) code3 (grph, (Inst)$1, 0L); } | RESTART { $$ = (Inst *) code3 (grph, (Inst)$1, 0L); } | PEN expr { $$ = $2; code3 (grph,(Inst)$1,(Inst)1); } | PEN begin parglist { $$ = $2; code3 (grph,(Inst)$1,(Inst)$3); } | X maxmin { $$ = $2; code3 (grph, (Inst)$1, 0L); } | Y maxmin { $$ = $2; code3 (grph, (Inst)$1, 0L); } ; maxmin: MAX expr MIN expr { $$ = $2; } ; displist: disptype { $$=$1; } | displist disptype { $$=$1; } disptype: MATCHING begin nodenum { $$=$2; code4(dispnod,(Inst)$1,(Inst)0,(Inst)$3); } | CONNECT begin nodenum TO nodenum { $$=$2; code4(dispnod,(Inst)$1,(Inst)$5,(Inst)$3); } | RANGE begin nodenum TO nodenum { $$=$2; code4(dispnod,(Inst)$1,(Inst)$5,(Inst)$3); } | ELEMENT elemnum { $$=$2; code4(dispnod,(Inst)$1,(Inst)0,(Inst)1); } | elemtype { $$=(Inst *)code2(dispnod,(Inst)$1); } | disptype EXCEPT { code2(dispnod,(Inst)$2); } | rotatype expr { $$=$2; code2(dispnod,(Inst)$1); } | SIZE expr { $$=$2; code2(dispnod,(Inst)$1); } | DSCALE expr { $$=$2; code2(dispnod,(Inst)$1); } | COLOR expr { $$=$2; code2(dispnod,(Inst)$1); } | CALIBLIN expr { $$=$2; code2(dispnod,(Inst)$1); } | HIDE { $$=(Inst *)code2(dispnod,(Inst)$1); } | CENTER begin parglist { $$=$2; code3(dispnod,(Inst)$1,(Inst)$3); } | ONLY { $$=(Inst *)code2(dispnod,(Inst)$1); } ; filename: /* nothing */ { $$ = 0; } | FNAME { $$ = $1->name; } | STRING { $$ = (char *)$1; } ; cond: '(' cexpr ')' {code(STOP); $$ = $2; } ; while: WHILE { $$ = (Inst *)code3(whilecode,STOP,STOP); } ; forexpr: cexpr {code(STOP); $$ = $1; } ; for: FOR { $$ = (Inst *)code(forcode); code4(STOP,STOP,STOP,STOP); } ; if: IF { $$ = (Inst *)code(ifcode); code3(STOP,STOP,STOP); } ; foreach: FOREACH { $$ = (Inst *)code(foreacode); code3((Inst)0,STOP,STOP); code4(STOP,STOP,STOP,STOP); } | FOREACH elemtype '?' var { $$ = (Inst *)code(foreacode); code3((Inst)$2,STOP,STOP); code4(STOP,STOP,STOP,STOP); } | FOREACH ELEMENT '?' var { $$ = (Inst *)code(foreacode); code3((Inst)$2,STOP,STOP); code4(STOP,STOP,STOP,STOP); } ; elemtype: CABLE { } | SPHERE { } | SYNAPSE { } | CHAN { } | ROD { } | CONE { } | GJ { } | LOAD { } | RESISTOR { } | CAP { } | GNDCAP { } | BATT { } | GNDBATT { } | BUF { } ; begin: /* nothing */ { $$ = progp; } ; end: /* nothing */ { code(STOP); $$ = progp; } ; stmtlist: '{' stmtls '}' { $$ = $2; } ; stmtls: /* nothing */ { $$ = progp; } | stmtls stmt listerm ; expr: NUMBER { $$ = (Inst *)code2(constpush, (Inst)$1); } | CONST { $$ = (Inst *)code3(varpush,(Inst)$1,eval); } | var { $$ = $1; code(eval); } | var INCROP { $$ = $1; code(postinc); } | var DECROP { $$ = $1; code(postdec); } | INCROP var { $$ = $2; code(preinc); } | DECROP var { $$ = $2; code(predec); } | asgn | FUNCTION begin parglist { $$ = $2; code3(call,(Inst)$1,(Inst)$3); } | READ '(' var ')' { $$ = (Inst *)code2(varread, (Inst)$3); } | BLTIN begin parglist { $$=$2; code3(bltin,(Inst)$3,(Inst)$1->u.ptr);} | plotype begin nodenum { $$=$2; code3(xrecord, (Inst)$1, (Inst)$3); } | EDIST begin '(' nodenum ',' elemnum ')' { $$=$2; code2(edist, (Inst)$4); } | EFRAC begin '(' nodenum ',' elemnum ')' { $$=$2; code2(efrac, (Inst)$4); } | NDIST begin '(' nodenum ',' nodenum ')' /* args are backward here: */ { $$=$2; code3(ndist, (Inst)$6, (Inst)$4); } | ELEMENT elemnum PFIELD elemfield { $$=$2; code2(efield, (Inst)$4); } | NODE begin nodenum PFIELD nodefield { $$=$2; code3(nfield,(Inst)$5, (Inst)$3);} | '(' cexpr ')' { $$ = $2; } | expr '+' expr { code (add); } | expr '-' expr { code (sub); } | expr '*' expr { code (mul); } | expr '/' expr { code (xdiv); } | expr '^' expr { code (power); } | '-' expr %prec UNARYMINUS { $$=$2; code(negate); } | expr GT expr { code (gt); } | expr GE expr { code (ge); } | expr LT expr { code (lt); } | expr LE expr { code (le); } | expr EQ expr { code (eq); } | expr NE expr { code (ne); } | expr AND expr { code (xand); } | expr OR expr { code (orx); } | expr BITAND expr { code (bitand); } | expr BITOR expr { code (bitor); } | NOT expr { $$ = $2; code (xnot); } ; commaexpr: expr ',' expr { code(popone); } | commaexpr ',' expr { code(popone); } ; cexpr: expr { } | commaexpr { } ; var: VAR { $$ = (Inst *)code2 (varpush, (Inst)$1); } | ARRAY begin dimlist {$$ = $2; code3 (varpush, (Inst)$1,(Inst)$3); } | ARG {$$=(Inst *)code2(varpush,(Inst)$1->u.argnum);} | LOCALVAR {$$=(Inst *)code2(varpush,(Inst)$1->u.argnum);} ; prlist: expr { code(prexpr); } | STRING { $$ = (Inst *)code2(prstr, (Inst)$1); } | prlist ',' expr { code(prexpr); } | prlist ',' STRING { code2(prstr, (Inst)$3); } ; prflist: STRING { $$=(Inst *)code3(pprintf,(Inst)0,(Inst)$1);} | STRING ',' begin prfargs {$$=$3; code3(pprintf, (Inst)$4, (Inst)$1);} ; txtflist: STRING { $$= (Inst *)code3(txtf,(Inst)0,(Inst)$1);} | STRING ',' begin prfargs {$$=$3;code3(txtf,(Inst)$4,(Inst)$1);} ; prfargs: expr { $$ = 1; } | prfargs ',' expr { $$ = $1 + 1; } /* how many args? */ ; defn: FUNC procname { $2->type=FUNCTION; indef=1; formal=1; } '(' formarg ')' { formal=0; } stmt {code(procret); define($2); erasarg();indef=0; } | PROC procname { $2->type=PROCEDURE; indef=1; formal=1; } '(' formarg ')' { formal=0; } stmt {code(procret); define($2); erasarg();indef=0; } ; dimlist: '[' expr ']' { $$ = 1; } | dimlist '[' expr ']' { $$ = $1 + 1; } ; nodenum: expr { $$ = 1; } | dimlist { $$ = $1; } ; elemnum: expr { $$ = $1; } ; snode: '?' var { $$ = 1; } | '[' expr ']' { $$ = 0; } ; elemfield: TYPE { } | LENGTH { } | NDIST { } | DIA { } | RM { } | RI { } | CPLAM { } | NODE1 { } | NODE2 { } ; nodefield: NUMCONN { } | XLOC { } | YLOC { } | ZLOC { } | expr { $$ = (Inst *)0; } /* relative elem # */ ; procname: VAR | FUNCTION | PROCEDURE ; rotatype: XROT { } | YROT { } | ZROT { } ; arrname: VAR ; arglist: /* nothing */ { $$ = 0; } | expr { $$ = 1; } | arglist ',' expr { $$ = $1 + 1; } ; parglist: '(' arglist ')' { $$ = $2; } ; formarg: /* nothing */ { $$ = 0; argcount=0; } | ARG { $$ = $1->u.argnum = 1; argcount=1; } | formarg ',' ARG { $$ = $3->u.argnum = $1 + 1; argcount++; } ; localvar: /* nothing */ { $$ = 0; } | LOCALVAR { $$ = 1; $1->u.argnum = ++argcount; } | localvar ',' LOCALVAR { $$ = $1 + 1; $3->u.argnum = ++argcount; } ; vararg: var { $$ = 1; } | vararg ',' var { $$ = $1 + 1; } ; %% /* end of grammar */