Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ######################################################
- import "std/io" use std:io
- # This is a comment!
- func main() -> i32
- {
- # Display the text 'Hello, World!'
- println("Hello, World!");
- # Exit the program with a status code of 0
- ret 0;
- }
- ######################################################
- import "std/io" use std:io
- func main(char[&][&] args) -> i32
- {
- # In Degu, array references implicitly include their length (this is why they are not referred to as 'pointers')
- # C-style loops are extremely powerful, so Degu uses them too.
- for (i32 i = 0; i < args.len; i ++)
- println("Arg {0} is {1}.", i, args[i]);
- println("There are {0} arguments.", args.len);
- ret 0;
- }
- ######################################################
- import "std/io"
- func factorial(i32 x) -> i32
- {
- if (x > 1)
- ret factorial(x - 1) * x; # Recursive function call
- else
- ret 1;
- }
- func main() -> i32
- {
- for (i32 i = 1; i <= 8; i ++)
- std:io:println("{0}! = {1}", i, factorial(i));
- ret 0;
- }
- ######################################################
- type vec2 { f32 x, f32 y };
- func main()
- {
- # If an instance of a type is initialised without construction, all primitive types within it are implicitly set to '0' (or whatever the equivalent is for that type)
- # i32 default: 0
- # f32 default: 0.0
- # void& default: 0x0
- # void[&] default: start = 0x0, length = 0
- # i32[n] default: { 0, 0, 0, ... }
- vec2 v;
- }
- ######################################################
- import "std/io" use std:io
- import "std/str" use std:str
- type PhonePair { str name, str number };
- func main()
- {
- # Arrays can be declared with a C-style brace initializer. When using this method, the length of the array can be inferred at compile-time.
- PhonePair[?] phonebook = {
- { .name = "Alice", .number = "07345 123456" }, # C-style brace initializers exist for types too!
- { .name = "Bob", .number = "07873 248163" },
- { .name = "Charlie", .number = "07123 654321" },
- };
- for (usize i = 0; i < phonebook.len; i ++)
- println("{0} can be called on {1}", phonebook[i].name, phonebook[i].number);
- }
- ######################################################
- import "std/io" use std:io
- # Because 'ptr' is an array reference, we can pass arrays of any size
- # If ptr was declared as 'char[?]', the compiler would produce an error since the size of the value array can not be inferred at compile-time.
- func print_arr(char[&] ptr)
- {
- println("The char array reference points to '{0}'.", ptr);
- }
- func main()
- {
- # Here, we use compile-time size inference
- char[?] arr = "The Octodon genus of the Degu is native to South America";
- # This is an array reference. The length of the array is implicitly an attribute of the reference, and is known only at run-time
- char[&] ptr = arr&;
- # We can print a char array
- println("The char array is '{0}'.", arr);
- # We can print a char array reference
- println("The char array reference points to '{0}'.", ptr);
- # Array pointers can be passed to functions
- print_arr(arr);
- }
- ######################################################
- import "std/io" use std:io
- import "std/str" use std:str
- import "std/array" use std:array
- func main()
- {
- # The standard library contains many useful types that manage memory automatically. 'str' types contain heap-allocated representations of character arrays
- str text = str("Hello! These are some words.");
- # 'array' contains a heap-allocated array of items. This is necessary, since the number of items cannot be determined at compile-time.
- array<str> words = text.split(' ');
- for (usize i = 0; i < words.len; i ++)
- {
- # Degu does not support operator overloading. To access items in an array type, one must use 'myarray.items[n]'
- println("Word {0} is {1}", i, words.items[i]);
- }
- # 'str' types automatically free their internal memory when they go out of scope
- str input = readln("How many times? ");
- u32 times = input.u32(); # Parse the input string into an i32
- i32 a, b = 0, 1; # Shortcut declaration and assignment can be used for multiple variables of the same type
- for (u32 i = 0; i < times; i ++)
- {
- # In Degu, sequence points only occur at the start and end of a statement. Therefore, swapping can occur without the use of a temporary variable.
- a, b = b, a;
- b += a;
- println("fibonnaci({0}) = {1}", i, a);
- }
- }
- ######################################################
- # Degu supports generic programming
- func print<type T>(T obj)
- {
- # The compiler intuitively understands types, and so can infer a human-readable name for the type
- println("Object of type {0} is {1}", typename(T), obj);
- }
- # Degu's generic programming also supports primitive generics
- func factorial<u32 X>() -> u32
- {
- if (X > 1)
- ret factorial<X - 1>();
- else
- ret 1;
- }
- # Since the compiler has all the information it needs, it will evaluate this expression at compile-time, thereby reducing run-time overhead
- # Function calls that are not pre-computable at compile-time are not permitted as global variable initializers (TODO: Define 'pre-computable')
- u32 fac_10 = factorial<10>();
- # Degu's generic programming extends to types
- type tuple<type T, type U> { T first, U second };
- # Degu even supports variadic generic programming
- func print_objects<type... A>(A arg...)
- {
- # Statements tailed with '...' are expanded for each variadic argument
- print(arg);...
- # The same applies for code blocks...
- {
- if (arg > 0)
- print(arg);
- }...
- # ...and also parameters
- do_nothing(arg...);
- }
- # Degu's variadic generics can be limited to a specific number of additional arguments
- type maximum_of_5<type...5 A>(A arg...)
- {
- do_nothing(arg...);
- }
- ######################################################
- type vec3 { f32 x, f32 y };
- # In Degu, methods are defined outside of types to avoid the complexity problems that usually accompany OOP. They use the 'impl' keyword
- impl vec3.add(vec3 v)
- {
- # The 'this' keyword is used to refer to the current instance
- # Shortcut operations on multiple variables can be used
- this.x, this.y += v.x, v.y;
- }
- # In Degu, the following is illegal: Methods cannot modify data pointed to by any arguments. However, they can modify global variables (although this is discouraged)
- # For an object to be modified by a method, it must be passed by value (although the compiler may implicitly decide to pass by reference if the method does not modify the value of the object)
- impl vec3.copy_to(vec3& v)
- {
- v@.x, v@.y = this.x, this.y;
- }
- ######################################################
- # Degu namespaces are declared with the 'name' keyword
- name my_namespace
- {
- type my_type { i32 a, i32 b };
- # Pointers to void may exist. However, pointer arithmetic is illegal
- # Pointers may not be initialised with integers directly (since doing so is dangerous). A typecast must be explicitly used first
- # To perform a typecast, a value must be surrounded with brackets and the '~>' operator used
- void& ptr = (0xC0000000 ~> void&);
- }
- ######################################################
- import "std/mem" use std:mem
- # In Degu, certain method names are reserved for special purposes
- # These names are 'create', 'destroy', 'move' and 'copy'
- type IntArray { i32[&] items };
- # 'create' can be called without an instance of the type being created first, and is usually used as a constructor
- impl IntArray.create(usize len)
- {
- this.items = new_array<i32>(len);
- }
- # 'move' is implicitly called when an instance is initialised by transferring the contents of another instance. It can also be used as a way of enabling typecasting instances of different types
- impl IntArray.move(IntArray& other)
- {
- this.items = other@.items;
- }
- # 'copy' is implicitly called when an instance is initialised by copying the contents of another instance. Like 'move', it can also be used as a way of enabling typecasting between different types
- impl IntArray.copy(IntArray& other)
- {
- this.items = copy_array<i32>(other@.items);
- }
- # 'destroy' is implicitly called whenever the instance goes out of scope without first being implicitly copied and is used as a way of clearing up any memory that may be owned by an object. It cannot be called explicitly
- impl IntArray.destroy()
- {
- delete_array<i32>(this.items);
- }
- func main()
- {
- IntArray arr = IntArray.create(5);
- arr.items[0] = 1;
- arr.items[1] = 2;
- arr.items[2] = 4;
- arr.items[3] = 8;
- arr.items[4] = 16;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement