Introduction
Basics of Dragonstone
This is a quick overview into some of the features of Dragonstone, for these examples, we'll be using the interpreter to run our code.
Hello World
The first thing you need to learn in any programming language is normally the Hello World! program. In Dragonstone this is pretty simple:
1 echo "Hello World!"
2
# OUTPUT: Hello World!
The entire program consists of a call to the method echo with the
string Hello World! as an argument. This method prints the string
to the standard output. All code in the top-level scope is part of the main
program, so in this example there is no need for an explicit main function
as the entry point to the program. These kinds of variables are called local variables.
Dragonstone print statements automatically add a line break after each call to echo, but also supports printing without a line break using eecho:
1 eecho "Hello"
2 eecho " World!"
3
# OUTPUT: Hello World!
For print statements you can also use 2 variations of debug prints, e! and ee!, which prints the full expression.
The only difference between the 2 is that e! adds a line break at the end, while ee! does not:
1 e! "Hello World!"
2 ee! "Hello"
3 ee! " World!"
4
# OUTPUT: "Hello World!" # -> "Hello World!"
# "Hello" + " World!" # -> "Hello" + " World!"
Paired with typeof (shown later) this can be powerful for debugging.
Comments
Single Line Comments start with a #.
1 # Single Line Comment
2
Single Line Trailing Comments start with a # on the same line.
1 echo "Hello World!" # Trailing Comment
2
Multi-Line Comments start with a #[` and end with a `]#, they can also be nested.
1 #[
2 This is a Multi-Line Comment.
3 ]#
4
Nested Multi-Line Comment.
1 #[
2 #[
3 This is a Nested Multi-Line Comment.
4 ]#
5 ]#
This can also be inline.
1 #[ Inside. ]# numbers = 10 #[ Outside. ]#
2
Variables
To store a value and so it can be re-used later, it can be assigned to a variable.
For example, if you want to say Hello! three times, you don't need to repeat the same string multiple times. Instead, you can assign it to a variable and re-use it:
1 message = "Hello!"
2 echo message
3 echo message
4 echo message
5
This program prints the string Hello! three times to the
standard output, each followed by a line break. The name of a
variable always starts with a lowercase ascii or unicode letter
(or underscores) and can otherwise consist of alphanumeric
characters (or underscores). As a typical convention in
programming, uppercase letters are avoided and names are written
in snake_case, but there is no explicit rules within
Dragonstone preventing you from using uppercase.
Type of a Variable
The type of a variable is automatically inferred. In the above example, it's String. You can verify this with typeof:
1 message = "Hello Jules!"
2
3 echo typeof(message)
4
Variable Expression
The e! is similar to echo as it prints the value to the standard
output, but it also prints the full expression. It's a useful
tool for debugging:
1 message = "Hello Jules!"
2
3 e! typeof(message)
4
Reassigning a Value
A variable can be reassigned with a different value:
1 message = "Hello Jules!"
2
3 echo message
4
5 message = "Hello Ringo!"
6
7 echo message
8
This also works with values of different types. The type of the variable changes when a value of a different type is assigned.
1 message = "Hello Jules!"
2
3 e! message, typeof(message)
4
5 message = 50
6
7 e! message, typeof(message)
8
Strings
A string, which is just a set of ascii or unicode characters, and by default
are UTF-8 (this needed to be done to support unicode), all you need to do is
enclose them in double quotes " ". But, note that strings are immutable, any
changes to that string will change its output later.
1 message = "Hello!"
2 echo message
3
# OUTPUT: Hello!
Interpolation
String interpolation is a method in which you combine strings, this is done inside
double quotes " " and using #{...}. Here's an example:
1 name = "V"
2 echo "Hello, my name is #{name}"
3
# OUTPUT: Hello, my name is V
This also works with any type of variable, so it doesn't need to be a string only.
1 number = "100"
2 echo "Your grade is #{number}%"
3
# OUTPUT: Your grade is 100%
Concatenation
An alternative to interpolation, or if you need to group multiple strings together
you can use concatenation by adding strings with the + like this
example:
1 name = "V"
2 echo "Hi, my name is " + name + "!"
3
# OUTPUT: Hi, my name is V!
Escaping
Sometimes you might find trouble writing some characters in literals. Something like
a double quote " " if used inside a string, would either throw an error
or cause certain parts of you program to not run. The workaround for this in
programming is by escaping. If a double quote is preceded by a backslash \ it will be used as an escape and both characters together will output correctly.
1 echo "I said: \"Hi\""
2
# OUTPUT: I said: "Hi"
Dragonstone has multiple types of escapes that won't print such as a line break \n, tabulator \t, and double backslash \\.
Here is the current list, with more coming soon:
Slash = /\//
Backslash = /\\/
Backspace = /\b/
Tabulator = /\f/
New Line = /\n/
Return = /\r/
Tab = /\t/
Vertical Tab = /\v/
Unicode
A Unicode is an international standard for text in many different writing systems. This includes not just the latin alphabet used in English, but also includes the characters of many others. The Unicode standard also includes things like emojis and icons.
1 echo "I ❤️ U!"
2
# OUTPUT: I ❤️ U!
As usual with most programming languages you can use the unicode directly, however
some characters or emojis may not be supported on all fonts or editors. Some don't
even output and you may end up with a blank space. To use the unicode directly you
have to use the \ followed by the u codepoint and then in
curly brackets {...} the hexadecimal of the emoji you wish to use,
here's an example:
1 echo "This is \u{1F525}"
2
# OUTPUT: This is 🔥
String Manipulation
Dragonstone also allows you to manipulate a string, so if you want to change how a string looks you can convert it using some of the methods it provides, with more coming soon:
1 msg = "Hello World!"
2 echo "standard: #{msg}"
3 echo "upcased: #{msg.upcase}"
4 echo "downcased: #{msg.downcase}"
5 echo "reversed: #{msg.reverse}"
6
# OUTPUT: standard: Hello World!
# upcased: HELLO WORLD!
# downcased: hello world!
# reversed: !dlroW olleH
Other String Types
There's also support for some other detailed information about strings.
We can check the number of characters a string contains:
1 msg = "Hello World!"
2 e! msg.size
3
# OUTPUT: msg.size # -> 12
Without e!:
1 msg = "Hello World!"
2 echo msg.size
3
# OUTPUT: 12
Or a simpler method with the Standard Library:
1 use "strings_length"
2
3 e! strings.length("Test")
4
# OUTPUT: strings.length("Test") # -> 4
Without e!:
1 use "strings_length"
2
3 echo strings.length("Test")
4
# OUTPUT: 4
Numbers
Now, with Dragonstone has quite a few ways to deal
with Data, for our introduction we're going to work
on numbers. There are 2 ways to deal with numbers: int (Integer) and float (Float). You can also be optionally explicit even
more by specifying int32, int64, float32, and float64.
1 e! typeof(1)
2 e! typeof(1.5)
3
# OUTPUT: typeof(1) # -> "Integer"
# typeof(1.5) # -> "Float"
Float values print with a decimal point whereas Integer values don't.
Arithmetic
Equality and Comparison
If two numbers have the same value, the == operator says they are equal, no matter what type they are.
1 e! 1 == 1
2 e! 1 == 2
3 e! 1.5 == 1
4 e! -2.0 == -2
5
# OUTPUT: 1 == 1 # -> true
# 1 == 2 # -> false
# 1.5 == 1 # -> false
# -2.0 == -2 # -> true
In addition to the equality operator, there are comparison operators that check how two values relate to each other. Like equality, comparisons work the same way no matter the type.
1 e! 2 > 1
2 e! 1 >= 1
3 e! 1 < 2
4 e! 1 <= 2
5
# OUTPUT: 2 > 1 # -> true
# 1 >= 1 # -> true
# 1 < 2 # -> true
# 1 <= 2 # -> true
The <=> operator, called the spaceship operator
because of how it looks, compares two values. It returns 0 if
they are equal, a positive number if the first is larger, or
a negative number if the second is larger. It acts like all
the other comparison operators combined.
1 e! 1 <=> 1
2 e! 2 <=> 1
3 e! 1 <=> 2
4 e! 5.5 <=> 5
5
# OUTPUT: 1 <=> 1 # -> 0
# 2 <=> 1 # -> 1
# 1 <=> 2 # -> -1
# 5.5 <=> 5 # -> 1
Operators
You can do basic math using operators. Most of them take two values
and are written between those values, like a + b. Some
only need one value and are written before it, like -a.
The expression’s value is the result of that operation.
1 e! 1 + 1 # addition
2 e! 1 - 1 # subtraction
3 e! 2 * 3 # multiplication
4 e! 2 ** 4 # exponentiation
5 e! 6 / 2 # division
6 e! 2 // 3 # floor division
7 e! 7 % 3 # modulus
8 e! -1 # negation
9 e! +1 # unary plus
10
# OUTPUT: 1 + 1 # -> 2
# 1 - 1 # -> 0
# 2 * 3 # -> 6
# 2 ** 4 # -> 16.0
# 6 / 2 # -> 3.0
# 2 // 3 # -> 0
# 7 % 3 # -> 1
# -1 # -> -1
# +1 # -> 1
Most math operations with integers give another integer as the
result. The division operator / is an exception
because it always gives a float. The floor division operator // gives an integer result, but rounded down to
the nearest whole number. When you mix integers and floats in
an operation, the result is always a float. In other cases,
the result usually has the same type as the first value.
Here's a full list of the supported operators in Dragonstone:
# Unary
# + positive +1
# &+ wrapping positive &+1
# - negative -1
# &- wrapping negative &-1
# ! inversion !true
# ~ binary complement ~1
#
# Binary
# & binary AND 1 & 2
# | binary OR 1 | 2
# ^ binary XOR 1 ^ 2
#
# Shifts
# << shift left, append 1 << 2
# >> shift right 1 >> 2
#
# Equality
# == equal 1 == 2
# != not equal 1 != 2
#
# Inequalities
# < less 1 < 2
# <= less or equal 1 <= 2
# > greater 1 > 2
# >= greater or equal 1 >= 2
# <=> three-way comparison 1 <=> 2
#
# Addition
# + addition 1 + 2
# &+ wrapping addition 1 &+ 2
#
# Subtraction
# - subtraction 1 - 2
# &- wrapping subtraction 1 &- 2
#
# Multiplication
# * multiplication 1 * 2
# &* wrapping multiplication 1 &* 2
#
# Exponent
# ** exponentiation 1 ** 2
# &** wrapping exponentiation 1 &** 2
#
# Division
# / division 1 / 2
# // floor division 1 // 2
#
# Modulus (find the remainder of division)
# % modulus 1 % 2
#
# Subsumption
# === case subsumption "foo" === 5
#
# Logical
# && logical AND true && false
# || logical OR true || false
#
# Range
# .. inclusive range 1..10
# ... exclusive range 1...10
#
# Assignments
# = variable assignment a = 1
#
Precedence
When an expression uses several operators, the question is which one is applied first. In math, for example, multiplication and division are done before addition and subtraction, and Dragonstone follows the same precedence rules for its operators.
1 e! 7 + 5 * 3
2 e! (3 + 4) * 2
3
# OUTPUT: 7 + 5 * 3 # -> 22
# 3 + 4 * 2 # -> 14
Here's a full list of the operator precedence:
# Unary +, &+, -, &-, !, ~
#
# Exponential **, &**
#
# Multiplicative *, &*, /, //, %
#
# Additive +, &+, -, &-
#
# Shift <<, >>
#
# Binary AND &
#
# Binary OR/XOR |,^
#
# Equality and Subsumption ==, !=, ===
#
# Comparison <, <=, >, >=, <=>
#
# Logical AND &&
#
# Logical OR ||
#
# Range .., ...
#
# Assignment =, []=, +=, &+=, -=, &-=,
# *=, &*=, /=, //=, %=, |=,
# &=, ^=, **=, <<=, >>=, ||=,
# &&=
#