diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..15f6171 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing to Perk + +Welcome to the Perk contribution guide! + +--- + +## Finding what to contribute on +A good starting point is to check [issues tagged with "good first issue"](https://github.com/Alex23087/Perk/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22). These should be simple tasks that we left behind specifically for people who want to contribute but don't know where to start. + +If you have issues with those issues, or want to contribute in a different way, you can either open a new issue or reach out to us on [Discord](https://discord.com/invite/DgDDV6xPQe). + +--- + +## Pull Request Process +We don't have a strict pull request process, but here are some guidelines to follow: +1. Fork the repository and create your branch from `main`. +2. If you've added code that should be tested, add tests. +3. :warning: **Ensure the test suite passes.** :warning: + - Ideally, all tests should pass before you submit your pull request. See [Tests](#tests) for more information. If you can't get them to pass, you can still submit your PR, but please explain why the tests are failing in the PR description. We will absolutely help fix the tests, but it will likely delay the merging of your PR. +5. Issue that pull request! + +:warning: **If you open a pull request to change a big part of the language, such as adding an entirely new construct, or changing how something is compiled, please get in touch with us first, either by opening an issue or reaching out on Discord. This will help us ensure that your changes align with the project's goals and avoid unnecessary work.** :warning: + +--- + +## Tests +:warning: All references to the static tests only currently apply to the [`devel`](https://github.com/Alex23087/Perk/tree/devel) branch, and will be merged to `main` in the (near) future. :warning: + +### Directory structure +Our current test setup consists in a number of Perk programs that should test small parts of the language. These programs are located in the `tests/` directory. The structure of this directory is as follows: +``` +tests/ +├── pass/ # Should compile and run successfully (dynamic) +├── fail/ # Should fail to compile (dynamic) +├── pass_static/ # Should compile and run successfully (static) +├── fail_static/ # Should fail to compile (static) +└── future/ # Tests for future features (not run) +``` +In more detail: +- `pass/` and `fail/` test features of the full language, with support to features that require dynamic memory allocation (or in general runtime support) +- `pass_static/` and `fail_static/` test the subset of the language that can be compiled to C without any runtime support (i.e. no heap allocation, no garbage collection, no standard library) +- `future/` contains tests for features that are not yet implemented, and are more of a concept for what we want to implement in the future. These tests are not run. + +### File structure +Each test is a `.perk` file, with a name starting with an increasing number (for example `01-hello_world.perk`). This number is used to order the tests when they are run, and should be unique in each directory. + +Every **passing** test (i.e., a test in `pass/` or `pass_static/`) also has a corresponding `.expected` file, which contains the expected output of the test. The make target checks that the output of the test matches the expected output. **If there is no `.expected` file, or the output differs, the test is considered to fail.** + +### Running the tests +To run the tests, simply run: +```bash +make test +``` +This will run all the tests in `pass/`, `fail/`, `pass_static/` and `fail_static/` + +You can also run a specific set of tests by running one of: +```bash +make test_pass +make test_fail +make test_pass_static +make test_fail_static +``` + +All test commands support passing a specific test file as an argument. For example: +```bash +make test_pass FILE=42 +``` +will only run the test that matches `test/pass/42*.perk`. + +All the tests should pass. If you add a new feature, please add tests for it in the appropriate directory. diff --git a/README.md b/README.md index f78fe91..e44e7ab 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,43 @@ # Perk -Perk is a modern low level programming language, compiled to C. It builds on C's simplicity, adding features such as option types, lambdas and typeclasses. Its current goal is to replace C in the implementation of the MellOS operating system. +Perk is a modern low level programming language, compiled to C. It builds on C's simplicity, adding features such as option types, lambdas, typeclasses and algebraic data types. Its current goal is to replace C in the implementation of the [MellOS](https://github.com/mell-o-tron/MellOs) operating system. --- -## Run Perk with nix +## Join us! +If you want to join Perk development, discussions, or just want to see what's going on, join our [Discord server](https://discord.com/invite/DgDDV6xPQe)! +We love new people joining the community, and are always happy to help out new contributors, so don't hesitate! -```bash -nix run github:Alex23087/Perk -- [files] -``` +--- -This will build the `perkc` compiler and run it directly (you can pass any arguments after `--`). +## Table of Contents +- [Documentation](#documentation) +- [Integration with C](#integration-with-c) +- [Features](#features) +- [Running Perk](#running-perk) + - [Nix](#nix) + - [Arch Linux](#arch-linux) +- [Extensions](#extensions) + - [VSCode](#vscode) + - [Vim](#vim) +- **[Contributing](CONTRIBUTING.md)** + +--- ## Documentation We are using `ocamldoc` to generate the documentation. Use the command `make docs` to generate the documentation. +You can view the latest documentation automatically built from this repository on [the Perk website](https://perklang.org/). + +--- + ## Integration with C Import C libraries using `import "libname.h"`. The compiler will automatically add most of the prototypes from the C source to the typechecker. This is not yet perfect, and does not yet work for custom include paths [(check out this issue)](https://github.com/Alex23087/Perk/issues/12), nor does it currently include macros. +--- + ## Features - Simple **type inference** @@ -41,8 +59,8 @@ let position: (float * float) = (200.,200.) - **Option types**, with implicit boxing at assignment ``` - let z : (int*)? = nothing; - z = just &x; +let z : (int*)? = nothing; +z = just &x; ``` - **Typeclass system** (*Archetypes and Models*) @@ -89,4 +107,71 @@ fun streq (s1 : char*) : char* => int { } ``` -- Static subset (only uses the stack, only allows non-capturing lambdas) \ No newline at end of file +- Static subset (only uses the stack, only allows non-capturing lambdas) + +- Algebraic data types (ADTs) :warning: currently in `devel` :warning: + +``` +type IntList = | Empty | Cons (int, IntList) + +fun sum (l : IntList) : int { + let res := 0; + match (l) { + Empty {res = 0}, + Cons(var x : int, var l1 : IntList) {res = x + sum(l1)} + }; + return res +} +``` + +--- + +## Running Perk +### Nix + +```bash +nix run github:Alex23087/Perk -- [files] +``` + +This will build the `perkc` compiler and run it directly (you can pass any arguments after `--`). + +### Arch Linux +[![AUR](https://img.shields.io/aur/version/perk-opam-git?style=flat)](https://aur.archlinux.org/packages/perk-opam-git) + +Perk is on the AUR!\ +You can install `perk-opam-git` from your favourite AUR helper. + +This package pulls the latest Perk version from the main branch of this repository and builds `perkc` using `opam` and `dune`. All required dependencies are automatically installed. It then installs the compiler in `/usr/local/bin/perkc` + +--- + +# Extensions + +## VSCode + +We have two extensions for VSCode, located in `tools/vscode-extensions/`: +- `perk-syntax`: provides syntax highlighting for Perk files; +- `perk-lsp`: provides error checking using `perkc --check`. + +To install them, you should build them using `make extensions` and then install them in VSCode using the "Install from VSIX..." option. + +## Vim + +An extension is available for Vim (or NeoVim), located in `tools/vim-extensions/`: + +- `perk-syntax`: provides syntax highlighting for Perk files; + +To install it, copy the content of the `tools/vim-extensions/perk-syntax/` in your Vim pack directory: +``` +mkdir -p ~/.vim/pack/perk/start/perk +cp -R ./tools/vim-extensions/perk-syntax/* ~/.vim/pack/perk/start/perk/ +``` + +For vim-plug: +``` +call plug#begin() +Plug '~/{path-to-perk}/tools/vim-extensions/perk-syntax' +call plug#end() +``` + +For more details refer to the [README.md](./tools/vim-extensions/perk-syntax/README.md) of the extension. diff --git a/tools/vim-extensions/perk-syntax/README.md b/tools/vim-extensions/perk-syntax/README.md new file mode 100644 index 0000000..0afe561 --- /dev/null +++ b/tools/vim-extensions/perk-syntax/README.md @@ -0,0 +1,38 @@ +# Perk Vim Syntax Plugin + +This directory provides a minimal Vim plugin for Perk syntax highlighting and filetype detection. + +## Installation +Copy (or symlink) the contents into your vim (or nvim) runtime path, e.g.: + +``` +mkdir -p ~/.vim/pack/perk/start/perk +cp -R ./* ~/.vim/pack/perk/start/perk/ +``` + +For vim-plug: +``` +call plug#begin() +Plug '~/{path-to-perk}/tools/vim-extensions/perk-syntax' +call plug#end() +``` + +## Features +- Highlights Perk keywords, types, numbers, strings (with escapes), comments and TODOs. +- Highlights function names after `fun` and variable names declared via `let`. +- Marks embedded C delimiters `BEGIN_C` / `END_C`. + +## Extending +You can add more highlighting by editing `syntax/perk.vim`: +- Add new keywords to the `perkKeyword` group. +- Add additional types to `perkType`. +- Create new regions for multi-line constructs. + +## Filetype Detection +`ftdetect/perk.vim` sets the filetype for any `*.perk` file automatically. + +## Troubleshooting +If highlighting does not appear: +1. Run `:echo &filetype` to verify it reports `perk`. +2. Ensure the plugin directories are correctly placed in your runtime path. +3. Check for conflicting plugins defining `perk`. diff --git a/tools/vim-extensions/perk-syntax/ftdetect/perk.vim b/tools/vim-extensions/perk-syntax/ftdetect/perk.vim new file mode 100644 index 0000000..e18bf05 --- /dev/null +++ b/tools/vim-extensions/perk-syntax/ftdetect/perk.vim @@ -0,0 +1,5 @@ +" Filetype detection for Perk +augroup perk_filetype + autocmd! + autocmd BufNewFile,BufRead *.perk setfiletype perk +augroup END diff --git a/tools/vim-extensions/perk-syntax/syntax/perk.vim b/tools/vim-extensions/perk-syntax/syntax/perk.vim new file mode 100644 index 0000000..bfc85d6 --- /dev/null +++ b/tools/vim-extensions/perk-syntax/syntax/perk.vim @@ -0,0 +1,54 @@ +" Vim syntax file for Perk language +" Derived from VSCode grammar +" Maintainer: axdelafuen + +if exists("b:current_syntax") + finish +endif + +" Keywords +syn keyword perkKeyword let import open extern archetype model struct private public fun for while do if then else return summon banish make cast of just nothing + +" Types +syn keyword perkType int void uint8_t uint16_t uint32_t uint64_t float double bool char + +" Comments +syn match perkComment "//.*" contains=perkTodo +syn region perkComment start="/\*" end="\*/" contains=perkTodo +syn match perkTodo "\" contained + +" Strings +syn region perkString start=+"+ skip=+\\\\.+ end=+"+ contains=perkEscape +syn region perkString start=+'+ skip=+\\\\.+ end=+'+ contains=perkEscape +syn match perkEscape "\\\\." contained + +" Numbers +syn match perkNumber "\<0x[0-9A-Fa-f]\+\>" +syn match perkNumber "\<0o[0-7]\+\>" +syn match perkNumber "\<0b[01]\+\>" +syn match perkFloat "\<[0-9]\+\.[0-9]\+\>" +syn match perkNumber "\<[0-9]\+\>" + +" Function names after 'fun' +syn match perkFunctionName /\