sapphire/README.md

149 lines
4.5 KiB
Markdown
Raw Normal View History

2022-06-22 17:12:41 +00:00
# Sapphire
A modern, fast and reliable programming language. (WIP)
2022-08-25 18:37:50 +00:00
**WARNING**: The About, Basic usage and Examples sections are planned for the future and not yet implemented. They are just sections that describe what is planned for Sapphire for the future, since at the moment there are not many features to describe.
2022-06-22 17:12:41 +00:00
## About
Sapphire is a relatively high-level programming language, yet low-level when it needs to be. The language supports low-level memory manipulation using pointers, but pointer arithmetic is only allowed in unsafe contexts, for greater memory safety. Dynamic memory allocation is also a thing, though it is recommended not to use it directly, but instead make great use of [smart pointers](https://en.wikipedia.org/wiki/Smart_pointer).
Sapphire is a [compiled](https://en.wikipedia.org/wiki/Compiled_language) programming language, with static typing, although [type inference](https://en.wikipedia.org/wiki/Type_inference) is also supported. It also has a high-level standard library, which supports console/file I/O, operating system functions, advanced math operations, string manipulation, and many more.
## Basic usage
"Hello world" in Sapphire:
```
const io from @'core/io';
let @main in {
io.outln('Hello, World!');
}
```
or alternatively:
```
const { outln } from @'core/io';
let @main in {
outln('Hello, World!');
}
```
## Examples
FizzBuzz:
```
const io from @'core/io';
const { toString } from @'core/type_utils';
let @fizzBuzz(i32 i) in {
String result = '';
if(i % 3 == 0)
{
if(i % 5 == 0)
{
result = 'FizzBuzz';
} else {
result = 'Fizz';
}
} else {
if(i % 5 == 0)
{
result = 'Buzz';
} else {
result = toString(i);
}
}
io.outln(result);
}
let @main in {
for(i32 i = 1; i <= 100; i++)
{
fizzBuzz(i);
}
}
```
Quine:
```
const io from @'core/io';
String fmt = 'const io from @%ccore/io%c;%cString fmt = %c%s%c;%clet @main in {%c%cio.outf(fmt,39,39,10,39,fmt,39,10,10,9,10,10);%c}%c';
let @main in {
io.outf(fmt,39,39,10,39,fmt,39,10,10,9,10,10);
}
2022-06-22 17:30:21 +00:00
```
2022-08-25 18:25:38 +00:00
## Examples that actually work right now
Exit with exit code 0 (success):
```
2022-08-26 14:22:40 +00:00
let @main : i32 in {
2022-08-25 18:25:38 +00:00
0
}
```
Exit with non-zero exit code (failure):
```
2022-08-26 14:22:40 +00:00
let @main : i32 in {
2022-08-25 18:25:38 +00:00
1 // or any other number
}
```
Exit with calculated exit code (yes, this language is a glorified calculator right now):
```
2022-08-26 14:22:40 +00:00
let @main : i32 in {
2022-08-25 18:25:38 +00:00
3 + 5 * 6 // It doesn't even support parentheses, what a failure
} // the exit code is actually computed at compile time by LLVM (optimizations!!)
```
2022-06-22 17:30:21 +00:00
## Documentation
2022-08-25 18:25:38 +00:00
More documentation is available at [Documentation](docs/Documentation.md), whenever this file gets created.
2022-06-22 17:30:21 +00:00
## Building
2022-08-25 18:19:42 +00:00
2022-07-19 13:33:22 +00:00
First, install the required packages. (ninja is optional, you can use any build system you want)
2022-06-22 17:30:21 +00:00
Debian/Ubuntu:
2022-06-22 18:24:16 +00:00
`# apt install zlib1g-dev build-essential cmake ninja-build llvm-dev`
2022-06-22 17:30:21 +00:00
2022-06-22 17:52:45 +00:00
CentOS/Fedora/RHEL: `# dnf install gcc gcc-c++ zlib-devel libffi-devel cmake ninja-build llvm-devel`
2022-06-22 17:30:21 +00:00
2022-06-22 18:38:39 +00:00
Arch: `# pacman -S gcc cmake ninja llvm-libs llvm`
2022-06-22 17:30:21 +00:00
2022-07-19 13:33:22 +00:00
For Ninja users:
2022-06-22 17:51:59 +00:00
On platforms that install ninja to `/usr/bin/ninja` instead of `/usr/bin/ninja-build`, CMake may fail.
In that case, symlink ninja-build to ninja (`ln -s /usr/bin/ninja /usr/bin/ninja-build`).
2022-07-19 13:33:22 +00:00
First-time setup:
```
2022-08-25 18:37:50 +00:00
./sapphire.sh generate <build system, such as Ninja or Unix Makefiles (you can view all possible options with cmake --help)> <build type: Debug or Release (or MinSizeRel/RelWithDebInfo)>
2022-07-19 13:33:22 +00:00
```
2022-06-22 17:30:21 +00:00
2022-07-19 13:33:22 +00:00
To change build type/build system, just run `./sapphire.sh clean` followed by the generate command above.
2022-06-22 17:30:21 +00:00
2022-07-19 13:33:22 +00:00
Building:
2022-06-22 17:30:21 +00:00
```
2022-07-19 13:33:22 +00:00
./sapphire.sh build
2022-06-22 17:30:21 +00:00
```
2022-07-19 13:33:22 +00:00
Installing (probably will have to be run as administrator/root):
2022-06-22 17:30:21 +00:00
```
2022-08-25 18:19:42 +00:00
./sapphire.sh install <destination, default depends on platform, on Linux it's often /usr/local>
2022-06-22 17:30:21 +00:00
```
2022-07-19 13:33:22 +00:00
This will install the compiler at `<destination>/bin/sapphirec`.
2022-06-22 17:30:21 +00:00
## Running
The compiler is built at `build/sapphirec`.
2022-08-25 18:19:42 +00:00
For now, it can only generate object files/LLVM IR, so you'll have to link manually.
2022-06-22 17:30:21 +00:00
A few example commands:
2022-08-25 18:37:50 +00:00
```sh
2022-06-22 17:30:21 +00:00
$ build/sapphirec --version # prints the compiler version
$ build/sapphirec --help # shows usage
$ build/sapphirec main.sp # compiles a file
2022-08-25 18:19:42 +00:00
$ build/sapphirec main.sp -o main.o # compiles a file with output filename
$ build/sapphirec main.sp -o main.o --msystem darwin # compiles a file for macOS
$ build/sapphirec main.sp -o main.o && gcc main.o -o main && ./main # compiles, links and runs
$ build/sapphirec main.sp -o main.ll --emit-llvm # display the generated cross-platform LLVM intermediate representation
2022-08-25 18:37:50 +00:00
```
## License
[BSD-2](https://opensource.org/licenses/BSD-2-Clause), since that's my favorite license :). See [LICENSE](LICENSE).