Code Monkey home page Code Monkey logo

gecko's Introduction

Logo

Gecko is a general-purpose programming language built for the LLVM platform.
Gecko

GitHub branch checks state Discord



Technology & principles

Gecko is a general-purpose, strongly-typed programming language, with a focus on a powerful type system, memory safety, and simplicity. Inspired by Rust, Python, Java, C#, JavaScript, Scala, and others. Built using Rust. It uses πŸ”—LLVM as its backend.

Overview:

Syntax example

extern func puts(msg: Str) -> Int

func main(argc: Int, argv: *Str):
  unsafe:
    puts("hello world")

  return 0

Project roadmap

πŸ”¨ β€” Work in progress. βœ”οΈ β€” Completed.

Feature Note(s) Status
Functions - βœ”οΈ
Externs - βœ”οΈ
Function calls - βœ”οΈ
Structs Definition, declaration & accessing of structs. πŸ”¨
Modules - πŸ”¨
Generics - πŸ”¨
if statement Includes the else statement as well. βœ”οΈ
return statement - βœ”οΈ
Variables Declaration, assignment, and reference of variables. βœ”οΈ
Casting Type casts between primitives. βœ”οΈ
Binary expressions - βœ”οΈ
Literals Includes string, integer, character, and boolean literals. βœ”οΈ
Types Basic types such as Bool, Int, Str, etc. βœ”οΈ
Static arrays Arrays with sizes specified (or determined) at compile-time. βœ”οΈ

Directory structure

Path Description
.github/ Contains GitHub configuration files. For example, the GitHub actions workflow file rust.yml.
src/ The root directory for the project's source files.
tests/ Root directory for integration tests.
.gitignore Configuration file to specify paths ignored by Git.
Cargo.lock Cargo configuration file.
Cargo.toml Cargo configuration file.
LICENSE The license file.
README.md Information about the project.

Language specification

β€” Identifiers & naming

Naming is straight forward. Whitespace and most special characters are disallowed in names (with the exception of _). Identifiers must not start with a number. They must also not be reserved keywords or types.

Here is the exact regular expression rule for identifiers:

^([_a-zA-Z]+[\w]*)

πŸ”—test this regular expression

β€” Comments

Only single-line comments are available for simplicity. All comments start with the # character, and anything after that is considered part of the comment and is ignored by the compiler.

# This is a comment.

It should be noted that string literals take precedence over comments, in the case that they appear before comments (as one would logically expected):

"# This is a string literal."

Please note that some code examples might include comments using //, this is illegal syntax and it is only used for syntax highlighting on this document.

β€” Types

Several intrinsic types are defined by the compiler. It is intended for the intrinsic types to be bare-bones, and to have the standard library expand upon them, this allows for easier refactoring of type-specific functions, without having to modify the compiler's source code.

Definition Description
Bool Boolean type. Its value can either be true or false.
Str String type. Equivalent to i8* or int* in other languages.
I8 Integer type with bit-size 8. Can be used to define characters, as well as strings as a pointer.
I16 Integer type with bit-size 16. Equivalent to a short int on other languages.
I32 Integer type with bit-size 32. Equivalent to an int on other languages. Usually the most common number type used.
I64 Integer type with bit-size 64. Equivalent to a long int on other languages. Useful for larger numbers.

β€” Modules

Modules provide a simple way of organizing code within a project. They also have the advantage of preventing global naming collisions (ex. when importing a library). Modules are based off the file name, and are to be defined in the src/ directory. They are not declared in code for simplicity.

Accessing a module is trivial:

foo::bar::entity

β€” Functions

Function definitions & calls follow conventional norms. They are easy to define and use. The language grammar was designed in a way to have only one way to achieve things, with the idea that limited options remove the problems of different programmers using different methods of accomplishing the same thing (ex. different function declaration syntaxes). This way, whenever you encounter code you know what to expect right away.

Omitting the return type will imply that such function does not return a value (the equivalent to other languages' void type). Functions without return types may not return a value, nor are they required to have a return statement on their bodies.

func main(argc: Int, argv: *Str):
  return 0

func do_nothing():
  pass

β€” Variables

Variable declaration, assignment and reference follow straight-forward rules and adhere to common conventions. This makes creating, and using variables easy and most programmers will be familiar with this style. Variable names adhere to the identifier rule.

let product: Int = 3 * 4

For convenience, variables can also be declared without specifying their types by using the let keyword for type inference. When inferring type from a literal integer, the preferred type inferred by the compiler will be i32, unless the integer cannot fit into i32's bit-size, in which case it will be either i64 or i128 depending on the value's required bit-width. For example, a value larger than 2147483647 will be inferred as i64 because it cannot fit into i32.

Variable declarations are immutable by default, unless the mut keyword is used.

let five: Int = 5 // type is explicitly given
let inferred_three = 3 // inferred type is `Int`
let big_number_i64 = 2147483647 + 1 // type is inferred to be `I64`
var counter = 0 // can be mutated/re-assigned

β€” Loops

There is a single loop construct that can be used to emulate while, for, and infinite loops. The loop construct is a pre-test loop, meaning its condition is always evaluated before its body is executed.

You can use the continue and break keywords as statements inside the loop body to control the loop.

loop: // no condition specified: infinite loop (the condition is assumed to be `true`)
  pass

loop condition: // pre-test loop with a condition, emulates a while loop
  pass

Here's a code example that will iterate 10 times:

let mut counter = 0

loop counter < 9:
  counter += 1

β€” Attributes

Attributes can be used to modify the behavior of functions and externs. They act as metadata, and only exist during compile-time. Below is the syntax for attributes:

@attribute_name // no arguments, equivalent to `@attribute_name()`
@example_1(arguments)

Attribute names must be valid identifiers, and they may optionally contain an argument list. Having duplicate attributes attached to a single function will result in an error, as well as the use of an undefined/unrecognized attribute.

Below is a list of all the intrinsic attributes available:

  • @deprecated: Marks a function as deprecated. A warning will be issued if the attached function is called.
  • @inline: Marks a function as inline. This will cause the compiler to inline the function, which may result in a performance gain.
  • @export: Marks a function to be exported externally. Its named will not be mangled.
  • @no_discard: The result of the function must be used, otherwise a warning will be issued.
  • @tail_recursive: Marks a recursive function to be validated for tail-recursion. In case that the function cannot be validated to be tail-recursive, an error will be issued. This is useful to prevent possible stack overflow exceptions caused by logic errors.
  • @calling_convention(str): Specifies the calling convention of an extern function. Attaching this attribute to a non-extern function will result in an error.

Building

β€” Environment variables

If building from source: Set the LLVM_SYS_120_PREFIX environment variable to the build directory inside the LLVM source files. It is expected that LLVM was built from source at this point. Additionally, set the LLVM_CONFIG to point to the build/bin/llvm-config (or build/bin/llvm-config.exe on Windows) executable file. Do not wrap the path with quotes, as it might lead to Access denied errors when attempting to build llvm-sys. If you're using Visual Studio Code, ensure it is seeing the LLVM_SYS_120_PREFIX environment variable.

β€” Linux

On Linux, you simply need to install the llvm and llvm-devel packages. Make sure they're both v13.0.0.

If you're using Fedora:

sudo dnf -y install llvm llvm-devel

You won't need to set any environment variables. Additionally, avoid using the llvmenv crate, since it's barely maintained and may lead you to issues.

After installing, you can verify you're running the correct LLVM version by using the llvm-config command:

$ llvm-config --version
13.0.0

If, after installing llvm-devel and restarting your shell session you're still having problems with the inkwell crate not being able to find the LLVM installation, try setting the LLVM_SYS_130_PREFIX environment variable manually:

export LLVM_SYS_130_PREFIX=${llvm-config --prefix}

That should fix the problem, then try running cargo build once more.

β€” Windows

On the Windows platform, it is recommended to use MSYS2 to install the GCC toolchain. After installing MSYS2, open the MSYS2 MinGW (64-bit) console (or the 32-bit if you're on 32-bit arch.), then install the GCC toolchain using:

pacman -S mingw-w64-x86_64-gcc

This project uses the inkwell crate to interface with LLVM. Thus, the GCC toolchain (through MSYS2) is required in order to build the llvm-sys Cargo package (which is a dependency of inkwell).

β€” Building Cargo crate

You will need to have πŸ”—Rust installed in order to build the project using Cargo. Once (or if you already have it) installed, you can simply build the project and its dependencies by issuing the following command:

cargo build

Running tests is also straight-forward:

cargo test

gecko's People

Contributors

theclonerx avatar

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.