<head><title>ColdC: Language Structure: Expressions</title></head> <body> <h1 align=center><a href="/ColdC/">ColdC</a>: <a href="/ColdC/Structure/">Language Structure</a>: Expressions</h1> <hr> <P> Expressions are ColdC <a href="tokens.html"><i>tokens</i></a> and <a href="#operators"><i>operators</i></a> which, when evaluated, will perform their functionality and take on a value after completion (also known as the <i>return value</i>). If they evaluated without error, the return value is a standard ColdC data type. If an error occured, the return value is an error data type, and execution of the method is halted. For more information on errors see the section on <a href="/ColdC/errors.html">Errors</a>. <P> <h2><a name="data" href="types.html">Data Types</a></h2> <p>All ColdC data has a type and a logical truth value it will take on when evaluated as an <a href="expressions.html"><i>expression</i></a>. Each data type is explained in the section <a href="types.html"><i>Data Types</i></a>. <h2><a name="vars">Variables</a></h2> <CODE>ColdC</CODE> provides two kinds of variables, <i>local variables</i> and <i>object variables</i>. <P><i>Local variables</i> are used within methods to temporarily store data. In order for a local variable to be used it must first be declared at the top of the method in a <code>var</code> declaration (see section <A HREF="/ColdC/Methods/">Methods and Method Structure</A>). <i>Object variables</i> are defined on an object, and can be used to store data for an indefinite period of time. More information on Variables can be found in the section <a href="/ColdC/Objects/variables.html">Variables</a>. <p>When a variable is evaluated as an expression, its value is that of its contents (the data stored in the variable name). Initially variables will contain the integer data value of zero (<code>0</code>). <P> To set the contents of a variable, use the <i>assignment expression</i>, which has the following syntax: <P> <blockquote> <PRE> <VAR>variable</VAR> = <VAR>value</VAR>; </PRE> </blockquote> <P> This assigns the value <i>value</i> to the variable <i>variable</i>. The values of a method's local variables are specific to the instant it is being processed. When the method is invoked at another time all of the local variables begin again with the value of zero (<code>0</code>). <P> Some examples of variable expressions follow: <P> <blockquote><pre>total = 3;</pre></blockquote> When evaluated, this expression has the value of three (<code>3</code>). <blockquote><pre>total + 3;</pre></blockquote> If the variable <i>total</i> was not previously assigned this expression would evaluate to three (<code>3</code>), otherwise it would be three plus the previous value of the variable <i>total</i>. <p>If the variable is a local variable, it must be declared at the top of the method. If it is not declared at the top of the method, the interpreter will assume it is an object variable. In the case that both a local variable and an object variable have the same name, the local variable will take precedence and be used in the method. In order to retrieve and set data on the object variable you must use the functions <a href="/ColdC/Functions/get_var.html">get_var()</a> and <a href="/ColdC/Functions/set_var.html">set_var()</a>. These functions need only be used if there is a concern about which variable will be used. If the variable is not declared in the method, the interpreter will always try to find it as an object variable. <h2><a name="operators">Operators</a></h2> <p>Operators are used to perform simple operations on expression values, such as adding two values together. <CODE>ColdC</CODE> provides a variety of operators to perform arithmetic and logical operations on data. Most of these operators fall into two syntactical categories: <i>unary operators</i> and <i>binary operators</i>. <P> <i>Unary operators</i> act on a single expression value. In <CODE>ColdC</CODE>, all unary operators are single characters which precede expressions. For example, <CODE>!a</CODE> is the logical negation of the value of the variable <CODE>a</CODE>. <P> <i>Binary operators</i> act on two expression values. For example, <CODE>a + b</CODE> is the sum of the values of the variables <CODE>a</CODE> and <CODE>b</CODE>. <P> Several operators or values are neither unary nor binary. <h3>Operator Precedence</h3> <P> It is easy to write an expression whose order of evaluation is unclear. For instance, the expression <CODE>a - b + c</CODE> could be parsed as <CODE>(a - b) + c</CODE> or as <CODE>a - (b + c)</CODE>. To resolve these conflicts, each operator has two properties: <i>precedence</i> and <i>association</i>. <P> <i>Precedence</i> determines whether an operator binds more tightly than another operator; for instance, <CODE>a + b * c</CODE> is equivalent to <CODE>a + (b * c)</CODE> because multiplication has higher precedence than addition. <P> <i>Association</i> determines whether operators at the same precedence level associate left to right or right to left; <CODE>a - b - c</CODE> is equivalent to <CODE>(a - b) - c</CODE> because subtraction associates left to right. <P> Here is a list of operators grouped by precedence, in order from highest precedence to lowest: <P> <blockquote><pre> [] . -- ++ ! <i>and unary</i> - * / % + - == != > >= < <= in && || ?| = += -= /= *= </pre></blockquote> All operators associate from left to right except the <CODE>&&</CODE>, <CODE>||</CODE>, and <CODE>?|</CODE> operators, which associate from right to left. You can always use parentheses (<SAMP>`('</SAMP> and <SAMP>`)'</SAMP>) to specify the order of evaluation explicitly. <h3>Assignment Operator</h3> The assignment operator evaluates an expression and assigns the value to a variable. The syntax of the assignment expression is: <blockquote><PRE> <VAR>variable</VAR> = <VAR>expression</VAR> </PRE></blockquote> <p>The interpreter assigns the value of <VAR>expression</VAR> to <VAR>variable</VAR>. <a name="arith"> <h3>Arithmetic Operators</h3> </a> <P><CODE>ColdC</CODE> provides seven operators for doing arithmetic, two unary operators and five binary operators. These operators apply primarily to integers and floats, but the addition operator also applies to strings. Using these operators on inappropriate data is an error of type <CODE>~type</CODE>. <P> The unary <CODE>-</CODE> operator takes the negative of an numeric value. The expression <CODE>-(3 + 4)</CODE> has the value <CODE>-7</CODE>. The unary <CODE>+</CODE> operator has no effect on its argument, and is provided only for completeness. <P> The binary operator <CODE>*</CODE> performs multiplication on its arguments. The expression <CODE>(3 * 4)</CODE> has the value <CODE>12</CODE>. The binary operators <CODE>/</CODE> and <CODE>%</CODE> perform division and modulus, respectively, on their arguments. The expressions <CODE>(13 / 5)</CODE> and <CODE>(13 % 5)</CODE> have the values <CODE>2</CODE> and <CODE>3</CODE> respectively. <P>The binary operators <CODE>+</CODE> and <CODE>-</CODE> perform addition and subtraction. The expressions <CODE>(3 + 4)</CODE> and <CODE>(3 - 4)</CODE> have the values <CODE>7</CODE> and <CODE>-1</CODE> respectively. The binary <CODE>+</CODE> operator can also apply to strings and lists, in which case it performs concatenation; the expression <CODE>("foo" + "bar")</CODE> has the value <CODE>"foobar"</CODE>, and the expression <CODE>(["foo", "bar"] + ["baz"])</CODE> has the value <CODE>["foo", "bar", "baz"]</CODE>. Furthermore, applying the binary <code>+</code> operator with the string as one value, and any other data type as the other value will result in the literal representation of that value being concatenated with the string. For instance, <code>"list: " + [1, 2, 3, 4]</code> has the value <code>"list: [1, 2, 3, 4]"</code>. <p>If both sides of a binary arithmetic expression are integers, the result will always be an integer, even if it could be a float. If one side of the expression is a float, the result will always be a float. For instance, <code>3 / 2</code> (both integers) would result in <code>1</code>, whereas <code>3 / 2.0</code> would result in <code>1.500000</code>. <h3>Logical Operators</h3> <P><CODE>ColdC</CODE> provides a number of relational and logical operators. These operators are primarily useful for expressing conditions, since they return either true or false, represented by the integers <CODE>1</CODE> and <CODE>0</CODE>. <P>The <CODE>==</CODE> and <CODE>!=</CODE> operators test for equality and inequality, respectively, of their arguments. Two pieces of data are equal if they have the same type and contain the same value. Equality of strings is not case-sensitive, but equality of symbols is, so <CODE>("foo" == "fOo")</CODE> is true, but <CODE>('car == 'CAr)</CODE> is false. Lists are equal if all of their elements are equal. <P>The <CODE><</CODE>, <CODE><=</CODE>, <CODE>>=</CODE>, and <CODE>></CODE> operators test whether their left-hand arguments are less than, less than or equal to, greater than or equal to, or greater than their right-hand arguments, respectively. Arguments to these operators must both be of the same type, and must be of integer, string, or objnum type. String comparison is not case-sensitive, so <CODE>("fooa" < "fooB")</CODE> is true, even though the ASCII value of <SAMP>`a'</SAMP> is greater than that of <SAMP>`B'</SAMP>. <P>The unary <CODE>!</CODE> operator tests whether its argument is false, thus acting as a logical not operation. <p>The operators <code>+=</code>, <code>-=</code>, <code>/=</code> and <code>*=</code> are a combination of the respective arithmetic operator and an assignment operator. Using these operators will first perform the arithmetic operation (such as addition)--with the left value being the variable and the right value being an expression--and will then assign the result back to the variable. The arithmetic operators will function the same as their regular counterparts. Examples (the variable <var>this</var> will be assumed to start at an integer value of 10): <blockquote><pre> this += 15; => 25 this += " total"; => "10 total" this /= 2; => 5 this *= 2; => 20 </pre></blockquote> <h3>Conditional Operators</h3> <P>The <CODE>||</CODE> and <CODE>&&</CODE> operators act as logical OR and AND operators, respectively. The expression <CODE>(this || that)</CODE> is equivalent to <i>this OR that</i>, where the return value of the expression is <var>this</var> if <var>this</var> is logically true. If <var>this</var> is not logically true then the return value of the expression is <var>that</var>. <p>The expression <CODE>(this && that)</CODE> is equivalent to <i>this AND that</i>, where the return value of the expression is logically true when both <var>this</var> and <var>that</var> are also logically true. If either <var>this</var> or <var>that</var> are not logically true then the return value is false. <p><CODE>ColdC</CODE>'s conditional operators are <i>short-circuit operators</i>, meaning that the right-hand argument is never evaluated if the left-hand argument is sufficient to determine the value of the expression. This is important if the right-hand argument has side-effects or could cause an error. For instance, because of this it is possible to have the following expression: <p> <blockquote><pre> (| dict[key] |) || throw(~keynf, "Key " + key + " is not in the dictionary."); </pre></blockquote> <p>With this expression if <var>key</var> is in the dictionary <var>dict</var> then the return value is the related value to <var>key</var>. If it is not, the error <code>~keynf</code> is thrown by the index operator (<code>[]</code). However, the expression is a <a href="#critical"><i>critical expression</i></a>. Because of this the left value becomes <var>~keynf</var>, which is logically false, and the interpreter moves onto the throw function. <P> The <CODE>?|</CODE> operator is a trinary operator, with the following syntax: <P> <blockquote><PRE> <VAR>condition</VAR> ? <VAR>true-expr</VAR> | <VAR>false-expr</VAR> </PRE></blockquote> <P> The result of this expression is the result of <VAR>true-expr</VAR> if <VAR>condition</VAR> is true, or the result of <VAR>false-expr</VAR> if <VAR>condition</VAR> is false. See section <A HREF="types.html">Data Types</A> for the definition of truth for <CODE>ColdC</CODE> data. <h2><a name="funcs">Calling Functions</a></h2> <p>Functions are driver-defined procedures which perform a certain action which ColdC is incapable of (such as opening a network connection), or which the driver can handle more efficiently. A function is called using the <i>function call expression</i>, which has the following syntax: <P> <blockquote> <PRE> <VAR>function</VAR>(<VAR>arg1</VAR>, <VAR>arg2</VAR>, <VAR>...</VAR>) </PRE> </blockquote> <P> <VAR>function</VAR> is an identifier naming the function, and <VAR>arg1</VAR>, <VAR>arg2</VAR>, <VAR>...</VAR> are expressions. There do not have to be any arguments, but you must include the parentheses even if there are no arguments. The arguments are evaluated from left to right. <P>As an example, the <CODE>pad()</CODE> function pads a string argument with spaces to a certain length. When evaluated with the string "foo" and a length of six characters: <blockquote><PRE> pad("foo", 6) => "foo " </PRE></blockquote> <p>Note: to better undestand the above example, read <a href="/ColdC/convention.html">A Note on Conventions</a>. <P>There are driver functions available for a variety of tasks. A comprehensive explanation of the available functions is available in the section <a href="/ColdC/Functions/">Function/Method Reference</a>. <h2><a name="meths">Calling Methods</a></h2> <P>Methods defined on an object can be executed with the <i>method-call expression</i>, which has the following syntax: <blockquote><PRE> <VAR>receiver</VAR>.<VAR>method</VAR>(<VAR>arg1</VAR>, <VAR>arg2</VAR>, <VAR>...</VAR>) </PRE></blockquote> <P>You may omit <VAR>receiver</VAR>, in which case it is assumed to be the current object. If <var>receiver</var> is not an object or frob data type, the interpreter will first attempt to lookup an object name using the data type's symbol name. If an object exists with that name, the method is called on that object. If not, or if receiver is an object which does not exist in the database, the error <code>~objnf</code> is thrown. Otherwise, if <VAR>receiver</VAR> is an object, then the method is called on the object. The result is the value returned by the method. If the method does not return a value, the result is <var>receiver</var>. If <VAR>receiver</VAR> is a frob, then the called on the frob's class object, with the frob's representation inserted as the first argument (other arguments are placed after the representation). <p><var>method</var> must be either the name of the method, or an expression which results in a symbol for the name of the method. If <var>method</var> cannot be found on <var>receiver</var> or any of <var>receiver</var>'s ancestors, then the error <code>~methodnf</code> is thrown. <p><VAR>arg1</VAR>, <VAR>arg2</VAR>, <VAR>...</VAR> are the arguments for the method. Arguments are evaluated from left to right, as with function arguments. You must include the parentheses around the argument list, even if there are no arguments. <p>Here are some examples of method-call expressions: <blockquote><PRE> .tell("I don't see that here."); => $lynx $sys.admins(); => [$lynx, $dancer, $jenner] ([1, 2, 3]).reverse() => [3, 2, 1] $parser.(tosym(what + "_mesg"))(messages) => $parser (<$thing_frob, #[['myname, "coins"], ['amount, 300]]>).name() => "300 coins" </PRE></blockquote> <p>In order to prevent incidents of infinite recursion, there is a maximum calling depth for methods. If calling a method would exceed the maximum calling depth, the error <CODE>~maxdepth</CODE> is thrown. <h3>Calling an Overridden Method</h3> <P>If a method overrides another method defined on an ancestor, the overriding method can call the overridden method using the function <code>pass()</code>. Arguments to <code>pass()</code> are sent to the overridden method as if the method were called normally. The return value of <code>pass()</code> is the normal return value of the overridden method. <p>For instance, passing to an overridden method with: <blockquote><pre> pass("this arg", 2); </blockquote></pre> Would be rougly equivalent to calling the same method, if it was not overridden, with: <blockquote><pre> obj.method("this arg", 2); </blockquote></pre> <p>When executed in this manner, the overridden method sees the same object, sender, and caller as the current method. <h2><a name="errors">Error-Handling Expressions</a></h2> <a name="critical"></a> <P>Two mechanisms exist for handling errors in expressions. These are the <i>critical expression</i> and the <i>propagation expression</i>. The <i>critical expression</i> allows you to ignore errors which occur inside an expression. It has the following syntax: <blockquote><PRE> (| expression |) </PRE></blockquote> <p>If an error occurs in <VAR>expression</VAR> the interpreter will stop evaluating <VAR>expression</VAR> and continue to execute the current method as if it had succeeded evaluating <VAR>expression</VAR>. The value of <VAR>expression</VAR> will be the error code for the error which occurred. <a name="propagate"></a> <P>The <i>propagation expression</i> allows you to indicate that any errors which occur inside an expression are the responsibility of the calling routine. It has the following syntax: <blockquote><PRE> (> expression <) </PRE></blockquote> <p>If an error occurs in <VAR>expression</VAR> it will propagate to the calling method as if the error had originated in the calling method and not in the current method. Otherwise, the calling method will receive the error as <code>~methoderr</code>. <P>Critical expressions override the behavior of catch statements so that errors which occur within critical expressions do not trigger catch error handlers. Propagation expressions do not override critical expressions or catch statements, however. They do not prevent errors from being caught; they only determine how errors propagate if they are not caught. <P>For more information on handling errors, see section <A HREF="/ColdC/errors.html">Errors</A>. <h2><a name="splicing">Splicing</a></h2> <P>Whenever you are writing an argument list or a list constructor expression you can splice a list value into the sequence of expressions by prepending a list expression with <SAMP>`@'</SAMP>. For example: <blockquote><pre> ['foo, @[1, 2, 3], 'quux] => ['foo, 1, 2, 3, 'quux] </pre></blockquote> <p>You can use the splicing operator when sending arguments: <blockquote><pre> $string.do_something(this, that, @others); </pre></blockquote> <p>The splicing operator is not listed in the operator precedence list (see section <A HREF="coldmud.html#SEC26">Precedence</A>). This is because it is meaningless to talk about, for example, adding a spliced list to another value. Using the splicing operator never causes an ambiguity. <hr size=4><p align=center><i>Last Modified on Mar 2 1996</i> <br><i>Copyright © 1995, 1996, Brandon Gillespie</i> </body>