Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2 from hassanalinali/develop
Browse files Browse the repository at this point in the history
Version 0.4.0
  • Loading branch information
alinalihassan authored Jan 30, 2019
2 parents 6a378e3 + 7a9938a commit b1db48b
Show file tree
Hide file tree
Showing 51 changed files with 1,157 additions and 534 deletions.
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
version: 2
jobs:
build:
branches:
ignore: gh-pages
docker:
- image: circleci/python:3.7.2
steps:
Expand Down
2 changes: 1 addition & 1 deletion .hooks/pre-commit.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash

# Pytest
echo "Running pre-commit hooks"
Expand Down
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,31 @@

___
[![License: GPL v3](https://img.shields.io/badge/license-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Version](https://img.shields.io/badge/version-0.3.0-brightgreen.svg)](https://github.com/hassanalinali/Lesma/blob/master/LICENSE.md)
[![Version](https://img.shields.io/badge/version-0.4.0-brightgreen.svg)](https://github.com/hassanalinali/Lesma/blob/master/LICENSE.md)
[![CircleCI](https://circleci.com/gh/hassanalinali/Lesma/tree/master.svg?style=shield)](https://circleci.com/gh/hassanalinali/Lesma/tree/master)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/90fcc06be70d4dd98f54f1bb2713d70c)](https://www.codacy.com/app/hassanalinali/Lesma?utm_source=github.com&utm_medium=referral&utm_content=hassanalinali/Lesma&utm_campaign=Badge_Grade)

**Lesma** is a compiled, gradually typed, imperative and object oriented programming language with a focused on expressiveness, elegancy, and simplicity, while not sacrificing on performance. The compiler is written in Python using LLVM as a backend.
**Lesma** is a compiled, statically typed, imperative and object-oriented programming language with a focus on expressiveness, elegancy, and simplicity, while not sacrificing on performance. The compiler is written in Python (for now, C++ coming) using LLVM as a backend.

Currently an early Work in Progress, and **many thanks** to [Ayehavgunne](https://github.com/Ayehavgunne) and his [Mythril](https://github.com/Ayehavgunne/Mythril) project for helping me by showcasing advanced examples of llvmlite and providing a base code.

## Features
- **it's fast**, because it should be so, but it won't ever oblige you to make an extra effort for the sake of performance
- **it's compiled**, so you can finally distribute your projects without dependencies, and because binary size also matters, a Hello World example would be around 8kb
- **it's fast**, because it should be so, together with LLVM's state of the art optimizations, but it won't ever oblige you to make an extra effort from your side just for the sake of performance
- **it's compiled** both AOT and JIT, so you can finally decide if you just want to run it or compile it and distribute your project without dependencies, and because binary size also matters, a Hello World example would be around 8kb
- **it's statically typed** so you don't need to guess the type of the variable if your coworker didn't spend the time to use meaningful names and you can make use of compile-time checks, autocomplete and more
- **it's simple and expressive** because the code should be easily readable and it shouldn't make you guess what it does

## Influences
- Python
- Swift
- Typescript
- Lua
- Swift

## Installing
You can pick up the latest release in the [Release tab](https://github.com/hassanalinali/Lesma/releases) and start using it. Lesma is currently being tested and provides binaries only on Unix. Compatibility between operating systems and architectures is not hard to achieve, but simply not a priority.
You can pick up the latest release in [**Releases**](https://github.com/hassanalinali/Lesma/releases) and start using it. Lesma is currently being tested and provides binaries only for Unix. Compatibility between operating systems and architectures is not hard to achieve, but simply not a priority at the moment.

Windows is also supported but you need to do additional work if you want to compile Lesma code (need to install clang, but this is not properly tested at the moment) and there are issues with Unicode characters, but all the tests pass and everything else seems to work.

In the case that your platform is not oficially supported, you need to build it on your own.

## Documentation
Expand All @@ -35,7 +38,7 @@ In the case that your platform is not oficially supported, you need to build it

## Build

In order to build Lesma, you need to have [Python 3.7](https://www.python.org/) installed. It's currently tested only on Linux. It makes use of clang to compile the resulting object file currently, so you need it installed, but only running a file doesn't require clang.
In order to build Lesma, you need to have at least [Python 3.5](https://www.python.org/) installed. It's currently tested only on Linux. It makes use of clang to compile the resulting object file currently, so you need it installed, but only running a file doesn't require clang.

Clone the repo:
```bash
Expand All @@ -50,8 +53,8 @@ pip install -r requirements.txt

Done! Now you can run the compiler or the interpreter, make a test file and hack your way around. Remember there are examples in the documentation.
```bash
python les.py run test.les
python les.py compile test.les
python src/les.py run test.les
python src/les.py compile test.les
```

Or install pytest and run the unit tests yourself
Expand All @@ -61,5 +64,5 @@ pytest

For advanced usage or help, consult the CLI help menu
```bash
python les.py -h
python src/les.py -h
```
3 changes: 2 additions & 1 deletion build_dist.sh
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
python -m nuitka src/les.py --include-package=lesma --standalone --nofollow-imports --remove-output --python-flag=no_site --plugin-disable=pylint-warnings
#!/usr/bin/env bash
pyinstaller src/les.py -D -n lesma
25 changes: 7 additions & 18 deletions docs/TODO.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
# TODO

## Fixes
- [ ] Fix Type declaration not expecting square brackets (for lists)
- [ ] Fix input function
- [ ] Fix not being able to return user-defined structs and classes
- [ ] Fix not being able to overload operators on user-defined structs and classes
- [ ] Unicode doesn't print properly on Windows platforms
- [ ] Fix string and list type declaration not working
- [ ] Fix base unary operators being applied before user defined ones
- [ ] Fix unicode on windows

## Improvements
- [ ] Allow any type for lists/tuples (currently only int)
- [ ] Allow more operators on different types such as strings
- [ ] Improve warning messages
- [ ] Add indentation related errors
- [x] Add docs for as and is
- [ ] Add docs for mixed arithmetic
- [ ] Remove clang as a dependency
- [ ] Move error messages from source files to typechecker
- [ ] Fix array types not working and empty lists
- [ ] Catch struct/class used parameters that are not initialized
- [ ] Add support for functions with same name but different parameters
- [ ] Fix local - global variable behaviour, currently there's an implicit main func
- [ ] Allow strings to be used in equalities
- [ ] Use dataclasses and static typing as much as possible in source code
- [ ] String/Lists are currently unsupported on: input function, operators, etc.
- [ ] Find a way to use pointers and null for FFI but restrict or disallow it in normal Lesma

## Features
- [ ] Implement Null (maybe someday)
- [x] Implement Tuples
- [ ] Implement Class inheritance
- [ ] Implement Dictionary
- [ ] Implement 'in' as a boolean result
- [x] Implement anonymous functions
- [ ] Implement Closure
- [ ] Implement string interpolation
- [ ] Implement Enums
- [x] Implement defer keyword
- [x] Implement fallthrough and change switch's behaviour
- [ ] Implement lambda functions
33 changes: 22 additions & 11 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,24 @@ print('夜のコンサートは最高でした。')

a_number: int # Initialize an Integer

# Binary, Hex and Octal numbers supported
bin_num = 0b101010
octo_num = 0o1272
hex_num = 0x1272

π: float = 3.14 # Support for utf-8 variable names
number = 23 # Type Inference, int in this case
number = number + 5 // 2 ^ 3 # Number operations
number+=5 # Operating Assignment

still_inf = inf - 999999 # Still infinity

question = 'what\'s going on' # Escaping

things = [1, 2, 3] # List, homogeneous
other_things = (1, 'Hello') # Tuple, non-homogeneous
things = [1, 2, 3] # List, mutable
other_things = (1.5, 9.5) # Tuple, immutable
stuff = {'first_name': 'Samus', 'last_name': 'Aran'} # Dictionary
other_stuff: int[] = [] # Empty Array of Ints
other_stuff: list[int] = [] # Empty Array of ints

print(things[1 + 1])

Expand Down Expand Up @@ -113,7 +120,7 @@ if my_var is int64
else if my_var as int64 is int64
print("That works")

# Type Aliasing
# Type Declaration
type fInt = func[int] -> int

def do_stuff(x: int, callback: fInt) -> int
Expand Down Expand Up @@ -178,39 +185,43 @@ def defer_demo()
defer_demo() # prints Hello World!

# Enums
enum Colors
enum Color
GREEN
RED
BLUE
YELLOW

x: Colors = Color.GREEN
print(x == Color.GREEN)

# Structs
struct Circle
radius: int
x: int
y: int
y: int = 4

cir: Circle = Circle(radius=5, x=2, y=4)
cir: Circle = Circle(radius=5, x=2)

print(cir.radius)

# Classes
class Vehicle
# Constructor
new(year: int, color: str)
def new(year: int, color: str)
this.year = year
this._color = color

# Inheritance
class Car(Vehicle)
new(year: int, color='green', hatchback=false)
def new(year: int, color='green', hatchback=false)
this.hatchback = hatchback
super.Vehicle(year, color)

print_year() -> void
print('This car was made in {this.year}')
def print_year() -> void
print('This car was made in {self.year}')

ford = Car(1992)

print(ford.hatchback)
ford.print_year()
```
27 changes: 27 additions & 0 deletions docs/features/classes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
**Classes** are objects that bundle fields and methods to provide additional functionality that you can further use as a type for any variable, which can then be further expanded using operator overloading and other type-specific behaviour. Classes members can be accessed using a dot `.`.

Classes **require a constructor to be specified**.

## Example
```py
class Vehicle
# Constructor
def new(year: int, color: str)
this.year = year
this._color = color
# Privatising the color field, won't be accessible from outside

# Inheritance
class Car(Vehicle)
def new(year: int, color='green', hatchback=false)
this.hatchback = hatchback
super.Vehicle(year, color)

def print_year() -> void
print('This car was made in {self.year}')

ford = Car(1992)

print(ford.hatchback)
ford.print_year()
```
12 changes: 12 additions & 0 deletions docs/features/enums.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
**Enums** (enumerations) are a set of symbolic names bound to unique, constant values. Enum members can be accessed using the dot `.`.

## Example
```py
enum Color
Red
White

white: Color = Color.White # Enum members are accessed using a dot
red: Color = Color.Red
print(white != red)
```
18 changes: 12 additions & 6 deletions docs/features/keywords.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ For reference, here are all the keywords categorized by type.

| | | | |
|---|---|---|---|
| struct | class | true | false |
| if | else | for | while |
| switch | case | default | def |
| const | break | continue | pass |
| void | alias | extern | operator |
| fallthrough | defer
| struct | class | if | else |
| for | while | switch | case |
| default | def | const | break |
| continue | pass | type | extern |
| operator | fallthrough | defer | self |

## Constant keywords

| | | | |
|---|---|---|---|
| true | false | inf |

## Operator keywords

Expand All @@ -26,3 +31,4 @@ For reference, here are all the keywords categorized by type.
| int64 | int128 | uint | uint8 |
| uint16 | uint32 | uint64 | uint128 |
| double | float | str | bool |
| func | list | tuple | void |
15 changes: 15 additions & 0 deletions docs/features/structs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
**Structs** fill a similar role to Python's dataclasses, which you can describe as "mutable namedtuples with defaults", but they're stricter in the sense that **they're not disguised classes**, you can not define methods or other class-specific behaviour, but they can still be extended by overloading operators and they are still defined as a type in Lesma. Struct members can be accessed using the dot `.`.

All the fields of a struct are required arguments on initialization unless a default is provided.

## Example
```py
struct Circle
radius: int
x: int
y: int = 4

cir: Circle = Circle(radius=5, x=2)

print(cir.radius) # Members of a struct are accessed using a dot.
```
5 changes: 3 additions & 2 deletions docs/features/syntax.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- Whitespace is signifiant, indentation uses either tabs or exactly 4 spaces
- Flow control statements, structs, classes and functions require indentation
- Flow control statements, structs, enums, classes and functions require indentation
- Lesma's Checker will report any invalid syntax or unrecommended behaviour, such incompatible types for operations, or unused variables.
- `_` variable name is used as an ignored result, and is treated differently by the compiler (similar to golang)

Expand Down Expand Up @@ -29,7 +29,8 @@ struct thing
z: double

class Example
x: int
new(x: int)
this.x = x
self.x = x
```

Loading

0 comments on commit b1db48b

Please sign in to comment.