Pryst (spoken as ˈprɪst) is a static-typed language with a beautiful C-like syntax.
It features variables, types, conditionals, loops, arrays and more!
Most of all, Pryst is currently in development
, so there will be new features!
int main(str argv[])
{
if (argv.len > 1) {
print("Hello" + argv[1]);
}
else {
print("Hello!");
}
}
- Build from Source
- Usage
- Variables
- Data Types
- Operators
- Functions
- Conditionals
- Loops
- Packages
- Imports
- Comments
- Package Manager
- Standard Library
- TODO
In order to build Pryst properly, you need to install GraalVM and Maven.
Go to GraalVM Github Package Download Link and install the proper GraalVM release matching your JDK version.
After you download GraalVM, follow the instructions by GraalVM Docs
Follow the instructions made by Baeldung
git clone https://github.com/jitcijk/pryst.git
cd pryst
mvn package
To run a Pryst source file on top of JVM, give it a relative/absolute path to the file.
./pryst /path/to/your/pryst/code.pr (It's extension name is .pr)
To run with native build:
./native/prystnative /path/to/your/pryst/code.pr
Variable names have to start with an alphabetic character and continue either with alphanumeric, underscores. For example:
int x; // OK
float var_whatever; // OK
bool _isClicked; // OK
str 3numbers[3]; // NO
Unsigned long integer variables in Pryst start with the keyword int
.
int age = 40;
age = 41;
Double precision floating-point variables in Pryst start with the keyword float
.
float height = 183.82;
height = 177.13;
Boolean variables in Pryst start with the keyword bool
.
bool x = true;
x = false;
if (x) {
print("x is true!");
}
else {
print("x is false!");
}
In Pryst, true | false
isn't 1 | 0
.
Instead, true
and false
is a singleton object.
More info: null
uses the same philosophy.
String variables in Pryst start with the keyword str
.
str myString = "Hello";
print(myString);
Static size arrays in Pryst look like this: type_name[arr_size]
.
str strArray[3] = {"Jack", "The", "Pillow"};
println(strArray[1][1]); // It basically means the second character of the second elem of the string array.
// It prints "h"
str[3][4] str_3by4_elems = {{"A", "B", "C", "D"}, {"E", "F", "G", "H"}, {"I", "J", "K", "L"}, {"M", "N", "O", "P"}};
print(str_4by4_elems[2][1]);
// It prints "J"
In Pryst, type conversion is kinda-explicit.
For example,
int x = 3;
float y = x; // OK
print("Hello" + x); // NO
print("Hello" + x.toStr()); // OK
bool z = true;
int w = x + z; // NO
Pryst currently supports 5 primitive data types: int
, float
, bool
, str
, array
.
Integers are whole numbers that support most of the arithmetic and bitwise operators, as you'll see later. They can be represented also as: binary with the 0b prefix, hexadecimal with the 0x prefix and octal with the 0o prefix.
int dec = 27
int oct = 0o33
int hex = 0x1B
int bin = 0b11011
int arch = 2 ** 32
Floating point numbers are used in a very similar way to Integers. In fact, they can be mixed and matched, like 3 + 0.2
or 5.0 + 2
, where the result will always be a Float.
float pi = 3.14159265;
float e = 2.71828182;
Scientific notation is also supported via the e
modifier:
float sci = 0.1e3;
float negsci = 25e-5;
It would be strange if this data type included anything else except true
and false
.
bool mad = true;
bool genius = false;
Expressions like the if/else
, won't check for values that are not necessarily boolean.
Strings are UTF-8 encoded, meaning that you can stuff in there anything, even emojis.
str weather = "Hot";
str price = "500円";
String concatenation is handled with the +
operator. Concatenation between a string and another data type will throw a compile-time error.
str name = "Tony" + " " + "Stark";
Additionally, strings are treated as enumerables. They support subscripting and iteration in for in
loops.
str me = "howdy"[2]; // "w"
Escape sequences are there too if you need them: \"
, \n
, \t
, \r
, \a
, \b
, \f
and \v
. Nothing changes from other languages, so I'm sure you can figure out by yourself what every one of them does.
str code = "if(name == \"ben\"){\n\tprint(10);\n};";
Arrays are ordered collections of a specific data type. You can't mix and match strings with integers, or floats with other arrays.
str names[] = ["John", "Ben"];
str john = names[0];
Individual array elements can be accessed via subscripting with a 0-based index:
str names[] = ["Kirk", "Bones", "Spock"];
str first = names[0]; // "Kirk"
str last = names[-1]; // "Spock"
In the same style, an index can be used to check if it exists. It will return null
if it doesn't:
if(names[10].exists())
// handle it
Individual elements can be reassigned on mutable arrays:
int numbers[] = [5, 8, 10, 15];
numbers[1] = 7;
Arrays can be compared with the ==
and !=
operators, which will check the position and value of every element of both arrays. Equal arrays should have the same exact values in the same position.
They can also be combined with the +
operator, which adds the element of the right side to the array on the left side.
str concat[] = ["an", "array"] + ["and", "another"]
// ["an", "array", "and", "another"]
+
, -
, *
, /
, %
, **
a++
means to invoke the statement then increment a
.
a--
means to invoke the statement then decrement a
.
++a
means to increment a
and then invoke the statement.
--a
means to decrement a
and then invoke the statement.
~
is the bitwise NOT operator.
&
is the bitwise AND operator.
|
is the bitwise OR operator.
^
is the bitwise XOR operator.
a += b
is equivalent to a = a + b
a -= b
is equivalent to a = a - b
a *= b
is equivalent to a = a * b
a /= b
is equivalent to a = a / b
a %= b
is equivalent to a = a % b
a &= b
is equivalent to a = a & b
a |= b
is equivalent to a = a | b
a ^= b
is equivalent to a = a ^ b
a **= b
is equivalent to a = a ** b
Pryst treats functions as functions, not as first class citizens.
int x() {
println("Hello");
}
Parentheses are optional and for simple functions like the above, I'd omit them. Calling the function needs the parentheses though:
x();
Pryst is static-typing, so type hinting is its own reward.
TODO
In Pryst, a return statement uses the keyword: return
.
You already know how to use the return statement, right?
return x;
TODO
Hmm... Should we?
Recursive functions calculate results by calling themselves. Although loops are probably easier to mentally visualize, recursion provides for some highly expressive and clean code. Technically, they build an intermediate stack and rewind it with the correct values in place when a finishing, non-recursive result is met. It's easier to understand them if you think of how they're executed. Let's see the classic factorial example:
int fac(int n) {
if(n == 0)
return 1;
return n * fac(n - 1);
}
Keep in mind that Pryst doesn't provide tail call optimization. That would allow for more memory efficient recursion, especially when creating large stacks.
Pryst provides two types of conditional statements. The if/else
and the switch
statement.
An if/else
block looks pretty familiar:
if(1 == 2)
println("Not calling me.");
else
println("1 isn't equal to 2. Duh!");
The ternary operator ?:
is a short-hand if/else
, mostly useful when declaring variables based on a condition or when passing function parameters. It's behaviour is exactly as that of an if/else
.
int price = 100;
int offer = 120;
str status = offer > price ? "sold" : "bidding";
Although multiple ternary operators can be nested, I wouldn't say that would be the most readable code. Actually, except for simple checks, it generally makes for unreadable code.
Switch
expressions on the other hand are way more interesting. They can have multiple cases with multiple conditions
that break automatically on each successful case, act as generic if/else, and match array elements.
int a = 5;
switch (a) {
case 2, 3:
println("Is it 2 or 3?");
case 5:
println("It is 5. Magic!");
default:
println("No idea, sorry.");
}
Everybody knows what a For Loop is, right?
Without arguments, the for
loop can behave as an infinite loop, much like a traditional while
.
Although there's not too many usecases, it does its job when needed. An example would be prompting the user for input
and only breaking the infinite loop on a specific text.
for( ; ; ;) {
str pass = prompt("Enter the password: ");
if(pass == "123") {
println("Good, strong password!");
break;
}
}
The break
and continue
keywords, well break or skip the iteration. They function exactly like you're used to.
In Pryst, a While Loop works as you expected.
int i = 10, j = 7;
while (i > j) {
j++;
}
Nothing ground breaking in here. You can write either single line or multi line comments:
// an inline comment
/*
I'm spanning multiple
lines.
*/
Pryst's package manager name is grape
.
TODO: For example, grape install time
TODO: The Standard Library is fully written in Pryst.
- Add
Object
type - Add support for
Class
- Inheritance, Abstraction
- Try to make a function as an object. (With static-typing)
- Implement Packages
- Implement Imports
- Create a Package Manager.
- Make a Standard Library.
And more!
Pryst was developed by cliid
, a Junior Developer from South Korea.
PRYST
: Pryst Runs Yet Stable and Translucent
.
Pryst is published in the MIT License
.