Bethon is a minimal subset of Python designed for teaching programming using Systematic Program Design
- Rust Programming Language compiler.
- To install it, follow the official guide here
Tip: you can check if you already have Rust installed by typing
cargo --versionin a terminal. (If a message like "cargo x.xx.x" returns by the command, it is already installed)
- Clone or download this repository.
- In a terminal, enter the repository's folder:
cd bethon- Finally, to install the interpreter, use
cargo install --path .Like Python, Bethon's primitive types are:
-
intfor integer values:10, 20, 0, -40
-
floatfor floating point values (real numbers):0.4, -1.0, 555.5
-
strfor string literals (words or phrases surrounded by"):"Hello, world!" -
boolfor boolean types:True, False
There is also the None type, which represents an empty value.
| Operator | Usage | Description |
|---|---|---|
| = | var = expr | Assigns expr to var |
| Operator | Usage | Description |
|---|---|---|
| == | expr == expr | Equality comparison |
| != | expr != expr | Nonequality comparison |
| > | expr > expr | Greater than comparison |
| >= | expr >= expr | Greater equal comparison |
| < | expr < expr | Less than comparison |
| <= | expr <= expr | Less equal comparison |
| Operator | Usage | Description |
|---|---|---|
| + | expr + expr | Arithmetic addition |
| - | expr - expr | Arithmetic subtraction |
| * | expr * expr | Arithmetic multiplication |
| / | expr / expr | Arithmetic division |
| % | expr % expr | Arithmetic remainder operator |
| Operator | Usage | Description |
|---|---|---|
| + | +expr | Returns expr unchanged |
| - | -expr | Arithmetic negation |
| Operator | Usage | Description |
|---|---|---|
| and | epxr and epxr | Logical and |
| or | epxr or expr | Logical or |
| not | not epxr | Logical not |
An expression ('expr') is any value produced or written into (literal) the program
The operator precedence matches the Python's rule of precedence:
| Operator |
|---|
| or |
| and |
| not |
| and |
| == != > >= < <= |
| + - |
| * / % |
| unary +, unary - |
(expr) |
Operators in the same box have the same precedence and are evaluated left-to-right in the code
In Bethon, classes are based on Python's dataclass construction.
To maintain the status of subset, the dataclass module have to be imported into the program:
from dataclasses import dataclassor
import dataclassesTo define a new class, mark it as a dataclass using @dataclass and use the keyword class folowed by the name of the new class.
Next, define the attributes and its types.
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: floator
import dataclasses
@dataclasses.dataclass
class Point:
x: float
y: floatTo create a new instance of your class, call it (C-style) with the attributes in order of definition:
Point(10.0, 20.0) # 10.0 will be set to 'x' and 20.0 to 'y'Enumerations are based on Python's Enum library, therefore, it needs to be imported into the program with
from enum import IntEnumor
import enumTo create a new enum, you need to create a simple class that inherits IntEnum's behavior:
class CardinalDirection(IntEnum):
North = 1
South = 2
East = 3
West = 4The assignment of each variant to an integer is mandatory, but it's not necessary for each integer to be unique.
The declaration of Unions match the new sintax available from Python 3.10 onwards. You can put any valid type into an union and use them anywhere a type can be used:
any_typed_var: int | float | str | bool = 10Aliasing works just like an assignment, but with a type:
AnyPrimitiveType = int | float | str | bool
any_typed_var: AnyPrimitiveType = 10Constants can be defined just by writing a name anywhere in the code followed by an equal (=) and anything that is or produces a value.
x = 10 # int literal
some_string = "some string" # string literal
is_valid = True # boolean literal
point = Point(10.0, 20.0) # User defined type constructor
fun_ret = create_point(z, y) # function call
nothing = None # an empty valueYou can ensure the type of a constant by declaring a type after its name:
int_var: int = 10
str_var: str = "hello, world!"
some_var: str = 10 # this will raise an errorFunction definitions start with the keyword def followed by:
- the functions name;
- its parameters around parentheses;
- the type of value it will produce (if any) after a
->and; - the function's body after a colon, like in the examples:
def create_point(x: float, y: float) -> Point:
""" Creates a new Point based on the parameters (works like the default Point constructor) """
return Point(x, y)
# no return type declared because the function does not produce any value
def print_point(p: Point):
""" Prints a Point to the screen """
print("Point:")
print(" x:", p.x)
print(" y:", p.y)You can call any function like:
p1 = create_point(10.0, 20.0)
print_point(p1)You can write any valid code inside a function body.
The keyword
returnwill end the execution of the function and return the value produced by the expression in front of it to the function's caller
Control flow can be done with if/else
The if condition has to evaluate to a boolean value
origin = Point(0.0, 0.0)
p1 = Point(10.0, 20.0)
if p1 == origin:
print("p1 is origin")
else:
print("p1 is not the origin")You can write any valid code inside a if/else body.
It is useful to be sure about the correctness of values. assert can do this.
assert 10 == 10
assert 10.5 > 10.4
assert True or False == True
assert True and False == False
origin = Point(0.0, 0.0)
p1 = Point(10.0, 20.0)
assert p1 != originBe careful using assert, if the expression does not evaluate to True, the program will exit with an error. Try this:
assert 10 + 10 == 10