GithubHelp home page GithubHelp logo

noa's Introduction

Noa logo

Noa

Note

Noa is currently a heavily work-in-progress project. The current state of the project does not fully represent what the final result is meant to look like.

Noa is a dynamically typed, imperative, compiled programming language. The language features a familiar C/JS/Rust-like syntax with static variable resolution (so no "variable is not defined" errors!) and a lightweight featureset. Jump down to the samples section for some code samples!

Noa compiles to its own cross-platform bytecode format Ark which in turn can be run through the Noa runtime.

In addition to the language itself, Noa also features a VSCode extension with full(-ish) language support! The extension currently supports basic syntax highlighting, error messages, basic intellisense, go to definition, find all references, and renaming symbols!

This merely a passion project of mine and is not meant to be taken seriously! It's not meant to be a "production-ready" language, but I hope to one day be able to write some somewhat useful programs in it.

Installation

Note

Noa can currently only be compiled from source.

Compile from source

To compile and install Noa from source, you need the .NET 8 SDK and runtime and Cargo to compile the compiler and runtime respectively. Once you have .NET and Cargo installed, follow these instructions:

  1. Clone the repo using git clone https://github.com/thinker227/noa.git.
  2. cd into the root of the project (the folder which contains this readme file).
  3. Run the update-tool.sh script (or the commands therein, they're all just .NET commands) which will compile and install the complier as a .NET tool. Worry not, you can easily uninstall it using dotnet tool uninstall noa --global.
  4. cd into src/runtime and run cargo build -r which will compile the runtime.
  5. Locate the produced executable (which should be in target/release named noa_runtime or noa_runtime.exe on Windows).
  6. Create an environment variable named NOA_RUNTIME containing the file path to the runtime executable. Alternatively you can specify the --runtime <path> command-line option when running noa run to manually specify the path to the runtime executable, however it's much simpler to use an environment variable.
  7. You'll usually have to restart your terminal and/or pc for the environment variable and .NET tool to be available.

After everything has been installed, you can invoke the Noa CLI using the noa command from your terminal!

VSCode extension

Compile from source

To compile and install the VSCode extension from source, you need Node.js and vsce. Also make sure you have code available from the command line.

  1. cd into src/vscode-extension and run npm install followed by npm run compile.
  2. Run vsce package. If it warns you that a license file cannot be found, type y and enter to continue.
  3. Run code --install-extension <path>, replacing <path> with the file path to the .vsix file which vsce generated.

Project status

  • AST
  • Lexer
  • Parser
  • Scope/symbol resolution
  • Flow analysis
  • Optimization
  • Bytecode
  • Runtime
  • CLI
  • Language server

Samples

Warning

Some of these samples may currently not work.

print("Hello world!");
let x = 0;

x = 1; // ERROR: x is immutable

let mut y = 2;

y = 3; // fine
let x = {      // Block expression
    let a = 1;
    let b = 2;
    a + b      // Implicit return from block
};
func add(a, b) => a + b;

let num = add(1, 2);
func greet(name) {
    print("Hello, " + name + "!");
};

let name = readLine();
greet(name);
func createCounter() {
  let mut x = 0;
  () => {
    x += 1;
    x
  }
}

let counter = createCounter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3

Dreamlands

// Import module
import "module.noa" (foo, bar, baz);

// Export stuff
export (val, hello);

let val = 69;
let hello = () => print("Hello!!!");

noa's People

Contributors

thinker227 avatar

Stargazers

Ferenci Ákos avatar Jérémie Astor avatar

Watchers

 avatar

Forkers

ace-of-heartz

noa's Issues

Documentation

Allow doc comments above variables and functions which are available on the node and symbol as well as displayed in Intellisense. Doc comments should likely start with /// and can contain simple markdown.

/// This is a doc comment for `x`. 
let x = 0;

/// This is a doc comment for `f`. 
/// It always returns [`x`]. 
func f() => x;

For a non-hacky implementation, a concrete syntax tree (#29) would be quite useful before implementing this. This could already be implemented though since some tokens exist in the AST, and doc comments should only be able to appear on eg. let and func tokens. Still need whitespace in tokens though.

Lambda hover info

Add a tooltip when hovering over a lambda => arrow which displays info about lambda parameters and captured variables. Requires #36 for retrieving the captured variables.

let x = 1;
let f = (y) => x + y;

Hovering above the => should produce something like this:

(y) => ...

Captured variables: x

Implict top-level function

Make the top-level of a file evaluate as a function. This would also allow typing the root of a file as BlockExpression.

  • If the top-level function returns an integer, it is used as the exit code of the program.
  • If the top-level function returns nil (#16), the exit code is implicitly 0.
  • Todo: what should happen if the top-level function returns anything else?

Module system

Implement a system for importing and exporting functions from different files/modules.

A couple alternatives for a basic syntax:

from "./path/to/module" import {a, b, c}
// Very function-like
import ./path/to/module(a, b, c);
// Javascript-y
export func f() => ...;
// Function-like
export(f);
func f() => ...;

Additionally it would be somewhat nice to be able to import/export things as aliases.

(this issue is a heavy work in progress, more research should be done on how to implement a decent module system)

REPL

Add a basic REPL for evaluating expressions and running them.

Binary and and or expressions

Add binary boolean and and or expressions. Syntax could be either the traditional C-like && and || or a more explicit and and or syntax.

Add ... hole token/expression

Add ... as a "hole" which acts an an inline comment.

let x = ...;

func f(...) => ...;

func g(x) {
    print(x);
    ...
    print(y);
}

In place of an expression, ... could potentially evaluate to a runtime "not implemented" error. In any other place it should act as a comment without affecting surrounding code.

Chained invocations aren't parsed properly

Chained invocation expressions are not parsed properly.

func f() => f;

f()();

Currently the expression stops being parsed after the first () while it should in reality continue parsing an expression and construct another invocation expression with f() as the target.

Additional infrastructure for VSCode extension

  • A setting to set the minimum verbosity levels for logs when launching the language server. Also implement a corresponding configuration value in the extension which should be passed to the language server on startup.
  • Warnings in case of failure to find the CLI executable.

Reachability diagnostics

Add diagnostics reported for unreachable code. See #27.

Currently unsure of exactly where to report these diagnostics.

Add nil literal

Add nil as a literal expression.

Consider () as the syntax instead to aid making the lang statically typed.

API for lambda closures

Add a better API for retrieving information about captured variables in lambdas and their associated closure. This will aid when eventually implementing closures at runtime.

Built-in functions

Add support for functions not defined in source but rather natively in the runtime.

Some useful functions to have:

  • print(what)
  • input() (maybe use a different name?)
  • readFile(path)
  • writeFile(path, text)

Built-in functions could potentially be implemented using a special built-in module (see #41).

Strings

Add string literals and runtime support for string objects. Requires #43. Consider supporting string interpolation and raw strings, eg. string literals with newlines.

Add assignment statements

Add statements for assigning values to variables

let mut x = 0;
x = 1;

Assigning to an immutable variable should be an error

let y = 2;
y = 3; // error

Assignment targets should follow the same lookup rules as identifier expressions.

Drop tuple support

Since the language is currently dynamically typed, arrays and tuples are pretty much the same kind of structure, except arrays are more flexible. See #20 for arrays. Tuples would be better suited once/if the language becomes statically typed.

Produce an error on all tuple expressions indicating that tuples aren't supported.

Concrete syntax tree

Implement tokens and whitespace into the syntax tree. This would allow for more precise error reporting locations as well as various useful info.

Add list- and list access expressions

Add list "literal"/construction expressions with the classic [a, b, c] notation. These expressions should allow trailing commas.

In conjunction, add list access expression as xs[n], where xs is a valid l-value and n is any arbitrary expression. List access expressions are valid l-values.

Objects

Add support for objects. What these object should look like is up in the air. They'll most likely use prototypical inheritance and support mutable/immutable properties/fields.

Hovers and completions break when the cursor is above whitespace

Hovers and completions in the language server break when the cursor position is in what is technically whitespace. This is especially annoying when the cursor position is one past the end of a node (foo|) which makes completions completely unusable.

This also causes misplaced symbol completions because the node under the cursor might technically be in the surrounding block.

{
    print(x);
    |
    print(y);
}

Introducing whitespace-aware tokens (#29) would likely fix this issue because the span of nodes would leech off any associated whitespace.

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.