Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
* PyHask PyHask is the project for compiler's design class, it aims to build a small object oriented programming language using Haskell with syntax inspired on Python. * User's manual ** Language's philosophy This language aims to be an imperative styled and statically typed language with support for the basic control flow structures, declaration for primitive types, declaration of N-dimensional arrays (PyHask does not impose a limit on the number of dimensions for an array), primitive based functions and basic objected oriented functionality. PyHask believes in scopes with arbitraty depth and to allow variables declared in a scope to be redeclared outside of it. PyHask borrows most of its syntax from Python, including type annotations for which it borrows Python's type hints. The project aims for the feel of an scripting language by not imposing the creation of a main block, and to freely allow variable declarations anywhere in the code. ** How to run PyHask After cloning the repository please build it using: #+BEGIN_SRC sh stack build #+END_SRC After that source programs must be first compiled and the generated output can be executed in the following way #+BEGIN_SRC sh stack exec PyHask-exe compile example.ph stack exec PyHask-exe execute example.phc #+END_SRC Please refer to [[https://docs.haskellstack.org/en/stable/README/][Stack]] for more information related to the Haskell tool stack and how to use it. ** Primitive types This language supports ~int~, ~float~, ~char~ and ~bool~ as primitive types. ** Variable declarations *** Primitive declaration Primivites are declared in PyHask by using the keyword ~let~, specifying all the variables for that type; after that it is required to specify the primitive type for the variables and optionally and initial value for the variables. if no initial value is provided a default one will be given. **** Default values - ~int~ : ~0~ - ~float~ : ~0.0~ - ~char~ : ~a~ - ~bool~ : ~True~ **** Valid declaration with default value ~let a : int := 10~ **** Valid declaration no default value ~let a : int~ **** Invalid declaration ~let a~ *** Array declaration An array is declared also by using the keyword ~let~, specifying variables, and by specifying the type and dimensions of the array, arrays in PyHask are N-dimensional, arrays declaration do not support optional initial value as assigning an entire array is currently not supported in PyHask, all the values for the array have as initial value the default ones specified in the previous section of the document. **** Valid array declaration with one dimension ~let a : int[5]~ **** Valid array declarations with more than one dimensions - ~let a : int[5][6]~ - ~let b : bool[3][9][10]~ *** Object declaration To create an object it is necessary to first declare a class for which to instantiate an object from, this topic is gonna be covered later in the manual, in the meantime an example is gonna be given with a hypotethical class called ~Home~ that receives a integer and a floating point value on its constructors Object declaration uses the ~create~ keyword instead of the ~let~ keyword. The correct structure for object creation is to use ~create~ followed by the class from which the object will be instantiated, and in parenthesis the parameters to be passed to the constructor. **** Valid object declaration ~create h : Home(10,5.0)~ ** Control flow structures *** Conditionals PyHask supports conditionals by means of having ~if~, ~elif~, and ~else~ blocks. These blocks work just like in Python, with ~if~ block optionally followed by a number of ~elif~ blocks and optionally an ~else~ block as a catch all. After the ~if~ and ~elif~ keywords a boolean expression must be stated to evaluate if the block is going to be executed. **** Valid conditonal - only if block #+BEGIN_SRC python if 5 < 2: print(1) #+END_SRC **** Valid conditional - with multiple elif blocks #+BEGIN_SRC python if 5 == 3: print(1) elif 2 < 3: print(2) elif 5 == 5: print(3) #+END_SRC **** Valid conditional - with an else block #+BEGIN_SRC python if 5 == 3: print(1) else print(2) #+END_SRC *** While loop PyHask supports while loops the Python way, by using the keyword ~while~ followed by a boolean expression and a block of statements. **** Valid while loop #+BEGIN_SRC python while True: print(3) #+END_SRC *** For loop For loops are one of the elements where PyHask differs from Python. For loops share some similarity with C-styled loops by first having variable declarations, followed by a boolean expression and an statement. **** Valid for loop #+BEGIN_SRC python for i : int := 0 : True : i := i + 1: print(i) #+END_SRC ** Functions PyHask borrows its syntax for functions from Python, even the the type declarations for functions are based on Python's optional type hinting. Functions are declared by first using the keyword ~def~ followed by the name of the function and a list of parameters for the function to receive; finally the function must mark the return type for it with ~->~ and setting a primitive type or the ~void~ keyword. *** Function with return type #+BEGIN_SRC python def fact(i: int) -> int: if i == 0: return 1 return i * fact(i-1) #+END_SRC *** Function without a return type #+BEGIN_SRC python def no_return() -> void: print(10) #+END_SRC ** Classes Classes are perhaps the most complicated construct which PyHask has to offer. Again the syntax for it somewhat resembles Python's syntax. The ~class~ keyword must be used to indicate the start of a class declaration, optionally followed by a parent class enclosed in parenthesis. The class definition must be followed by an init block. Init blocks can contain member definitions and must always define a constructor named ~init~. After the initialization block methods of the class can follow declared as regular functions while inside the indentantion of the class. Methods will have access to ~self~ referring to an instance of the object of the class for which the method belongs. Methods may have a ~super~ variable referring to the parent of the class, this can be used to call a parent's method and it's specially useful in constructors to initialize the variables the parent constructor initializes. *** Simple class example #+BEGIN_SRC python class Home: init: __init__(i:int): pass def f(d: float) -> int: return 1 #+END_SRC *** Class declaration #+BEGIN_SRC python class MemberedClass: init: let member1 : int let member2 : float __init__(i: int, f: float): self.member1 := i self.member2 := f def calc() -> float: return self.member1 * self.member2 #+END_SRC *** Inheritance example #+BEGIN_SRC python class SonClass(MemberedClass): init: __init__(i: int, f: float): super.__init__(i,f) def calc() -> float: return super.calc() #+END_SRC ** More examples Please refer to the /ph/ files in the repository for more examples of PyHask