Giter VIP home page Giter VIP logo

envious's Introduction

Envious Programming Language

A new programming language that focuses on simplicity without compromising on speed. This language is meant to be born from the desires of the community. In a sense, it is a language that will hopefully address the issues that developers have with other programming languages.

Perhaps more importantly, this project is a way for me to learn more about compilers and VMs.

Details about EnvyLang

Envy is heavily influenced by Math. A lot of the symbols used comes directly from mathametical theory. In that right, Envy is easy to understand. Envy targets the LLVM or Low-Level Virtual Machine.

Also, note that this language is under active development and that there will be many changes in the future.

Current status of the language

Currently, there are 4 different parts of the project that have been partially completed.

  • Lexer
  • Parser
  • Type checker
  • Code generator

Implemented Features

  • Variable with mutabality
  • If and else expressions
  • While loops
  • Functions
  • External function definitions
  • Static type checking

Types

Seeing as to how Envious is a statically typed language, it is important to discuss the various types in the language.

Currently, there are 5 types:

  • Int
  • Float
  • Bool
  • Char
  • Void

In the future, more types will be included, however, the lack of a garbage collector or memory management makes it difficult to implement these types at the moment.

The different types of expressions

Envious is an expression based language. Therefore, most of the statements written are expressions. Here is a detailed description of each expression.

Define expression

The define expression creates a new function that is very similar to math.

The syntax of the define expression is as follows:

define add(x: Int, y: Int) :: Int = x + y 

Some notable parts of the function is the inclusion of the define keyword, the function name, a comma-separated list of parameters that have the name of the parameter followed by the type, the return type of the function, and the body which consistes of a single expression.

In other programming languages, this is better known as a function.

Let expression

The let expression allows the declaration of a new variable or the mutation of a previously defined variable. For example, the variable x can be defined using the following expression:

let x = 123

This will define a new variable x that is defined within its scope (typically the surrounding function)

A let expression does not return any value, unlike Java.

If expression

The if expressions allows certain expressions be run based on a condition. For example, the message printed out to the console can be changed based on whether it is sunny or not.

let isSunny = true
if isSunny then
    print('Y')
else
    print('N')

There are three different parts to an if expression: the condition, the then expession, and the optional else expression. The condition must be a boolean expression and follows the if keyword. The then expression describes the expression to execute if the condition is true and must be preceded by the then keyword. Lastly, in the event that an expression must be run if the condition is false, the else expression can be used.

The if expression returns the value of the branch that was chosen. This implies that the two branches must result in the same type.

While expression

The while expression allows for a certain expression to be repeated based on a given condition. Although the word expression is used, a while expression does not return any value.

Currently, the while expression is the only looping mechanism implemented.

The syntax for the while expression is as follows:

let condition = true
while condition
    expression

Block expression

The block expression allows multiple expressions to be run. This is most useful when combined with other expressions. The block expression returns the value of the last expression in the block.

A block expression can be constructed by surrounding a group of expressions with a pair of curly braces.

Application expression

Lastly, an application expression represents an application of a function with its parameters. This expression returns the value of the function and thus, has the same type as the return value of the function.

A function can be applied as follows:

function(parameters)

In this case, function refers to the name of the function and parameters refers to the comma separated paramers that are passed to the function.

TUI and CLI

In addition to the compiler, there are two seperate modules, namely the TUI (terminal user interface) and the CLI (command line interface)

The TUI allows the user to quickly prototype code in a REPL like environment and see colored error messages and the generated code. The behavior of the TUI should change soon to show the output of the code as opposed to the generated code.

The CLI provides an interface for the user to interact with the compiler. It provides options to compile, build, and run any given files.

Quick Start

The easiest way to play around with Envy is via the TUI. In order to get it running locally, you'll need to install the dependencies. The following directions are currently OS X only:

  1. Install homebrew
  2. Install Rust: $ brew install rust
  3. Install cmake: $ brew install cmake
  4. Install LLVM v10.0.0 from the LLVM Download Page and unzip it into your home directory.
  5. Install the llvm-sys package. At the time of writing, the current required version is 10.0.0:
cd ~ && mkdir -p llvm-10.0.0.src/build
cd llvm-10.0.0.src/build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/llvm-10.0.0
cmake --build . --target install # Note that this may take in the neighborhood of 90 minutes.
  1. Build envious: $ cd path_to_envious_root && LLVM_SYS_100_PREFIX=$HOME/llvm-10.0.0 cargo build --release
  2. Now enter the TUI: $ cd path_to_envious_root/target/release && ./envious -t
  3. If everything worked, you should see something like the following:

