Skip to content

Expressions

mmaness edited this page Oct 5, 2011 · 11 revisions

This section describes the structure of expressions in Survenity.

Arithmetic Conversions

Only numeric types may be used in arithmetic operations. The following rule(s) govern conversions of those types:

  • If either argument is a decimal, the other is converted to a decimal
  • Otherwise, both must be integers and no conversion takes place Some operators have additional rules, consult the operator sections below.

Elements / Types

Elements or types are the building blocks of expressions. The syntax for elements is:

element ::= identifier | literal | enclosure
enclosure ::= parenthesized_expression | list

Identifier

An identifier can occur as an element. That identifier is bound to an object. See the execution model for more information.

Literals

Survenity supports the following literals:

literal ::= integer | decimal | string_literal

Literals evaluate to their given type and values. See the lexical analysis section for more information. Note that literals refer to immutable data types. There is no guarantee that evaluation of two literals with the same value will refer to two different objects.

Parenthesized Expression

A parenthesized expression follows the following form:

parenthesized_expression ::= "(" expression ")"

The value of a parenthesized expression is the same as the value of expression between the matching parentheses.

A pair of matching parentheses with no value between has no meaning in Survenity and would cause a parsing error.

List

A list is denoted by a pair of matching square brackets, '[' and ']'. It has the following form:

list ::= "[" literal* "]"  *** DOUBLE CHECK THIS, it may be expression rather than literal ***

A list evaluates to a list object with the elements of the list included in the list (references to those objects, not copies).

Primaries

The most tightly bound operation in Survenity is called a primary. The syntax is:

primary ::= element | subscription | call

Subscription

A subscription selects an item inside a sequence. This is currently only supported for lists and not strings.

subscription ::= primary "[" expression "]"

The primary must evaluate to a object that is a sequence. The expression must evaluate to an integer. This integer represents a location or mapping in the primary sequence. Negative integers are not currently supported but their intended behavior would be to take the length of the sequences and add the negative integer to it in order to find the mapping.

Call

A call calls a callable object with a set of arguments (if any):

call ::= primary "(" parameters? ")"
parameters ::= ( (expression "," parameters) | expression )

The primary must evaluate to an object that is callable, such as a function. All of the expressions in the parameters are evaluated in order from left-to-right.

Each expression in a call (comma-separated) is called an argument. If there are more arguments in a call than it is defined to use, then a TooManyArgumentsError is thrown. If there are fewer arguments in a call than it is defined to use, then a TooFewArgumentsError is thrown.

A call must always return an object (null object included) unless an error occurs.

The Sequential Operator

The sequential operator has the following syntax:

sequential ::= primary | (primary ".." primary)

The sequential operation takes two integers and returns a list with that contains all integers between the two integers inclusive. The first element in that list is the value of the primary and the last element is the value of the expression. Its operation is undefined for non integer operands.

Binary Arithmetic Operations

The binary arithmetic operators has the standard order of precedence with exponentiation having the highest precedence. The following syntax governs binary arithmetic operations:

exponentiation ::= sequential | (exponentiation "^" sequential)
product ::= exponentiation | (product ("*" | "/" | "//" | "%") exponentiation)
summation ::= product | (summation ("+" | "-") product)

The power operator '*' yields the value of the left hand operand raise to the right hand operand power. Both operands must evaluate to numbers.

The division '/' and integer division '//' operators yield the quotient of their operands. The left operand is divided by the right operand. Division is an operation between two numbers which can result in decimal numbers (e.g. 3 / 2 equals 1.5). Integer division is division in which the floor of the quotient is returned (e.g. 3 // 2 equals 1). Division by zero results in a DivisionByZeroError being thrown.

The modulo operator '%' returns the value of the left operand mod right operand. This concept is similar to remainder. The modulo operator should operator exactly as the modulo operator behaves in Ruby. The value of modulo operator always has the same sign as that of the right operand.

The multiplication operator returns the product of two operands.

The addition operator '+' returns the sum of two operands.

The subtraction operator '-' returns the difference between the left and right operands.

Evaluation Order

Survenity evaluates expressions in order of precedence then from left to right when precedence is similar.

Summary

So the following list summarizes the order of precedence in Survenity from highest precedence to lowest precedence:

  1. '( expression )' - Parenthesized Expression
  2. 'x[ index ]' - Subscription
  3. '..' - Sequence
  4. '^' - Exponentiation
  5. '*' , '/' , '//' , '%' - Multiplication, Division, Integer Division, and Modulo
  6. '+' , '-' - Addition and Subtraction

Go back to Survenity Language Reference

Home | JULIE Intro | Getting Started with JULIE | JULIE References | JULIE Development | Survenity Language