Python++ Language Reference Manual, Exams of Object Oriented Programming

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

2022/2023

Uploaded on 02/28/2023

newfound
newfound 🇨🇦

4.5

(13)

362 documents

1 / 14

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Python++ Language Reference Manual
Nathan Cuevas
njc2150
Robert Kim
rk3145
Nikhil Min Kovelamudi
nmk2146
David Steiner
ds3816
February 2021
Contents
1 Introduction 2
2 Lexical Conventions 2
2.1 Keywords ............................................... 2
2.2 Type names .............................................. 2
2.2.1 Primitive type tokens .................................... 2
2.2.2 Class names .......................................... 3
2.2.3 Array types .......................................... 3
2.3 Identifiers ............................................... 3
2.4 Op erators ............................................... 3
2.4.1 Object operators ....................................... 3
2.5 Literals ................................................ 3
2.5.1 Integer literals ........................................ 3
2.5.2 Long literals ......................................... 3
2.5.3 Floating point literals .................................... 3
2.5.4 Boolean literals ........................................ 4
2.5.5 Character literals ....................................... 4
2.5.6 String literals ......................................... 4
2.6 Comments ............................................... 4
2.7 Punctuation .............................................. 4
2.8 Syntactically significant whitespace ................................. 4
3 Syntax 5
3.1 Conventions used in this manual .................................. 5
3.2 Types ................................................. 5
3.2.1 Representation of primitives in memory .......................... 5
3.2.2 Classes ............................................ 5
3.2.3 Arrays ............................................. 6
3.3 Functions ............................................... 6
3.3.1 Function declarations .................................... 6
3.3.2 Function calls ......................................... 6
3.4 Expressions .............................................. 7
3.4.1 Literals ............................................ 7
3.4.2 Identifiers, functions, and classes .............................. 7
3.4.3 Array expressions ....................................... 7
3.4.4 Parentheses .......................................... 7
3.4.5 Mathematical operators ................................... 8
3.4.6 Assignments ......................................... 8
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe

Partial preview of the text

Download Python++ Language Reference Manual and more Exams Object Oriented Programming in PDF only on Docsity!

Python++ Language Reference Manual

- njc Nathan Cuevas - rk Robert Kim - nmk Nikhil Min Kovelamudi - ds David Steiner - February
  • 1 Introduction Contents
  • 2 Lexical Conventions
    • 2.1 Keywords
    • 2.2 Type names
      • 2.2.1 Primitive type tokens
      • 2.2.2 Class names
      • 2.2.3 Array types
    • 2.3 Identifiers
    • 2.4 Operators
      • 2.4.1 Object operators
    • 2.5 Literals
      • 2.5.1 Integer literals
      • 2.5.2 Long literals
      • 2.5.3 Floating point literals
      • 2.5.4 Boolean literals
      • 2.5.5 Character literals
      • 2.5.6 String literals
    • 2.6 Comments
    • 2.7 Punctuation
    • 2.8 Syntactically significant whitespace
  • 3 Syntax
    • 3.1 Conventions used in this manual
    • 3.2 Types
      • 3.2.1 Representation of primitives in memory
      • 3.2.2 Classes
      • 3.2.3 Arrays
    • 3.3 Functions
      • 3.3.1 Function declarations
      • 3.3.2 Function calls
    • 3.4 Expressions
      • 3.4.1 Literals
      • 3.4.2 Identifiers, functions, and classes
      • 3.4.3 Array expressions
      • 3.4.4 Parentheses
      • 3.4.5 Mathematical operators
      • 3.4.6 Assignments

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

1 Introduction

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.

2 Lexical Conventions

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.

2.1 Keywords

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

2.2 Type names

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++.

2.6 Comments

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.

2.7 Punctuation

Python++ uses the following characters for punctuation: ( ) [ ] :. ,

  • Left and right parentheses can be used to group expressions and are also used to define and call functions.
  • Left and right brackets are used for array literals and array access.
  • Colons are used when defining classes and functions.
  • Periods are used to invoke functions that are part of objects.
  • Commas are used to separate parameters to function calls as well as array parameters.
  • Underscores are used exclusively to indicate that a method in a class is an object operator.

2.8 Syntactically significant whitespace

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.

3 Syntax

3.1 Conventions used in this manual

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 Types

3.2.1 Representation of primitives in memory

  • int refers to a 32-bit integer and corresponds to i32 in LLVM.
  • long refers to a 64-bit integer and corresponds to i64 in LLVM.
  • float refers to a 32-bit floating point value and corresponds to float in LLVM.
  • char refers to an ASCII character and corresponds to the i8 type in LLVM.
  • string refers to an array whose elements are all char. string’s are immutable in Python++.
  • boolean refers to a value that is either “true” or “false” and corresponds to the i1 type in LLVM.

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 Expressions

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

  • refers and − (when appearing between two expressions) refer to addition and subtraction, respectively, and group from left to right. They have equal precedence among themselves and are lower precedence than ∗, /, and %. ∗, /, and % refer to multiplication, division, and modulo, respectively, and group from left to right. They have equal precedence among themselves and are higher precedence than + and −. OBJ-OPERATOR refers to a user defined infix operator, which appears as a method prefixed by an underscore on the class. See this section for more information and a code sample. Unary minus, as in −expr, refers to the negative sign and has a higher precedence than the other mathematical operators.

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

3.6 Statements

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

3.7 Parameters and variable declarations

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

3.8 Associativity and precedence table

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

4 Semantics

4.1 Declaration rules

Variables must be defined before they are used. Semantically,

int x = 5 println(x) # prints 5

is legal but

x = 5

Before we call my_function_1, everything is as expected.

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)

After we call my_function_1, the object was mutated but the primitive param was not.

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"

4.4 Mutability

Objects in Python++ are mutable by default. Strings and primitives are immutable.

5 Conversions

Some operators in Python++ can cause conversion of the value of the operands from one type to another.

5.1 Floats and Integers

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.

5.2 Characters and Strings

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.

5.3 Object operators

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'