








Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Python++ uses the ASCII character set and is case- sensitive. 2.1 Keywords ... They consist of a lowercase letter followed by one or more lowercase letters,.
Typology: Exams
1 / 14
This page cannot be seen from the preview
Don't miss anything!









3.4.7 Boolean operators...................................... 9 3.5 High-level program structure.................................... 9 3.5.1 The program......................................... 9 3.6 Statements.............................................. 10 3.6.1 If statements......................................... 10 3.6.2 Loop statements....................................... 10 3.7 Parameters and variable declarations................................ 10 3.8 Associativity and precedence table................................. 11
4 Semantics 11 4.1 Declaration rules........................................... 11 4.2 Scoping rules............................................. 12 4.3 Function parameters are passed by value.............................. 12 4.4 Mutability............................................... 13
5 Conversions 13 5.1 Floats and Integers.......................................... 13 5.2 Characters and Strings........................................ 13 5.3 Object operators........................................... 13
Python++ is a general-purpose imperative programming language inspired by Python that aims to create a language as easy to use as Python, but with the added type safety of Java. The language is strongly and statically typed, has no type inferencing, and supports object-oriented programming without requiring that all functions be part of objects. Python++ uses syntactically significant whitespace as opposed to curly braces and semicolons. In addi- tion to adding static typing to a Python-style syntax, Python++ aims to add quality of life features such as automatic constructor generation for data classes, a new syntax for loops, and a better operator overloading syntax. Python++ does not offer any garbage collection nor does it allow for pointer arithmetic.
Python++ has the following kinds of tokens: keywords, type names, identifiers, operators, literals, comments, punctuation, and syntactically significant whitespace. Python++ uses the ASCII character set and is case- sensitive.
Python++ treats the following keywords as reserved and will always return a special token matching the name rather than treating it as any other type of token. The reserved keywords are: not or and loop while if elif else def class return returns self required optional static NULL
Python++ is a statically typed language. A type is either a primitive type, which means it matches one of the below types, a class name, or it is an array type.
2.2.1 Primitive type tokens
The primitive datatype tokens are: int, long, float, boolean, char, string, void
2.5.4 Boolean literals Boolean literals are either the string “true” or the string ”false”. These are case-sensitive, so “True” or “FALSE” will not match the boolean literal token. Boolean literals have a higher precedence than identifiers, so “true” and “false” always get tokenized as a boolean literal rather than an identifier. Thus “true” and “false” are not valid identifiers.
2.5.5 Character literals
Character literals consist of a single quote, followed by a single character, followed by a single quote. The exact regex to match character literals is ‘.’
2.5.6 String literals
String literals consist of a double quote, followed by any character other than a double quote or newline, followed by a double quote. String literals cannot contain newlines or double quote characters in Python++.
Python++ supports both single-line and multi-line comments. Single-line comments start with a # character and indicate that everything after the # on that line is a comment and can be discarded. Alternatively, a comment can be started using /# and closed using #/. Comments starting with /# are allowed to span multiple lines.
Python++ uses the following characters for punctuation: ( ) [ ] :. ,
Python++ uses syntactically significant whitespace rather than curly braces or semi-colons. Python++ differs from Python in that spaces are not syntactically significant and only tab characters can be used. The NEWLINE character is used to indicate the end of each statement. One INDENT token is used every time a line has increased indentation level compared to the previous indentation level. A DEDENT token is released for each corresponding decrease in the indentation level. Consider the following code block for a concrete example:
1 int x = 5 2 3 def foo(string y) returns void: 4 char c = 'c' 5 if x > 5: 6 if c == 'c': 7 println("foo") 8 elif: x > 10: 9 println("x was greater than 10") 10 11 println(1)
An INDENT token would be emitted after the NEWLINE on line 3. Another would be emitted after the NEWLINE on lines 5, 6, and 8. No INDENT would be emitted after the NEWLINE on line 4, because line 5 is at the same level of indentations. Thus INDENT is not the same as how many tab characters were on a line. Two DEDENT tokens would be emitted after the NEWLINE on line 7, and one DEDENT would be emitted after the NEWLINE on line 10.
A context-free grammar is used to specify valid syntax for Python++ programs. In this manual, nonterminal symbols will appear as italicized-strings-in-lowercase (clicking the nonterminal will open the section of the document where productions of that nonterminal are defined). Terminals will appear as uppercase strings in a monospaced font. For enhanced legibility, hyphens will be used to separate words within a nonterminal or terminal. An example of a terminal could be TERMINAL. If there is more than one production for the same nonterminal symbol, the different alternatives will be listed on separate lines. An example of a production would be
foo → bar BAZ Which would mean the nonterminal foo consists of the nonterminal bar followed by the terminal BAZ.
3.2.1 Representation of primitives in memory
3.2.2 Classes
The primitive types above can be combined to yield more powerful types. Python++ allows users to define objects which are “manipulatable regions of storage” which consist of a struct that has fields made up of primitive types or other objects. Classes in Python++ do not support inheritance. Formally, we say a class definition consists of only the following rule:
classdecl → CLASS TYPE : NEWLINE INDENT STATIC : NEWLINE INDENT assigns NEWLINE DEDENT REQUIRED : NEWLINE INDENT vdecls NEWLINE DEDENT OPTIONAL : NEWLINE INDENT assigns NEWLINE DEDENT optional-fdecls NEWLINE
The fact that the entries appear on different lines here does not indicate that there is more than one production here. This was purely a cosmetic choice since the real production, which should all go on a single line, is too long to fit on this page. Objects can be instantiated using the following rule.
object-instantiation → TYPE(params) → TYPE()
3.4.1 Literals
A literal by itself can be considered an expression. NULL is also considered an expression. Thus all of the following productions are valid expressions:
expr → INT-LITERAL → LONG-LITERAL → FLOAT-LITERAL → CHAR-LITERAL → STRING-LITERAL → BOOLEAN-LITERAL → NULL
3.4.2 Identifiers, functions, and classes
Identifiers by themselves are considered valid expressions. This applies whether the identifier is used on its own or it refers to a field inside an object. Instantiations of objects are also valid expressions. Thus all of the following productions are valid expressions:
expr → IDENTIFIER → object-instantiation → object-variable-access → func-call
3.4.3 Array expressions
Array expressions can be either an array-literal or an array-access. Thus the following productions are valid expressions:
expr → array-literal → array-access
3.4.4 Parentheses
Expressions can be wrapped in parentheses. The type and value of an expression are the same as that of the original expression. Parentheses allow for grouping of expressions to override the default precedence for mathematical operators.
expr → (expr)
3.4.5 Mathematical operators
expr → expr + expr → expr - expr → expr * expr → expr / expr → expr % expr → expr OBJ-OPERATOR expr → - expr
3.4.6 Assignments
Assignments are also expressions. Assignment operators all have the same precedence, and their precedence is lower than all other operators. Assignment operators are right associative.
assign → TYPE IDENTIFIER = expr → IDENTIFIER = expr → object-variable-access = expr
Python++ also includes the update and assign operators + =, − =, ∗ =, and / =. These refer to setting the new value of the left-hand side equal to the old value of the left-hand side plus/minus/times/divided by the value of the right-hand side, respectively.
assign-update → IDENTIFIER += expr → IDENTIFIER -= expr → IDENTIFIER *= expr → IDENTIFIER /= expr → object-variable-access += expr → object-variable-access -= expr → object-variable-access *= expr → object-variable-access /= expr
Thus the following are valid expressions:
expr → assign → assign-update
Python++ makes a distinction between statements and expressions, even though both can have side effects and an expression by itself can be a statement. Each statement in Python++ is terminated by a NEWLINE. No semicolons are used in Python++. Python++ has four types of statements: expressions, return statements, if statements, and loops. For- mally, these are specified as:
stmt → expr NEWLINE → RETURN expr NEWLINE → if-stmt → loop
A group of statements can appear one after the other:
stmts → stmt NEWLINE → stmts stmt
3.6.1 If statements
Users can branch on conditionals using if statements. If statements can be used as solo if statements, if/else statements, or if/elif/else statements, with an arbitrary amount of elifs. Formally, if statements are defined as:
if-stmt → IF expr : NEWLINE INDENT stmts DEDENT → IF expr : NEWLINE INDENT stmts DEDENT ELSE : NEWLINE INDENT stmts DEDENT → IF expr : NEWLINE INDENT stmts DEDENT elif ELSE : NEWLINE INDENT stmts DEDENT → IF expr : NEWLINE INDENT stmts DEDENT elif
Where elif is defined as:
elif → ELIF expr : NEWLINE INDENT stmts DEDENT → elif ELIF expr : NEWLINE INDENT stmts DEDENT
3.6.2 Loop statements
Python++ only offers one kind of loop, a “loop while” construct that uses a novel syntax.
loop → LOOP expr WHILE expr : NEWLINE INDENT stmts DEDENT → LOOP WHILE expr : NEWLINE INDENT stmts DEDENT
As a statically typed language, Python++ requires function declarations to specify the types of parameters. This is done using the following grammar, where each typed parameter is separated by a comma:
type-params → TYPE IDENTIFIER → type-params , TYPE IDENTIFIER
Parameters written without their type are also available when making function calls and initializing array literals. Their syntax is:
params → expr → params , expr
Variables can also be declared without being part of an assignment. This can be used to define the fields within a class.
vdecl → TYPE IDENTIFIER
vdecls → vdecl → vdecls NEWLINE vdecl
The table is increasing order of precedence.
Associativity Operator(s)
right = += -= *= /= left OR left AND
left NOT left == != > < >= <= left + -
left * / % left OBJ-OPERATOR non-associative UNARY-MINUS
Variables must be defined before they are used. Semantically,
int x = 5 println(x) # prints 5
is legal but
x = 5
println(my_object.x) # prints 1 println(my_object.y) # prints 2 println(my_object.z) # prints 3 println(primitive_param) # prints 1
def my_function_1(MyObject object_param, int primitive_param): object_param.x = 500 object_param.y = 500 object_param.z = 500 primitive_param = 500
my_function_1(my_object, primitive_param)
println(my_object.x) # prints 500 println(my_object.y) # prints 500 println(my_object.z) # prints 500 println(primitive_param) # prints 1
def my_function_2(MyObject object_param): object_param = MyObject(20, 20, 20)
my_old_object = my_object my_function_2(my_object) println(my_old_object == my_object) # prints "true"
Objects in Python++ are mutable by default. Strings and primitives are immutable.
Some operators in Python++ can cause conversion of the value of the operands from one type to another.
When floats and ints are combined in Python++ arithmetic, the integer is treated as a floating point number and the result is always a float. This includes arithmetic expressions that include longs. If a long and an int are combined in any arithmetic operator, the result is always of type long.
When a character is added to a string using the + operator for concatenation, i.e. ‘c’ + “haracter”, the resulting data type is a string, in this case “character”. This string type conversion also occurs when 2 characters are concatenated, e.g. ‘o’+‘k’ == “ok”. Use of the + operator between chars and/or strings always converts to a string.
Python++ objects may also contain user-defined infix operator definitions in the form of special function definitions that define how objects work with operators. The type used in the parameter within the function declaration defines what types can work on the right hand side of the operator. The return type of the expression is defined by the return type of the function.
The following sample code demonstrates how the custom infix operators work in practice:
class MyClass: required: int x int y
def _+(MyClass b) returns MyClass: # addition function return MyClass(self.x+b.x, self.y+b.y)
def _-(MyClass b) returns MyClass: # subtraction function return MyClass(self.x-b.x, self.y-b.y)
def _%%%(MyClass b) returns int: return self.x * b.x
MyClass instA = MyClass(1, 3) MyClass instB = MyClass(2, 2) MyClass sum = instA + instB # compiler will convert this to instA.+(instB) MyClass difference = instA - instB # compiler will convert this to instA.-(instB) int num = instA %%% instB # compiler will convert this to instA._%%%(instB) println(sum.x) # prints '3' println(sum.y) # prints '5' println(difference.x) # prints '-1' println(difference.y) # prints '1' println(num) # prints '2'