Releases: dosisod/skull
Release v0.9.0
This is a smaller release, but still introduces a lot of nice new features:
Namespaces
Namespaces provide a way to explicitly group a bunch of variables and functions under a new name:
namespace Math {
pi := 3.1415
square(x: Float) Float {
return x ^ 2.0
}
}
areaOfCircle(radius: Float) Float {
return Math.pi * Math.square(radius)
}
There are still some kinks to iron out, but all in all, namespaces are useable for the most part, and pave the way for module support in the future.
Update to LLVM 14
Other then some minor code/test changes, everything is pretty much the same. You might be able to get away with using LLVM 13 for some things, but it is recommended that you use version 14.
100ms Compilation Speedup via LLVM JIT
In an effort to reduce build times, and reduce the dependency on a C compiler during build time, Skull will now JIT compile the shim code used for the initial startup of the compiled program. Originally the shim was written in C, and passed to the C compiler for each build. Now, a single LLVM IR shim is JIT compiled into the LLVM module right before emitting the code, greatly speeding up build times.
Optimize Dockerfiles
There are now slimmed down, production ready Skull dockerfiles! The old development dockerfiles are now suffixed with -dev
, and are only intended to be used by people actively doing development on the project.
Allow main
function exports
Since the C shim has been replaced with a JIT compiled version (and other reasons), the name main
can now safely be exported in Skull programs.
Release v0.8.0
It has been a while since the last release! A lot of refactoring and cleanup has happened to the LLVM backend, semantic analyzer, and AST generator, but some new features and niceties have been squeezed in as well:
Name Mangling
To allow for modules in the future, name mangling has been added for exported variables. This means that functions and variables using the export
keyword will not be able to communicate with C libraries (for the time being). I am looking into ways to allow for explicitly exporting with C naming conventions, but for now, the name mangling will remain the way it is.
Reference Types
You can now create C-like pointers using the new reference type:
num := 1234
ref := &i
ref2: &Int = &i
num2 := *ref
You can also have nested/double references, like so:
a := 1
b: &Int := &a
c: &&Int := &b
Skull Shared Library
Running make install-dev
will install the libskull.so
library, giving users more access to the Skull compiler and it's internals. Support for a CTypes Python API is also in the works, but is not high priority at the moment.
Docker Images
Docker images for Alpine, Archlinux, and Ubuntu have been added! Go to the packages page for more info.
Other Changes
- Add
--color
flag - Add redundant reassignment check back in
- Use LLVM API to emit object files instead of using external llc command (~40ms speedup)
Release v0.7.0
It has been a long time since the last release, and as such, a lot of progress has been made, including upgrades to the LLVM backend, a new C backend, new language features, and a lot of bug fixes. Let's begin!
Upgrade to LLVM 13
LLVM 13 is now required to build Skull. Previously it was using LLVM 10, which is widely supported, but has less features compared to the newer versions.
Fix order of operations
The expression AST parser has been rewritten to respect order of operations. Previously, expressions where evaluated right-to-left, and had no concept of operator precedence. Now, everything is evaluated left-to-right, and an operator precedence system (similar, but different to C) has been introduced.
Add new C backend
Skull pograms can now be compiled into C code, which can be compiled on (almost) any system. Simply use the --c-backend
flag to enable:
$ skull file.sk --c-backend
# this will output a file called ".file.sk.c", which can be changed with the -o flag
Add optimization flags for LLVM backend
The -O1
, -O2
, and -O3
flags (similar to GCC/Clang) has been added, which allows for optimizing Skull code using LLVM's vast suite of optimization passes:
$ cat tmp.sk
f(x: Int) Int {
if x is 0 {
return 0
}
return x + f(x - 1)
}
return f(3)
$ skull tmp.sk -E -O2
; ModuleID = 'tmp.sk'
source_filename = "tmp.sk"
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
define i64 @.tmp() local_unnamed_addr #0 {
entry:
ret i64 6
}
attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn }
Here, LLVM is smart enough to evaluate f(3)
, despite f
being a recursive function (it is tail-recursive, since the call to f
is at the end, but still very cool).
Add LLVM debug information
Debug info can now be turned on via the -g
flag, which adds line/column info to statements, functions, expressions, and if/elif/else/while blocks. Debug info is currently not available for the C backend.
Add break
and continue
statements
Both the C and LLVM backends now support the break
and continue
statements in while loops.
while true {
if true {
break
}
else {
continue
}
}
Add noop
statement
Since if/while/function blocks are no longer allowed to be empty, a new noop statement has been added to explicitly state that nothing should happen. It is similar to Python's pass
statement, and it basically does nothing.
# A dummy function
f() { noop }
f()
Add NaN
NaN
(not a number) is now a built-in floating point literal.
Lots of minor improvements
- Add
--help
and--version
long options - Add
--werror
flag to turn all warnings into errors - Emit error when output file is a directory
- Emit warning when file starts with BOM
- Emit warning when function is unused
- Emit warning when explicit types can be trivially deduced
- Emit warning if condition is always true/false
- Emit warning when variables should be const, or is unused
- Add ability to export constant variables
export pi := 3.1415
- Add COLOR environment variable to enable colored errors
- Allow for comments and unreachable statements after return
- Allow for long hex escapes
emoji := "\x1F480"
- Allow for booleans in
is
operator
x := true is false
Release v0.6.0
Features/changes in v0.6.0:
Make types uppercase
x: Int = 1
Allow for declaring main
function again
main() {
# ok
}
# error, cannot export main
export main() Int {
return 0
}
Lots and lots of operators
a := 1 isnt 1 # true
b := 10 mod 3 # 1
c := 1 < 2 # true
d := 1 <= 2 # true
e := 1 > 2 # false
f := 1 >= 2 # false
g := - 1 # -1
h := 2 ^ 3 # 8
i := 2.0 ^ 3.0 # 8.0
j := "this" is "that" # false
k := 0b11 << 2 # 0b1100
l := 0b1100 >> 2 # 0b11
m := (1 + 2) # 3
Underscore seperators in numerics
x := 0b1100_0101
y := 123_456.0
Unreachable statement
if false {
unreachable
}
Better errors
- Add
skull:
prefix to fatal errors - Prepend filename to compilation errors
Release v0.5.0
Features in v0.5.0:
Type aliases:
alias := int
x: alias = 1
and
, xor
, and or
boolean operators:
x := true and true
y := false xor true
z := true or false
is
operator:
x := 1 is 2
Allow for escaped quotes in strings and runes:
c := '\"'
s := "what\'s your name?"
Multi-parameter functions:
f(a: int, b: int) int {
return a + b
}
x := f(1, 2)
Else if statments:
if false {
# do something
}
elif true {
# do something else
}
Add line / column numbers for compiler errors:
$ cat file.sk
x := 1 + 2.0
$ skull file.sk
Compilation error: line 1 column 10: type mismatch: expected type "int"
Release v0.4.0
Lots has been added since the version 0.3.0 release, including while
, else
, block comments and functions!
Replace []
syntax with {}
and ()
if true {
func()
}
Native and external functions
# external function declaration
external puts(string: str) int
err := puts("hello world!")
# native function definition
func() {
# do something
}
func()
While statments
while true {
# do something
}
Else statements
if something {
# do something
}
else {
# do something else
}
Multi-line/block comments
#{
this is a block comment!
#}
Skull flags
$ skull main.sk -c -o main.o
Compiles
main.sk
into an object file calledmain.o
.
$ skull main.sk -S
Output assembler for
main.sk
.
$ skull main.sk -E
...
Outputs LLVM IR from
main.sk
to stdout.
Skull header file
C/C++ programs can now include headers for Skull types:
#include <skull/Skull.h>
SkullInt add_one(SkullInt num) {
return num + 1;
}
New escape sequences
# \0 null terminator
c_str := "hello world\0"
# \e escape shorthand
color := "\e[32;1Bright Green"
Other notable features/bugfixes:
main
implicitly returns0
.- Variables can be used on the left/right hand side of operations (add, subtract, etc).
- Error when explicitly dividing by zero.
- Error on redundant reassignment of variable (
x = x
). - Error on unreachable code after
return
.
Release v0.3.0
Since the v0.2.1
release, significant progress has been made! Before, skullc
was a standalone program. In this release, skullc
has been renamed to just skull
, and the old REPL system has been phased out. All the code has been converted to its LLVM equivalent. Here is a short list of all of the note-worthy features added:
Addition, subtraction, division, and multiplication of int and float constants.
add := 1 + 2
sub := 2.5 - 1.0
div := 10 / 2
mul := 2 * 4
Allow for compiling and running C code from Skull
$ cat main.sk
external func
func[]
$ skull main.sk -- libfunc.o
$ ./main
Allow for fine-grain control of CC arguments via --
$ skull main.sk -- -O3 -o something
$ ./something
Escape sequences in strings and runes
hello := "hello\r\nworld!"
hex := '\x1b'
Reassigning of mutable variables
mut x := 0
x = 1234
If statements
if true [
return 1
]
x := false
if x [
z := 1 + 2
return z
]
Compiler errors
$ cat bad.sk
this code wont compile
$ skull bad.sk
Compilation error: unexpected token: "this"
Fix v0.2.0
Version 0.2.0 did not update SKULL_VERSION
in the config.mk
file, this version fixes that (and bumps the minor version).
The Skull Compiler
Since last release, the skullc
Skull Compiler has been created. It is still in a very experimental state, but usable enough to constitue a release.
In the future, skullc
will just become skull
, and the existing REPL system will be phased out. For now, while things are being shifted over, they will remain seperate.
Getting up and running with Skull is very easy:
$ sudo make install
$ echo "return 0" > main.sk
$ skullc main.sk
$ ./main
Give it a try!