An open API service indexing awesome lists of open source software.

https://github.com/rickisgone/tungsten

A statically typed compiled programming language inspired by C++ and Java written in C++20
https://github.com/rickisgone/tungsten

build-system compiler languages package-manager programming-language

Last synced: about 2 months ago
JSON representation

A statically typed compiled programming language inspired by C++ and Java written in C++20

Awesome Lists containing this project

README

          

# The Tungsten programming language


the tungsten logo

## introduction

*Tungsten* is a statically-typed multi-paradigm compiled programming language made with the LLVM framework and inspired
by C++ and Java

## Example

Below is a snippet of code which shows some of the basic functionalities of tungsten

```c++
fun fibonacci(i64 n) -> i64 {
if (n <= 1)
ret n;
ret fibonacci(n - 1) + fibonacci(n - 2);
}

fun main() -> i32 {
for (i64 i = 0; i < 10; ++i) {
print("fibonacci(%lu) = %lu\n", i, fibonacci(i));
}
ret CodeSuccess;
}
```

> [!WARNING]
> the language is still under development, and everything is subject to change

# VSCode Extension

You can install the VSCode extension for *Tungsten* from
the [VSCode marketplace](https://marketplace.visualstudio.com/items?itemName=RickIsGone.tungsten)
or by searching for `tungsten` in the extensions tab of VSCode.
You'll need to have the compiler installed on your system for the extension to work properly.

# Installation

You have two options to get Tungsten:

## Option 1: Download Pre-compiled Binaries

You can download pre-compiled binaries from
the [GitHub Releases page](https://github.com/rickisgone/tungsten/releases/latest).

Available packages:

- **Windows**: `.zip`, `.msi`, `.7z` packages
- **Linux (Ubuntu)**: `.deb`, `.tar.gz`, `.7z`, `.sh` packages

Simply download the appropriate package for your platform.

## Option 2: Build from Source

If you prefer to build from source or need the latest development version, follow the building instructions below.

# Building

| Platform | Build Status |
|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Ubuntu | [![Ubuntu Build](https://github.com/rickisgone/tungsten/actions/workflows/Ubuntu%20build.yml/badge.svg)](https://github.com/rickisgone/tungsten/actions/workflows/Ubuntu%20build.yml) |
| Windows | [![Windows Build](https://github.com/rickisgone/tungsten/actions/workflows/Windows%20Build.yml/badge.svg)](https://github.com/rickisgone/tungsten/actions/workflows/Windows%20Build.yml) |
| Mac | [![macOS build](https://github.com/RickIsGone/tungsten/actions/workflows/MacOS%20build.yml/badge.svg)](https://github.com/RickIsGone/tungsten/actions/workflows/MacOS%20build.yml) |

## Prerequisites

Global

- cmake 3.28 or newer
- git

Compiler

- LLVM 18 or newer
- ZLIB (windows only)

Package Manager

- Libcurl
- libarchive

If you are on windows i'd suggest using [vcpkg](https://github.com/microsoft/vcpkg) to install the dependencies

> [!IMPORTANT]
> this project uses C++ modules, which are currently not supported by all compilers and CMake generators, so make sure
> to use both a compiler and a CMake generator that supports modules

**1. Cloning the repo:**

Start by cloning the repo with `git clone https://github.com/rickisgone/tungsten`
after doing this follow the instruction for the targeted OS

WINDOWS

**2. Compiling the project:**

Here I'm using vcpkg:

```bash
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE='VCPKG_DIR\scripts\buildsystems\vcpkg.cmake' -DVCPKG_TARGET_TRIPLET=x64-windows-static -DLLVM_DIR='VCPKG_DIR/installed/x64-windows-static/share/llvm/' -Dzstd_DIR='VCPKG_DIR/installed/x64-windows-static/share/zstd'
cmake --build build --config Release
```

replace `VCPKG_DIR` with the vcpkg directory

LINUX

**2. Compiling the project:**

*the default compiler and CMake generator on linux (gcc and Make) don't support modules, so I'll be using Clang and
Ninja in the example below*

```bash
cmake -S . -B build -GNinja -DCMAKE_CXX_COMPILER=clang++
cmake --build build --config Release
```

# Syntax

## Variables declaration

Tungsten has a similar naming convention to Rust, where base types are written in **camelCase** and structs and classes
are written in **PascalCase**

| Type | Alignment (Bytes) |
|----------|-------------------|
| `void` | N/A |
| `int` | 4 |
| `uint` | 4 |
| `float` | 4 |
| `f32` | 4 |
| `double` | 8 |
| `f64` | 8 |
| `char` | 2 |
| `bool` | 1 |
| `String` | N/A |
| `i8` | 1 |
| `i16` | 2 |
| `i32` | 4 |
| `i64` | 8 |
| `i128` | 16 |
| `u8` | 1 |
| `u16` | 2 |
| `u32` | 4 |
| `u64` | 8 |
| `u128` | 16 |

Tungsten has also a variadic type called `argPack` which is just like `...` in C

> [!NOTE]
> all variables are initialized to 0 by default and pointers are initialized to nullptr

### Stack allocation

```rust
i64 myVariable = 247;
i64 myVariable{247};
```

### Heap allocation

```c++
int* myPointer = new int{247};
```

To free the pointer:

```c++
free myPointer;
```

free also sets the address pointed by the pointer to `nullptr`

> [!WARNING]
> Tungsten doesn't have a garbage collector so you have to manually free the pointers

## Arrays

### Stack allocation

```c++
int[10] myArray;
```

### Heap allocation

```c++
int* myArray = new int[10];
```

To free the array:

```c++
free myArray;
```

this works for both normal and multidimensional arrays.

## References

references just just like in C++ are pointers which can't be reassigned and you need to specify an address when
declaring them:

```c++
int var;
int& ref = &var;
```

unlike in C++ to pass them to functions you need to do it explicitly:

```rust
i64 var;
fun(&var);
```

## Control flow statements

### If

If statements are written just like in C++

```cpp
if (condition) {
// do stuff
} else {
// do other stuff
}
```

And just like in C++ you can avoid using braces for single instructions

```cpp
if (condition)
// do stuff
else
// do other stuff
```

### While

Unlike in C++, while statements require braces to work

```cpp
while (condition) {
// do stuff
}
```

### Do while

Do whiles instead are just like in C++

```cpp
do {
// do stuff
} while(condition);
```

### For

For statements just like while statements require braces to work

```rust
for (i64 i = 0; i < 10; + + i) {
// do stuff
}
```

## Functions

Rather than a C++ aproach, functions are more similar to Rust's:

```rust
fun myFunction() -> i64 {
ret 247;
}
```

You can return arrays by doing:

```c++
fun myfunction() -> int[3] {
int[3] array{2, 4, 7};
ret array;
}
```

Or you can allocate on the heap and use a pointer:

```c++
fun myFunction() -> int* {
int* array = new int[3]{2, 4, 7};
ret array;
}
```

### Extern Functions

There are two types of extern functions

- C functions
- tungsten functions

You can import C functions with

```cpp
extern "C" fun myCFun() -> void;
```

and tungsten functions with

```cpp
extern fun myFun() -> void;
```

### Main Function

The `main` function can return either `int` or `i32`. Command line arguments are passed like in C with
`int argc, String* argv` or `i32 argc, char** argv`.
If no return value is provided, `0` will be returned by default.

```c++
fun main(int argc, String* argv) -> int {
/* your code */
ret CodeSuccess;
}
```

If you don't need the command-line arguments, you can simply omit them:

```c++
fun main() -> int {
/* your code */
ret 0;
}
```

### integrated Core Functions

Tungsten has a reduced number of integrated core functions

| Type | Name | Arguments | functionality |
|----------|-------------------|----------------------------------------------|----------------------------------------------|
| `i32` | shell | (String cmd) | same function as`system()` in C |
| `void` | print | (String fmt, ArgPack) | same function as`printf()` in C |
| `void` | input | (String fmt, ArgPack) | same function as`scanf()` in C |
| `String` | __builtinFile | no arguments | returns the name of the file |
| `String` | __builtinFunction | no arguments | returns the name of the function |
| `u64` | __builtinColumn | no arguments | returns the number of the column |
| `u64` | __builtinLine | no arguments | returns the number of the line |
| `String` | nameof | (any statement with a name) | returns the name of the variable |
| `String` | typeof | (any statement with a type) | returns the type of the variable |
| `u64` | sizeof | (any statement with a type or a type itself) | returns the size of the type of the variable |

## Namespaces

You can declare namespaces the same as c++:

```c++
namespace std {
fun a() -> void {}
}
```

but in tungsten you can also declare namespace members outside the namespace block like this:

```c++
namespace std {
fun a() -> void {}
}
fun std::b() -> void {}
```

## Classes

Tungsten also has classes and they are declared like this:

```cpp
class Foo {
constructor() {}
constructor(int init) {this->_member = init}
constructor(const Foo& other) {}

destructor() {}

fun member() -> int { ret this->_member; }

private:
int _member;
}
```

### Member access

```cpp
fun member() -> int { ret this->_member; }
```

As shown here, to access members of the class you need to use the `this` pointer

### Default visibility

Rather than being private by default like in C++, Tungsten classes are public

### Constructors and destructor

```cpp
constructor() {}
constructor(int init) {this->_member = init}
constructor(const Foo& other) {}
destructor() {}
```

Constructors are automatically invoked when creating an object, even if no explicit initialization braces are provided:

```cpp
Foo foo;
Foo foo{};
```

Both forms will call the default constructor.

#### Default constructors and destructor

If no default constructor, copy constructor, or destructor is explicitly defined, the compiler will automatically generate them.

## Building a project

To build a project, you can either compile via cmd by calling the `tungsten` compiler or you can make a `build.tgs` file
and use the integrated buildsystem

### Compiling via cmd

> [!IMPORTANT]
> Tungsten currently uses *clang++* to compile the generated llvm ir to an executable, so you need to have it installed
> for the compiler to work (clang 15 or higher is needed)

```shell
cd projectDirectory
tungsten [flags]
```

### Compiling via buildsystem

> [!IMPORTANT]
> Not added yet

A simple project's build file will look something like this:

```c++
import build;

Project myProject{Executable, "myProject"};

fun main() -> i32 {
myProject.addSource("main.tgs");
myProject.build();
}
```

To build the file, you'll then have to call the compiler in the directory where the build file is located

```shell
cd projectDirectory
tungsten tgs-build [flags]
```

The compiler will then automatically compile the `build.tgs` file.
After compiling the file, the compiler will automatically execute the `build` executable which will compile the project
following the rules set by the `build.tgs` file.
The build output will then be put into the `projectDirectory/build` directory

# TPKG

> [!IMPORTANT]
> Not added yet

tpkg is the package manager included with the *Tungsten programming language*

> [!NOTE]
> tpkg uses a centralized git directory, which is not checked, meaning it's on the users to open issues reporting
> malicious packages

package files are written in **json**, and a simple package file looks like this

```json
{
"name": "myPackage",
"version": "1.0.0",
"description": "my package description",
"homepage": "homepage url",
"license": "MIT/Apache 2.0/ecc.",
"source": "source/release code zip url",
"dependencies": [
"your dependencies"
],
"build": {
"type": "cmd/buildsystem",
"args": [
"myargs"
]
}
}
```

# License

This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE.txt) file for details.