.. index:: syntax (HOC)
HOC was the original programming language supported by NEURON. NEURON may also be programmed in Python.
.. index:: comments
- Syntax:
/*...*/
//...
- Description:
- Comments are similar in style to C++. Enclose any text in /.../ (but do not nest them). The rest of a line after // is a comment.
.. index:: expression
- Description:
- An expression has a double precision value. It usually appears as the right hand side of an assignment statement. An expression may be a number, variable, function call, or combination of simpler expressions.
- Options:
The ways in which expressions can be combined are listed below in order of precedence. e stands for any expression, v stands for any variable and operators are left associative except for assignment operators which are right associative.
(e)
- grouping
e^e
- exponentiation
-e
- negation
e*e e/e e%e
- multiplication, division, modulus
e+e e-e
- addition, subtraction
e==e e!=e e<e e<=e e>e e>=e
logical equal, unequal, less than, less than or equal, greater than, greater than or equal. These expressions have the numerical value 1 (true) or 0 (false). The expression is considered true if it is within :data:`float_epsilon` of being mathematically exact.
Special logical expressions of the form objref1 == objref2 (and obj != obj) are also allowed and return 1 (0) if the object references label the same object. This makes the former comparison idiom using :func:`object_id` obsolete. Logical expressions of the strdef1 == strdef2 cannot be directly compared because of parser consistency reasons. However obj1.string1 == obj2.string2 will return true if the strings are identical in the sense of :func:`strcmp` .
e&&e
- Logical and. Both expressions are always evaluated. A subexpression is considered false if it is within :data:`float_epsilon` of 0 and true otherwise. If the entire expression is true its value is 1.
e||e
- Logical or. Both expressions are always evaluated. A subexpression is considered false if it is within :data:`float_epsilon` of 0 and true otherwise. If the entire expression is true its value is 1.
v=e v+=e v-=e v*=e v/=e
- assignment. others are equivalent to
v = (v + e)
,v = (v - e)
,v = (v * e)
,v = (v / e)
, respectively.
.. seealso:: :data:`float_epsilon` .. index:: statement
- Syntax:
stmt
{stmt}
{stmt stmt ...stmt}
- Description:
- A statement is something executable that does not have a value, eg. for loops, procedure calls, or a compound statement between braces. An expression may be used anywhere a statement is required.
Example:
i = 0 //initialize i j = 0 //initialize j if(vec.x[i] <= 10 && i < vec.size()){ //In the parentheses is an expression: //if the value of the ith element in vec //is less than or equal to 10, and //if i is an index within vec // //Between the braces is/are statement(s): vec1.x[j] = vec.x[i] i = i+1 //increment i by 1 j = j+1 //increment j by 1 } else{ //Here is also a statement i = i+1 //simply go to the next element of vec }Statements exist between the braces following the
if
andelse
commands. The parentheses after theif
command contain an expression.
.. index:: proc
- Syntax:
- :samp:`proc {name}() stmt`
- Description:
- Introduce the definition of a procedure. A procedure does not return a value. You should always try to distill your programs into small, manageable procedures and functions.
Example:
proc printsquare() {local x x = $1 print x*x } printsquare(5)prints the square of 5.
Procedures can also be called within other procedures. The code which produces the interactive examples for the :class:`Random` class contains procedures for both creating the buttons which allow you to select parameters as well as for creating the histograms which appear on the screen.
.. index:: func
- Syntax:
- :samp:`func {name}() {{stmt1, stmt2, stmt3...}}`
- Description:
- Introduce the definition of a function. A function returns a double precision value.
Example:
func tan() { return sin($1)/cos($1) } tan(PI/8)creates a function
tan()
which takes one argument (floating point or whole number), and contains one statement.
.. index:: obfunc
- Syntax:
- :samp:`obfunc {name}() {{ statements }}`
- Description:
- Introduce the definition of a function returning an objref
Example:
obfunc last() { // arg is List return $o1.object($o1.count - 1) }
.. seealso:: :ref:`localobj <keyword_localobj>`, :ref:`return <keyword_return>`
.. index:: iterator
- Syntax:
iterator name() stmt
- Description:
- Define a looping construct to be used subsequently in looping over a statement.
Example:
iterator case() {local i for i = 2, numarg() { //must begin at 2 because the first argument is //in reference to the address $&1 = $i //what is at the address will be changed *iterator_statement* //This is where the iterator statement will //be executed. } }In this case
x=0 for case (&x, 1,2,4,7,-25) { print x //the iterator statement }will print the values 1, 2, 4, 7, -25
The body of the
for name(..) statement
is executed in the same context as a normal for statement. The name is executed in the same context as a normal procedure but should use only variables local to the iterator.
.. index:: arguments
Arguments to functions and procedures are retrieved positionally.
$1, $2, $3
refer to the first, second, and third scalar arguments
respectively.
If "i
" is declared as a local variable, $i
refers
to the scalar argument in the position given by the value of i
.
The value of i
must be in the
range {1...numarg()}.
The normal idiom is
for i=1, numarg() {print $i}
Scalar arguments use call by value so the variable in the calling statement cannot be changed.
If the calling statement has a '&'
prepended to the variable then it is passed by reference and must
be retrieved with the
syntax $&1, $&2, ..., $&i
. If the variable passed by reference
is a one dimensional array then $&1
refers to the first (0th) element
and index i is denoted $&1[i]
. Warning, NO array bounds checking is
done and the array is treated as being one-dimensional. A scalar or
array reference may be passed to another procedure with
&$&1
. To save a scalar reference use the :class:`Pointer` class.
Retrieval of strdef arguments uses the syntax: $s1, $s2, ..., $si
.
Retrieval of objref arguments uses the syntax: $o1, $o2, ..., $oi
.
Arguments of type :ref:`strdef <keyword_strdef>` and objref
use call by reference so the calling
value may be changed.
Example:
func mult(){ return $1*$2 }defines a function which multiplies two arguments. Therefore
mult(4,5)
will return the value 20.proc pr(){ print $s3 print $1*$2 print $o4 }defines a procedure which first prints the string defined in position 3, then prints the product of the two numbers in positions 1 and 2, and finally prints the pointer reference to an object in position 4.
For a string '
s
' which is defined ass = "hello"
, and an objref 'r
',pr(3,5,s,r)
will returnhello 15 Graph[0]assuming
r
refers to the first graph.
.. seealso:: :ref:`func`, :ref:`proc`, :ref:`objref`, :ref:`strdef <keyword_strdef>`, :class:`Pointer`, :func:`numarg`, :func:`argtype`
.. function:: numarg Syntax: ``n = numarg()`` Description: Number of arguments passed to a user written hoc function. .. seealso:: :ref:`arguments`, :func:`argtype`
.. function:: argtype Syntax: ``itype = argtype(iarg)`` Description: The type of the ith arg. The return value is 0 for numbers, 1 for objref, 2 for strdef, 3 for pointers to numbers, and -1 if the arg does not exist. .. seealso:: :ref:`arguments`, :func:`numarg`