134 lines
10 KiB
Plaintext
134 lines
10 KiB
Plaintext
6. Expressions in AVAP
|
|
This chapter explains the meaning of expression elements in AVAP.
|
|
|
|
6.1. Arithmetic Conversions
|
|
When describing an arithmetic operator in AVAP and using the phrase "numeric arguments are converted to a common type," it means that the operator's implementation for built-in types works as follows:
|
|
|
|
If either of the arguments is a complex number, the other is converted to complex.
|
|
Otherwise, if either of the arguments is a floating-point number, the other is converted to floating-point.
|
|
Otherwise, both must be integers, and no conversion is needed.
|
|
Additional rules may apply for certain operators.
|
|
|
|
6.2. Atoms
|
|
Atoms are the most basic elements of expressions in AVAP. The simplest atoms are identifiers or literals. Forms enclosed in parentheses, brackets, or braces are also syntactically categorized as atoms. The syntax for atoms is:
|
|
|
|
atom ::= identifier | literal | enclosure
|
|
enclosure ::= parenth_form | list_display | dict_display | set_display | generator_expression
|
|
6.2.1. Identifiers (Names)
|
|
An identifier that appears as an atom is a name. When the name is bound to an object, evaluating the atom yields that object. When a name is not bound, an attempt to evaluate it raises a NameError exception.
|
|
|
|
Private Name Mangling
|
|
When an identifier that occurs literally in a class definition begins with two or more underscores and does not end with two or more underscores, it is considered a private name of that class. Private names are transformed into a longer form before code is generated for them. The transformation inserts the class name, with the initial underscores removed and a single underscore inserted, in front of the name.
|
|
|
|
6.2.2. Literals
|
|
AVAP supports string and bytes literals, as well as various numeric literals:
|
|
|
|
literal ::= stringliteral | bytesliteral | integer | floatnumber | imagnumber
|
|
Evaluating a literal produces an object of the given type (string, bytes, integer, floating-point number, complex number) with the given value. All literals correspond to immutable data types.
|
|
|
|
6.2.3. Parenthesized Forms
|
|
A parenthesized form is an optional list of expressions enclosed in parentheses:
|
|
|
|
parenth_form ::= "(" [starred_expression] ")"
|
|
A parenthesized expression produces whatever the expression list produces: if the list contains at least one comma, it produces a tuple; otherwise, it produces the single expression that makes up the list of expressions.
|
|
|
|
6.2.4. Comprehensions for Lists, Sets and Dictionaries
|
|
To construct a list, set, or dictionary, AVAP provides special syntax called "comprehension," each in two flavors:
|
|
|
|
The contents of the container are listed explicitly.
|
|
They are computed using a set of loop and filtering instructions, called a "comprehension."
|
|
Common syntax elements for comprehensions are:
|
|
|
|
comprehension ::= assignment_expression comp_for
|
|
comp_for ::= "for" target_list "in" or_test [comp_iter]
|
|
comp_iter ::= comp_for | comp_if
|
|
comp_if ::= "if" or_test [comp_iter]
|
|
A comprehension consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new container are those produced by considering each for or if clause as a block, nested from left to right, and evaluating the expression to produce an element each time the innermost block is reached.
|
|
|
|
6.2.5. List Displays
|
|
In AVAP, lists are generated and handled differently. To construct a list, the command variableToList(variable, list) is used, and an item from the list is retrieved with itemFromList(list, index, variable_to_store_item). To get the number of elements in the list, getListLen(list, var_to_store_list_length) is used.
|
|
|
|
The syntax for list displays is:
|
|
|
|
list_display ::= "[" [starred_list | comprehension] "]"
|
|
A list display produces a new list object, whose content is specified by a list of expressions or a comprehension. When a list of expressions is provided, its elements are evaluated from left to right and placed in the list object in that order.
|
|
|
|
6.2.6. Set Displays
|
|
A set display is denoted by curly braces and is distinguished from dictionary displays by the absence of colon characters separating keys and values:
|
|
|
|
set_display ::= "{" (starred_list | comprehension) "}"
|
|
A set display produces a new mutable set object, whose content is specified by a sequence of expressions or a comprehension.
|
|
|
|
6.2.7. Dictionary Displays
|
|
In AVAP, objects are created and managed using specific commands. An object is created with AddvariableToJSON(key, value, object_variable), and a key from the object is retrieved with variableFromJSON(object_variable, key, var_to_store_key_value).
|
|
|
|
The syntax for dictionary displays is:
|
|
|
|
dict_display ::= "{" [dict_item_list | dict_comprehension] "}"
|
|
dict_item_list ::= dict_item ("," dict_item)* [","]
|
|
dict_item ::= expression ":" expression | "**" or_expr
|
|
dict_comprehension ::= expression ":" expression comp_for
|
|
A dictionary display produces a new dictionary object. If a comma-separated sequence of dictionary items is provided, they are evaluated from left to right to define the dictionary entries.
|
|
|
|
Slices
|
|
A slice selects a range of elements in a sequence object (e.g., a string, tuple, or list). Slices can be used as expressions or as targets in assignments or statements. The syntax for a slice is as follows:
|
|
|
|
slicing ::= primary "[" slice_list "]"
|
|
slice_list ::= slice_item ("," slice_item)* [","]
|
|
slice_item ::= expression | proper_slice
|
|
proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
|
|
lower_bound ::= expression
|
|
upper_bound ::= expression
|
|
stride ::= expression
|
|
There is ambiguity in the formal syntax here: anything that looks like a list expression also looks like a list slice, so any subscription might be interpreted as a slice. Instead of complicating the syntax further, this is disambiguated by defining that in this case, the interpretation as a subscription takes precedence over the interpretation as a slice (this is the case if the list slice does not contain a proper slice).
|
|
|
|
The semantics for a slice are as follows. The primary is indexed (using the same __getitem__() method as in a normal subscription) with a key constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple that contains the conversion of the slice elements; otherwise, the conversion of the single slice element is the key. The conversion of a slice element that is an expression is that expression. The conversion of a proper slice is a slice object whose start, stop, and step attributes are the values of the expressions given as the lower bound, upper bound, and step, respectively, substituting None for missing expressions.
|
|
|
|
Calls
|
|
A call invokes a callable object (e.g., a function) with a possibly empty series of arguments:
|
|
|
|
call ::= primary "(" [argument_list [","] | comprehension] ")"
|
|
argument_list ::= positional_arguments ["," starred_and_keywords]
|
|
["," keywords_arguments]
|
|
| starred_and_keywords ["," keywords_arguments]
|
|
| keywords_arguments
|
|
positional_arguments ::= positional_item ("," positional_item)*
|
|
positional_item ::= assignment_expression | "*" expression
|
|
starred_and_keywords ::= ("*" expression | keyword_item)
|
|
("," "*" expression | "," keyword_item)*
|
|
keywords_arguments ::= (keyword_item | "**" expression)
|
|
("," keyword_item | "," "**" expression)*
|
|
keyword_item ::= identifier "=" expression
|
|
An optional trailing comma may be present after positional and keyword arguments but does not affect the semantics.
|
|
|
|
The primary must evaluate to a callable object (user-defined functions, built-in functions, built-in object methods, class objects, class instance methods, and any object with a __call__() method are callable). All argument expressions are evaluated before attempting the call. Please refer to the Function Definitions section for the syntax of formal parameter lists.
|
|
|
|
If keyword arguments are present, they are first converted into positional arguments as follows. First, a list of unfilled slots is created for the formal parameters. If there are N positional arguments, they are placed in the first N slots. Then, for each keyword argument, the identifier is used to determine the corresponding slot. If the slot is already filled, a TypeError exception is raised. Otherwise, the argument is placed in the slot, filling it (even if the expression is None, it fills the slot). When all arguments have been processed, any slots that are still empty are filled with the default value from the function definition. If there are unfilled slots for which no default value is specified, a TypeError exception is raised. Otherwise, the list of filled slots is used as the argument list for the call.
|
|
|
|
Implementation Details in AVAP
|
|
In AVAP, variables are stored as strings, and lists and objects are managed using specific commands:
|
|
|
|
Lists: To generate a list, use variableToList(variable, list). To retrieve an item from the list, use itemFromList(list, index, variable_to_store_item). To get the number of items in the list, use getListLen(list, var_to_store_list_length).
|
|
Objects (dictionaries): An object is created with AddvariableToJSON(key, value, object_variable). To retrieve a key from the object, use variableFromJSON(object_variable, key, var_to_store_key_value).
|
|
Usage Example
|
|
Creation and management of lists:
|
|
|
|
// Creating a list
|
|
variableToList("item1", "myList")
|
|
variableToList("item2", "myList")
|
|
variableToList("item3", "myList")
|
|
|
|
// Retrieving an item from the list
|
|
itemFromList("myList", 1, "myVariable")
|
|
|
|
// Getting the length of the list
|
|
getListLen("myList", "listLength")
|
|
Creation and management of objects (dictionaries):
|
|
|
|
// Creating an object
|
|
AddvariableToJSON("key1", "value1", "myObject")
|
|
AddvariableToJSON("key2", "value2", "myObject")
|
|
|
|
// Retrieving a value by key from the object
|
|
variableFromJSON("myObject", "key1", "myVariable")
|
|
In this way, lists and objects in AVAP can be manipulated using the specific functions provided for working with variables stored as strings. |