Screen Shot 2021-06-08 at 4 11 14 PM

The following directions are for Linux and WSL users:

  1. Install Rust: $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  2. Install LLVM 10: $ sudo apt-get install llvm-10*
  3. Build envious: $ cd path_to_envious_root && LLVM_SYS_100_PREFIX=$HOME/llvm-10.0.0 cargo build --release
  4. Now enter the TUI: $ cd path_to_envious_root/target/release && ./envious -t

The following directions are for Windows users:

  1. Install Chocolatey:
    • First open PowerShell in administrative mode
    • Run $ Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
  2. Install LLVM 10: $ choco install llvm --version=10.0.0
  3. Add LLVM 10 as LLVM_SYS_100_PREFIX to Path
  4. Install Rust: Go to https://www.rust-lang.org/tools/install and follow the instructions to install Rust for Windows
  5. Build envious: $ cd path_to_envious_root && cargo build --release
  6. Now enter the TUI: $ cd path_to_envious_root/target/release && ./envious -t

envious's People

Contributors

dependabot[bot] avatar hacker-007 avatar ncox-smartsheet avatar thenickcox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

envious's Issues

Return types are not inferred for functions

The current implementation for the type inference algorithm is not able to infer the return types, especially if they are not used in any other context.

This will require a change to the actual algorithm used, which is currently the Wand Algorithm.

Rethink CLI architecture

The current architecture of the CLI forces the programming language to route through the runner while having a lot of the actions regarding arguments also occurring there. This may need to be changed to have the run function in the main.rs file take in a reference to the arguments and have the code run through there instead.

REPL not interacting as expected

The current system executes all of the previous statements entered as well. This system is inherently flawed and needs to be changed so that only the current statement entered is executed.

Add a ParenthesizedExpression

Currently, the type checking system points to an arbitrary point for errors. To resolve this, a ParenthesizedExpression is needed. The changes would not be that hard to make.

Add code generation for function calls

The function call expression needs to have the code generated for it. This will probably involve adding a function in the compiler.rs file to handle function calls. Also, function calls to the standard library will also need to be implemented. For example, a function call to print should result in "print EXPRESSION". An easy way of detecting standard library functions will need to be implemented as well.

Better semantic analysis

If a method is declared and as the expression, an if expression is used, then the method may produce unexpected output if no else section is provided. Currently, the compiler can not detect this issue. This may require some changing of how expressions are detected and if the else section is necessary for certain things.

Implement return statements

Return statements are able to be parsed and type checked, however, code generation still needs some work. The problem lies within the fact that return statements can not be placed in the middle of entry blocks. Therefore, even if the code is syntactically valid, during the code generation, the return statement is placed incorrectly.

Quick start guide?

Okay! I'm not super familiar with the Rust ecosystem, but I finally got cargo build to succeed in the envious-tui directory. (I'm planning to submit a PR for how to get that to work on OSX if the dependencies aren't already installed. There was a lot of work to do around the LLVM version, but I figured it out!) But now what? cargo run gives me:

$ cargo run
error: a bin target must be available for `cargo run`

Just hoping to get the TUI up and running so I can play around. If you let me know what I'm missing, I'll file a PR to help others get started, too.

Explanation of currently supported types?

First, this project is super exciting!

I'd love to see an explanation of supported types pretty high up in the readme. As this project is influenced by Rust, it's notable that the landing page of the docs features all of the supported types.

Fully going on opinion here, but that's also a good way to grok what a language is about. For example, if you come to a language like Go from a language like Ruby or JavaScript, one of the first unique aspects you're likely to come across is the difference between a string and a byte array.

So like, when I first come to a language, the first thing I do is decide what are going to be the mind-bending aspects of the learning curve, and types give a hint in that regard.

For me, it's like this. With Rust, that's borrowing. With Go, it's the lack of generics. With Haskell, it's that there's no NULL.

So what's going to blow my mind about Envious?

Garbage Collector

The language needs to have a garbage collector, which would improve the languages merit. Libgc may be an option, however, I still do not know how to integrate that into the program.

Add a basic REPL

A REPL will be very useful for programmers and is somewhat expected these days. The REPL will have to support lots of features such as support for multiple lines, in-built commands, support to edit previous commands and code, and autocompletion just to name a few. This will probably get its own Kanban board in the Github projects tab. For now, a basic REPL loop should suffice. Additional features can be added as the project grows.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.