Jane by Example
Jane is a programming language focused on keeping the balance between small utility scripting and large projects.
Jane by Example (as sneakily copied from Rust by Example) is a collection of examples for the Jane language and its uses, including some libraries.
- Hello World - Start with a traditional Hello World program.
Hello World
This is the traditional Hello World program for Jane:
file class Program; // A file statement configures the file
// file class defines the containing class of a program, so you don't have to wrap everything in class Program { ... }
// This is in fact a comment, as standard in many languages it starts with a double slash
// Compiler ignores everything in a line after a double slash
// Woah! A main function! This is where everything gets executed in an executable
// -s means it's static, thus doesn't need an instance to be called
fn -s Main() -> i32 {
Jane.Tty.WriteLn("Hello World!");
}
Alternatively for single script files the main function and wrapping class can be omitted:
Tty.WriteLn("Hello World!");
Tty represents the Console (Tty stands for Teletypewriter). The Tty object can receive the WriteLn call, which draws the supplied string on the Standard output and appends a newline.
To compile you will need the jane compiler
$ shjc hello.jn
makes hello
/ hello.exe
$ ./hello
Hello World!
Comments
If you want to be tidy you can have comments they're awesome
if you don't still use them other people (and your future self) will look at your code and start praying
We have multiple comments even:
// Line comment
/* Block/Multiline comment */
//: Param/Documentation comment
Print & Formatted print
Printing is done by streaming text to the Console. There are different methods on the Tty Class to do so:
Tty.WriteLn(str)
: Writes a string and appends a newline characterTty.Write(str)
: Writes a string and doesn't append a newline character (stdout).Tty.WriteErrorLn(str)
: same but to stderrTty.WriteError(str)
: you already know what this does
You can add color to your strings by using the utils in the Jane.Text.ANSIStyling class:
file use -s Jane.Text.ANSIStyling; // Makes override and extension methods available in the file
// -s means it's a static member, ANSIStyling is a class that provides static methods
let x: i32 = 4;
Tty.WriteLn("${x} + 4 = ${x + 4}".ANSIRed().ANSIItalic()); // This prints red and italic text to the console!
Tty.WriteLn(ANSIBlue("This is blue")); // This works too
Tty.WriteLn("This is green, bold, italic and has a white background"::(ANSIRed ANSIItalic ANSIBold ANSIBGWhite));
// Using the turbopufferfish chainer you can call multiple methods with the same return and input types a bit prettier imo and its like 4 characters shorter idk
Strings can be formatted by default, if you don't want that, use the raw""
string literal, or escape the dollar sign with a backslash
// Curly braces include evaluatable code, whose value will be converted to string if necessary
let day_number: i32 = 31;
Tty.WriteLn("${day_number} days");
// Using the same argument twice can be accomplished by using double brackets:
Tty.WriteLn("${"Alice"}, this is ${"Bob"}. ${{1}}, this is ${{0}}");
// And you can specify them after too:
Tty.WriteLn("${subject} ${verb} ${object}"{
subject "the quick brown fox"
verb "jumps over"
object "the lazy dog"
});
// Other than strings, numbers for example can be formatted too using a format string or just the radix:
Tty.WriteLn("Base 10: ${69420}"); // 69420
Tty.WriteLn("Base 2 (binary): ${69420.f(2)}); // 10000111100101100
Tty.WriteLn("Base 8 (octal): ${69420.f(8)}"); // 207454
Tty.WriteLn("Base 16 (hexadecimal): ${69420.f(16)}"); // 10f2c, standard is lowercase
Tty.WriteLn("Base 16 (hexadecimal, uppercase): ${69420.f(16).upper()}"); // 10F2C, if you need your hexadecimals uppercase use the inbuilt `str.upper()` function
Tty.WriteLn("Pad Start, clip to 2 decimal places: ${Math.Pi.f("000.00")}")
format string follows this pattern
See also
Primitives
The primitives in the Jane language include:
- Numbers:
- Integers:
- Signed:
- i8 (alias sbyte)
- i16 (alias short)
- i32 (alias int)
- i64 (alias long)
- i128 (alias reallylong)
- Unsigned:
- u8 (alias byte)
- u16 (alias ushort)
- u32 (alias uint)
- u64 (alias ulong)
- u128
- Signed:
- Floating Point Numbers:
- f32 (alias float, single)
- f64 (alias double)
- Integers:
- chr (character)
- str (string)
- bool (boolean)
- abyss (aliases: void, null, undefined, nil)
These primitives are passed by value.
Compound types
Compound types are comprised of the previously mentioned ones:
Tuples: (T1 T2 T3) Arrays: [T1 T1 T1]
Tuples are value-types, arrays are reference-types.
Declaration
// inferred types:
let counter = 0 // declares an i32 and sets it to 0
let text = "hello" // declares a str and sets it to "hello"
let pi = 'π' // declares a chr and sets it to π
// suffix notation:
let i = 76u64
let j = -6i8
// no inferring
let k: i32
let l: str
let m: T // generally
// abyssable
let n: str?
if n? {
// Amazing abyss check
}
else {
// :(
}
more on abyssables: Abyssable
Literals and operators
Integers 1
, floating-Point numbers 1.2
, characters 'a'
, strings "abc"
, booleans true
and the nulltype abyss
can be expressed using literals.
Integers can also be expressed using octal, binary or hexadecimal 0x00
, 0o00
, 0b00
.
Numeric literals can directly be typed using the suffixes i<number of bits>
, u<number of bits>
or f<number of bits>
.
Operators and upcasting are similar to other C-likes, with the addition of the power operator ^
.
Tty.WriteLn("1 + 2 = ${1u32 + 2}")
Tty.WriteLn("1 - 2 = ${1i32 - 2}")
Tty.WriteLn("true AND false is ${true && false}")
Tty.WriteLn("true OR false is ${true || false}")
Tty.WriteLn("NOT true is ${!true}")
Tty.WriteLn("0011 AND 0101 is ${0b0011 & 0b0101}")
Tty.WriteLn("0011 OR 0101 is ${0b0011 | 0b0101}")
Tty.WriteLn("0011 XOR 0101 is ${0b0011 xor 0b0101}")
Tty.WriteLn("1 << 5 is ${1 << 5}")
Tty.WriteLn("0x80 >> 2 is {0x80 >> 2}")