├── .gitignore ├── README.md ├── basic_types ├── basic_types.md ├── booleans.vale ├── int_functions.vale └── int_operations.vale ├── branching_and_looping ├── branching_and_looping.md ├── fizzbuzz.vale ├── if.vale ├── if_expression.vale └── while.vale ├── compile_and_run.bat ├── compile_and_run.sh ├── data_structures ├── arrays.vale ├── data_structures.md ├── lists.vale └── tuples.vale ├── ffi_c - Shortcut.lnk ├── ffi_c ├── calling_c.md ├── extern.vale ├── externstrlen.c ├── externstrlen.vale ├── mutstructtoc.c ├── mutstructtoc.vale ├── readInt.c ├── readInt.vale ├── structtoc.c ├── structtoc.vale ├── triple.c └── triple.vale ├── functions ├── functions.md ├── functions_lambdas.vale ├── lambdas_param.vale ├── overloads.vale └── recursion.vale ├── games ├── games.md └── roguelike.vale ├── generics ├── generic_structs.vale ├── generics.md └── using_generics.vale ├── getting_input ├── cmd_args.vale ├── getting_input.md └── keyboard_input.vale ├── hello_world.vale ├── images └── logo.png ├── interfaces ├── interfaces.md ├── open_interfaces.vale └── using_interfaces.vale ├── miscellaneous ├── main_ret.vale ├── miscellaneous.md ├── panic.vale ├── unreachable.vale └── vassert.vale ├── patterns ├── destructuring.vale ├── patterns.md └── tuple_destructuring.vale ├── programming_idioms ├── pi1.vale ├── pi12.vale ├── pi13.vale ├── pi19.vale ├── pi2.vale ├── pi20.vale ├── pi21.vale ├── pi3.vale ├── pi4.vale ├── pi5.vale ├── pi6.vale ├── pi7.vale ├── pi8.vale ├── pi9.vale └── programming_idioms.md ├── push.bat ├── references ├── constraint_ref.vale ├── constraint_ref_del1.vale ├── constraint_ref_del2.vale ├── constraint_ref_del2_solution.vale ├── references.md ├── refto_immutables.vale ├── simple_inlining.vale ├── structs_inline.vale └── weak_references.vale ├── strings ├── string_functions.vale ├── strings.md └── strings.vale ├── structs ├── embedding_structs.vale ├── embedding_structs2.vale ├── immutable_structs.vale ├── lending.vale ├── list_structs.vale ├── move_function.vale ├── moving.vale ├── struct_constructor.vale ├── struct_definition.vale └── structs.md └── variables ├── locals.vale ├── locals_mut.vale ├── nested_shadowed.vale └── variables.md /.gitignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This site contains working programs written in the [Vale programming language](https://vale.dev/). 2 | 3 | ![](images/logo.png) 4 | 5 | It has mainly an educational purpose: to help people learn the Vale language by showing correct syntax and working programs. 6 | 7 | The programs compile and run in the current version 0.1.2 (2021 May 7). They will be kept uptodate which each new Vale version. 8 | 9 | The programs are stored in folders according to their specific Vale characteristics. Each folder contains a .md file with more explanations on each program. 10 | 11 | Using VSCode as your editor, here is a simple [syntax highlighter](https://github.com/Ivo-Balbaert/vscode-vale). 12 | 13 | To compile a program: _python pathto/valec.py build program.vale_ 14 | 15 | To run a program: _main_ (on Windows) or _./a.out_ (on Linux) 16 | 17 | The output of a program is shown in comments after: // => 18 | 19 | 20 | 21 | All improvements or contributions welcome! 22 | 23 | 24 | **Sources**: 25 | - the [Vale guide](https://vale.dev/guide/introduction) or the [Vale samples](https://github.com/ValeLang/Vale/tree/master/Valestrom/Samples/test/main/resources), sometimes slightly modified under [Apache License 2.0](https://github.com/ValeLang/Vale/blob/master/LICENSE) 26 | 27 | - a work in progress to make the [programming idioms](https://www.programming-idioms.org/about#about-block-all-idioms) in Vale 28 | 29 | - miscellaneous other example programs and contributions 30 | -------------------------------------------------------------------------------- /basic_types/basic_types.md: -------------------------------------------------------------------------------- 1 | **booleans.vale**: shows elementary operations on boolean values 2 | 3 | **int_operations.vale**: shows operations ==, !=, +, * / and mod 4 | 5 | **int_functions.vale**: shows some functions on integers (abs, signum, min, max) 6 | 7 | -------------------------------------------------------------------------------- /basic_types/booleans.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | bt = true; 5 | bf = false; 6 | 7 | row = 2; 8 | println(row == 2); // true 9 | b = (row == 2); 10 | println(b); // true 11 | 12 | println(bt); // => true 13 | println(not bt); // => false 14 | 15 | println(bt and bf); // => false 16 | println(bt or bf); // => true 17 | 18 | println(bt and not bf); // => true 19 | } -------------------------------------------------------------------------------- /basic_types/int_functions.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | import stdlib.math.*; 3 | 4 | exported func main() { 5 | n = 5; 6 | m = -3; 7 | 8 | println(abs(m)); // => 3 9 | 10 | println(signum(n)); // => 1 11 | println(signum(m)); // => -1 12 | println(signum(0)); // => 0 13 | 14 | println(min(n, m)); // => -3 15 | println(max(n, m)); // => 5 16 | } -------------------------------------------------------------------------------- /basic_types/int_operations.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | a = 42; 5 | b = 108; 6 | 7 | println(a == b); // => false 8 | println(a != b); // => true 9 | 10 | // the left hand side c is a pattern that stores the incoming data into a local named c 11 | c = a + b; 12 | println(c); // => 150 13 | 14 | d = a * b; 15 | println(d); // => 4536 16 | 17 | println(5 / 2); // => 2 18 | println(5 mod 2); // => 1 19 | 20 | println(0 / 5); // => 0 21 | println(5 * 0); // => 0 22 | } 23 | -------------------------------------------------------------------------------- /branching_and_looping/branching_and_looping.md: -------------------------------------------------------------------------------- 1 | **if.vale**: shows if - else if - else, use of logical operators 2 | 3 | **while.vale**: shows a while loop 4 | 5 | **fizzbuzz.vale**: combining while-loop and if-conditions 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /branching_and_looping/fizzbuzz.vale: -------------------------------------------------------------------------------- 1 | // Print the numbers from 1 to 100, 2 | // except if the number is divisible by 3 then print ‘fizz’, 3 | // if the number is divisible by 5 print ‘buzz’ 4 | // or if the number if divisible by both print ‘fizzbuzz’. 5 | 6 | import stdlib.*; 7 | 8 | exported func main() { 9 | i = 1; 10 | while i <= 100 { 11 | if i mod 3 == 0 { print("fizz"); } 12 | if i mod 5 == 0 { print("buzz"); } 13 | if i mod 3 != 0 and i mod 5 != 0 { print(i); } 14 | set i = i + 1; 15 | println(""); 16 | } 17 | } -------------------------------------------------------------------------------- /branching_and_looping/if.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | first = 10; 5 | cond = 5; 6 | row = 2; 7 | col = 5; 8 | println(row == 2); // true 9 | 10 | if row == 2 { println("Right on!"); } // => Right on! 11 | b = (row == 2); 12 | if b { println("Right on!"); } // => Right on! 13 | 14 | if cond < first { println("first is greater"); } // => first is greater 15 | 16 | // nested if: 17 | if first <= 0 { println("first is less than or equal to 0"); } 18 | else if first > 0 and first < cond { println("first is between 0 and 5"); } 19 | else { println("first is 5 or greater"); } // => first is 5 or greater 20 | 21 | // logical operators: 22 | killedGoblin = false; 23 | if not killedGoblin { 24 | println("The goblin is still alive!"); // => The goblin is still alive! 25 | } 26 | 27 | n = 4; 28 | if n > 2 and n < 5 { println("The number is either 3 or 4"); } 29 | // => The number is either 3 or 4 30 | // same: 31 | if and(n > 2, n < 5) { println("The number is either 3 or 4"); } 32 | // => The number is either 3 or 4 33 | 34 | m = 1; 35 | if m > 2 or m < 5 { println("Bigger than 2 or smaller than 5"); } 36 | // => Bigger than 2 or smaller than 5 37 | if or(m > 2, m < 5) { println("Bigger than 2 or smaller than 5"); } 38 | // => Bigger than 2 or smaller than 5 39 | 40 | if n == 4 and m == 1 { println("This works!"); } 41 | } -------------------------------------------------------------------------------- /branching_and_looping/if_expression.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | n = 1; 5 | m = 2; 6 | width = 7 | if n < m { 8 | 42 9 | } else { 10 | 150 11 | }; 12 | println(width); // => 42 13 | 14 | something = 15 | if 4 < 7 { 16 | println("hi!"); // => hi! 17 | 7 18 | } else { 19 | 10 // works because its the only statement in the block 20 | }; 21 | println(something); // => 7 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /branching_and_looping/while.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | a = 1; 5 | while a < 42 { 6 | set a = a + 1; 7 | } 8 | println(a); // => 42 9 | 10 | i = 10; 11 | while i >= 0 { 12 | println("The variable i is now: " + i); 13 | set i = i - 1; 14 | } 15 | // The variable i is now: 9 16 | // The variable i is now: 8 17 | // The variable i is now: 7 18 | // The variable i is now: 6 19 | // The variable i is now: 5 20 | // The variable i is now: 4 21 | // The variable i is now: 3 22 | // The variable i is now: 2 23 | // The variable i is now: 1 24 | // The variable i is now: 0 25 | } 26 | -------------------------------------------------------------------------------- /compile_and_run.bat: -------------------------------------------------------------------------------- 1 | rem run this command-file from folder code_examples as 2 | rem compile_and_run > output 3 | %1\valec.exe build mysample=hello_world.vale stdlib=%1\stdlib\src --output_dir build 4 | build\main.exe 5 | 6 | rem basic_types 7 | %1\valec.exe build mysample=basic_types/booleans.vale stdlib=%1\stdlib\src --output_dir build 8 | build\main.exe 9 | %1\valec.exe build mysample=basic_types/int_operations.vale stdlib=%1\stdlib\src --output_dir build 10 | build\main.exe 11 | %1\valec.exe build mysample=basic_types/int_functions.vale stdlib=%1\stdlib\src --output_dir build 12 | build\main.exe 13 | 14 | rem branching_and_looping 15 | %1\valec.exe build mysample=branching_and_looping/if.vale stdlib=%1\stdlib\src --output_dir build 16 | build\main.exe 17 | %1\valec.exe build mysample=branching_and_looping/if_expression.vale stdlib=%1\stdlib\src --output_dir build 18 | build\main.exe 19 | %1\valec.exe build mysample=branching_and_looping/while.vale stdlib=%1\stdlib\src --output_dir build 20 | build\main.exe 21 | %1\valec.exe build mysample=branching_and_looping/fizzbuzz.vale stdlib=%1\stdlib\src --output_dir build 22 | build\main.exe 23 | 24 | rem calling_c 25 | %1\valec.exe build mysample=ffi_c/externstrlen.vale mysample=ffi_c/externstrlen.c stdlib=%1\stdlib\src --output_dir build 26 | build\main.exe 27 | 28 | rem data_structures: 29 | %1\valec.exe build mysample=data_structures/tuples.vale stdlib=%1\stdlib\src --output_dir build 30 | build\main.exe 31 | %1\valec.exe build mysample=data_structures/arrays.vale stdlib=%1\stdlib\src --output_dir build 32 | build\main.exe 33 | %1\valec.exe build mysample=data_structures/lists.vale stdlib=%1\stdlib\src --output_dir build 34 | build\main.exe 35 | 36 | rem functions: 37 | %1\valec.exe build mysample=functions/functions_lambdas.vale stdlib=%1\stdlib\src --output_dir build 38 | build\main.exe 39 | %1\valec.exe build mysample=functions/lambdas_param.vale stdlib=%1\stdlib\src --output_dir build 40 | build\main.exe 41 | %1\valec.exe build mysample=functions/overloads.vale stdlib=%1\stdlib\src --output_dir build 42 | build\main.exe 43 | %1\valec.exe build mysample=functions/recursion.vale stdlib=%1\stdlib\src --output_dir build 44 | build\main.exe 45 | 46 | rem games: 47 | %1\valec.exe build mysample=games/roguelike.vale stdlib=%1\stdlib\src --output_dir build 48 | build\main.exe 49 | 50 | rem generics: 51 | %1\valec.exe build mysample=generics/generic_structs.vale stdlib=%1\stdlib\src --output_dir build 52 | build\main.exe 53 | 54 | rem getting_input: 55 | %1\valec.exe build mysample=getting_input/cmd_args.vale stdlib=%1\stdlib\src --output_dir build 56 | build\main.exe 1 2 57 | rem run on command-line: 58 | %1\valec.exe build mysample=getting_input/keyboard_input.vale stdlib=%1\stdlib\src --output_dir build 59 | build\main.exe 60 | 61 | rem interfaces: 62 | %1\valec.exe build mysample=interfaces/using_interfaces.vale stdlib=%1\stdlib\src --output_dir build 63 | build\main.exe 64 | 65 | rem miscellaneous: 66 | %1\valec.exe build mysample=miscellaneous/main_ret.vale stdlib=%1\stdlib\src --output_dir build 67 | build\main.exe 68 | %1\valec.exe build mysample=miscellaneous/panic.vale stdlib=%1\stdlib\src --output_dir build 69 | build\main.exe 70 | %1\valec.exe build mysample=miscellaneous/unreachable.vale stdlib=%1\stdlib\src --output_dir build 71 | build\main.exe 72 | %1\valec.exe build mysample=miscellaneous/vassert.vale stdlib=%1\stdlib\src --output_dir build 73 | build\main.exe 74 | 75 | rem patterns: 76 | %1\valec.exe build mysample=patterns/destructuring.vale stdlib=%1\stdlib\src --output_dir build 77 | build\main.exe 78 | %1\valec.exe build mysample=patterns/tuple_destructuring.vale stdlib=%1\stdlib\src --output_dir build 79 | build\main.exe 80 | 81 | rem programming_idioms: 82 | %1\valec.exe build mysample=programming_idioms/pi1.vale stdlib=%1\stdlib\src --output_dir build 83 | build\main.exe 84 | %1\valec.exe build mysample=programming_idioms/pi2.vale stdlib=%1\stdlib\src --output_dir build 85 | build\main.exe 86 | %1\valec.exe build mysample=programming_idioms/pi3.vale stdlib=%1\stdlib\src --output_dir build 87 | build\main.exe 88 | %1\valec.exe build mysample=programming_idioms/pi4.vale stdlib=%1\stdlib\src --output_dir build 89 | build\main.exe 90 | %1\valec.exe build mysample=programming_idioms/pi5.vale stdlib=%1\stdlib\src --output_dir build 91 | build\main.exe 92 | %1\valec.exe build mysample=programming_idioms/pi6.vale stdlib=%1\stdlib\src --output_dir build 93 | build\main.exe 94 | %1\valec.exe build mysample=programming_idioms/pi7.vale stdlib=%1\stdlib\src --output_dir build 95 | build\main.exe 96 | %1\valec.exe build mysample=programming_idioms/pi8.vale stdlib=%1\stdlib\src --output_dir build 97 | build\main.exe 98 | %1\valec.exe build mysample=programming_idioms/pi9.vale stdlib=%1\stdlib\src --output_dir build 99 | build\main.exe 100 | %1\valec.exe build mysample=programming_idioms/pi12.vale stdlib=%1\stdlib\src --output_dir build 101 | build\main.exe 102 | %1\valec.exe build mysample=programming_idioms/pi13.vale stdlib=%1\stdlib\src --output_dir build 103 | build\main.exe 104 | %1\valec.exe build mysample=programming_idioms/pi19.vale stdlib=%1\stdlib\src --output_dir build 105 | build\main.exe 106 | %1\valec.exe build mysample=programming_idioms/pi20.vale stdlib=%1\stdlib\src --output_dir build 107 | build\main.exe 108 | %1\valec.exe build mysample=programming_idioms/pi21.vale stdlib=%1\stdlib\src --output_dir build 109 | build\main.exe 110 | 111 | rem references: 112 | %1\valec.exe build mysample=references/constraint_ref.vale stdlib=%1\stdlib\src --output_dir build 113 | build\main.exe 114 | %1\valec.exe build mysample=references/constraint_ref_del1.vale stdlib=%1\stdlib\src --output_dir build 115 | build\main.exe 116 | %1\valec.exe build mysample=references/constraint_ref_del2.vale stdlib=%1\stdlib\src --output_dir build 117 | build\main.exe 118 | %1\valec.exe build mysample=references/constraint_ref_del2_solution.vale stdlib=%1\stdlib\src --output_dir build 119 | build\main.exe 120 | %1\valec.exe build mysample=references/refto_immutables.vale stdlib=%1\stdlib\src --output_dir build 121 | build\main.exe 122 | %1\valec.exe build mysample=references/simple_inlining.vale stdlib=%1\stdlib\src --output_dir build 123 | build\main.exe 124 | %1\valec.exe build mysample=references/structs_inline.vale stdlib=%1\stdlib\src --output_dir build 125 | build\main.exe 126 | %1\valec.exe build mysample=references/weak_references.vale stdlib=%1\stdlib\src --output_dir build 127 | build\main.exe 128 | 129 | rem strings: 130 | %1\valec.exe build mysample=strings/strings.vale stdlib=%1\stdlib\src --output_dir build 131 | build\main.exe 132 | %1\valec.exe build mysample=strings/string_functions.vale stdlib=%1\stdlib\src --output_dir build 133 | build\main.exe 134 | 135 | rem structs: 136 | %1\valec.exe build mysample=structs/embedding_structs.vale stdlib=%1\stdlib\src --output_dir build 137 | build\main.exe 138 | %1\valec.exe build mysample=structs/embedding_structs2.vale stdlib=%1\stdlib\src --output_dir build 139 | build\main.exe 140 | %1\valec.exe build mysample=structs/immutable_structs.vale stdlib=%1\stdlib\src --output_dir build 141 | build\main.exe 142 | %1\valec.exe build mysample=structs/lending.vale stdlib=%1\stdlib\src --output_dir build 143 | build\main.exe 144 | %1\valec.exe build mysample=structs/list_structs.vale stdlib=%1\stdlib\src --output_dir build 145 | build\main.exe 146 | %1\valec.exe build mysample=structs/move_function.vale stdlib=%1\stdlib\src --output_dir build 147 | build\main.exe 148 | %1\valec.exe build mysample=structs/moving.vale stdlib=%1\stdlib\src --output_dir build 149 | build\main.exe 150 | %1\valec.exe build mysample=structs/struct_constructor.vale stdlib=%1\stdlib\src --output_dir build 151 | build\main.exe 152 | %1\valec.exe build mysample=structs/struct_definition.vale stdlib=%1\stdlib\src --output_dir build 153 | build\main.exe 154 | 155 | rem variables: 156 | %1\valec.exe build mysample=variables/locals.vale stdlib=%1\stdlib\src --output_dir build 157 | build\main.exe 158 | %1\valec.exe build mysample=variables/locals_mut.vale stdlib=%1\stdlib\src --output_dir build 159 | build\main.exe 160 | %1\valec.exe build mysample=variables/nested_shadowed.vale stdlib=%1\stdlib\src --output_dir build 161 | build\main.exe 162 | -------------------------------------------------------------------------------- /compile_and_run.sh: -------------------------------------------------------------------------------- 1 | # run this command-file from folder code_examples as 2 | # compile_and_run C:\ValeCompiler > output 3 | $1/valec build mysample=hello_world.vale stdlib=$1/stdlib/src --output_dir build 4 | build/main 5 | 6 | # basic_types 7 | $1/valec build mysample=basic_types/booleans.vale stdlib=$1/stdlib/src --output_dir build 8 | build/main 9 | $1/valec build mysample=basic_types/int_operations.vale stdlib=$1/stdlib/src --output_dir build 10 | build/main 11 | $1/valec build mysample=basic_types/int_functions.vale stdlib=$1/stdlib/src --output_dir build 12 | build/main 13 | 14 | # branching_and_looping 15 | $1/valec build mysample=branching_and_looping/if.vale stdlib=$1/stdlib/src --output_dir build 16 | build/main 17 | $1/valec build mysample=branching_and_looping/if_expression.vale stdlib=$1/stdlib/src --output_dir build 18 | build/main 19 | $1/valec build mysample=branching_and_looping/while.vale stdlib=$1/stdlib/src --output_dir build 20 | build/main 21 | $1/valec build mysample=branching_and_looping/fizzbuzz.vale stdlib=$1/stdlib/src --output_dir build 22 | build/main 23 | 24 | # calling_c 25 | $1/valec build mysample=ffi_c/externstrlen.vale mysample=ffi_c/externstrlen.c stdlib=$1/stdlib/src --output_dir build 26 | build/main 27 | 28 | # data_structures: 29 | $1/valec build mysample=data_structures/tuples.vale stdlib=$1/stdlib/src --output_dir build 30 | build/main 31 | $1/valec build mysample=data_structures/arrays.vale stdlib=$1/stdlib/src --output_dir build 32 | build/main 33 | $1/valec build mysample=data_structures/lists.vale stdlib=$1/stdlib/src --output_dir build 34 | build/main 35 | 36 | # functions: 37 | $1/valec build mysample=functions/functions_lambdas.vale stdlib=$1/stdlib/src --output_dir build 38 | build/main 39 | $1/valec build mysample=functions/lambdas_param.vale stdlib=$1/stdlib/src --output_dir build 40 | build/main 41 | $1/valec build mysample=functions/overloads.vale stdlib=$1/stdlib/src --output_dir build 42 | build/main 43 | $1/valec build mysample=functions/recursion.vale stdlib=$1/stdlib/src --output_dir build 44 | build/main 45 | 46 | # games: 47 | $1/valec build mysample=games/roguelike.vale stdlib=$1/stdlib/src --output_dir build 48 | build/main 49 | 50 | # generics: 51 | $1/valec build mysample=generics/generic_structs.vale stdlib=$1/stdlib/src --output_dir build 52 | build/main 53 | 54 | # getting_input: 55 | $1/valec build mysample=getting_input/cmd_args.vale stdlib=$1/stdlib/src --output_dir build 56 | build/main 1 2 57 | # run on command-line: 58 | $1/valec build mysample=getting_input/keyboard_input.vale stdlib=$1/stdlib/src --output_dir build 59 | build/main 60 | 61 | # interfaces: 62 | $1/valec build mysample=interfaces/using_interfaces.vale stdlib=$1/stdlib/src --output_dir build 63 | build/main 64 | 65 | # miscellaneous: 66 | $1/valec build mysample=miscellaneous/main_ret.vale stdlib=$1/stdlib/src --output_dir build 67 | build/main 68 | $1/valec build mysample=miscellaneous/panic.vale stdlib=$1/stdlib/src --output_dir build 69 | build/main 70 | $1/valec build mysample=miscellaneous/unreachable.vale stdlib=$1/stdlib/src --output_dir build 71 | build/main 72 | $1/valec build mysample=miscellaneous/vassert.vale stdlib=$1/stdlib/src --output_dir build 73 | build/main 74 | 75 | # patterns: 76 | $1/valec build mysample=patterns/destructuring.vale stdlib=$1/stdlib/src --output_dir build 77 | build/main 78 | $1/valec build mysample=patterns/tuple_destructuring.vale stdlib=$1/stdlib/src --output_dir build 79 | build/main 80 | 81 | # programming_idioms: 82 | $1/valec build mysample=programming_idioms/pi1.vale stdlib=$1/stdlib/src --output_dir build 83 | build/main 84 | $1/valec build mysample=programming_idioms/pi2.vale stdlib=$1/stdlib/src --output_dir build 85 | build/main 86 | $1/valec build mysample=programming_idioms/pi3.vale stdlib=$1/stdlib/src --output_dir build 87 | build/main 88 | $1/valec build mysample=programming_idioms/pi4.vale stdlib=$1/stdlib/src --output_dir build 89 | build/main 90 | $1/valec build mysample=programming_idioms/pi5.vale stdlib=$1/stdlib/src --output_dir build 91 | build/main 92 | $1/valec build mysample=programming_idioms/pi6.vale stdlib=$1/stdlib/src --output_dir build 93 | build/main 94 | $1/valec build mysample=programming_idioms/pi7.vale stdlib=$1/stdlib/src --output_dir build 95 | build/main 96 | $1/valec build mysample=programming_idioms/pi8.vale stdlib=$1/stdlib/src --output_dir build 97 | build/main 98 | $1/valec build mysample=programming_idioms/pi9.vale stdlib=$1/stdlib/src --output_dir build 99 | build/main 100 | $1/valec build mysample=programming_idioms/pi12.vale stdlib=$1/stdlib/src --output_dir build 101 | build/main 102 | $1/valec build mysample=programming_idioms/pi13.vale stdlib=$1/stdlib/src --output_dir build 103 | build/main 104 | $1/valec build mysample=programming_idioms/pi19.vale stdlib=$1/stdlib/src --output_dir build 105 | build/main 106 | $1/valec build mysample=programming_idioms/pi20.vale stdlib=$1/stdlib/src --output_dir build 107 | build/main 108 | $1/valec build mysample=programming_idioms/pi21.vale stdlib=$1/stdlib/src --output_dir build 109 | build/main 110 | 111 | # references: 112 | $1/valec build mysample=references/constraint_ref.vale stdlib=$1/stdlib/src --output_dir build 113 | build/main 114 | $1/valec build mysample=references/constraint_ref_del1.vale stdlib=$1/stdlib/src --output_dir build 115 | build/main 116 | $1/valec build mysample=references/constraint_ref_del2.vale stdlib=$1/stdlib/src --output_dir build 117 | build/main 118 | $1/valec build mysample=references/constraint_ref_del2_solution.vale stdlib=$1/stdlib/src --output_dir build 119 | build/main 120 | $1/valec build mysample=references/refto_immutables.vale stdlib=$1/stdlib/src --output_dir build 121 | build/main 122 | $1/valec build mysample=references/simple_inlining.vale stdlib=$1/stdlib/src --output_dir build 123 | build/main 124 | $1/valec build mysample=references/structs_inline.vale stdlib=$1/stdlib/src --output_dir build 125 | build/main 126 | $1/valec build mysample=references/weak_references.vale stdlib=$1/stdlib/src --output_dir build 127 | build/main 128 | 129 | # strings: 130 | $1/valec build mysample=strings/strings.vale stdlib=$1/stdlib/src --output_dir build 131 | build/main 132 | $1/valec build mysample=strings/string_functions.vale stdlib=$1/stdlib/src --output_dir build 133 | build/main 134 | 135 | # structs: 136 | $1/valec build mysample=structs/embedding_structs.vale stdlib=$1/stdlib/src --output_dir build 137 | build/main 138 | $1/valec build mysample=structs/embedding_structs2.vale stdlib=$1/stdlib/src --output_dir build 139 | build/main 140 | $1/valec build mysample=structs/immutable_structs.vale stdlib=$1/stdlib/src --output_dir build 141 | build/main 142 | $1/valec build mysample=structs/lending.vale stdlib=$1/stdlib/src --output_dir build 143 | build/main 144 | $1/valec build mysample=structs/list_structs.vale stdlib=$1/stdlib/src --output_dir build 145 | build/main 146 | $1/valec build mysample=structs/move_function.vale stdlib=$1/stdlib/src --output_dir build 147 | build/main 148 | $1/valec build mysample=structs/moving.vale stdlib=$1/stdlib/src --output_dir build 149 | build/main 150 | $1/valec build mysample=structs/struct_constructor.vale stdlib=$1/stdlib/src --output_dir build 151 | build/main 152 | $1/valec build mysample=structs/struct_definition.vale stdlib=$1/stdlib/src --output_dir build 153 | build/main 154 | 155 | # variables: 156 | $1/valec build mysample=variables/locals.vale stdlib=$1/stdlib/src --output_dir build 157 | build/main 158 | $1/valec build mysample=variables/locals_mut.vale stdlib=$1/stdlib/src --output_dir build 159 | build/main 160 | $1/valec build mysample=variables/nested_shadowed.vale stdlib=$1/stdlib/src --output_dir build 161 | build/main 162 | -------------------------------------------------------------------------------- /data_structures/arrays.vale: -------------------------------------------------------------------------------- 1 | // see also tuples.vale 2 | 3 | import stdlib.*; 4 | 5 | exported func main() { 6 | arr1 = [](5, {_}); // [0, 1, 2, 3, 4] 7 | // the type of arr1 is Array 8 | println(arr1[0]); // => 0 9 | println(arr1.0); // => 0 10 | set arr1[0] = 1; 11 | println(arr1[0]); // => 1 12 | set arr1.0 = 2; 13 | println(arr1[0]); // => 2 14 | 15 | // size of an array: 16 | println(arr1.len()); // => 5 17 | 18 | // print out all elements: 19 | arr2 = [](4, {_ * 2}); // [0, 2, 4, 6] 20 | arr2.each( { println(_); } ); 21 | // => 22 | // 0 23 | // 2 24 | // 4 25 | // 6 26 | 27 | // builtin foreach: 28 | foreach n in &arr2 { println(n); } 29 | // => 30 | // 0 31 | // 2 32 | // 4 33 | // 6 34 | foreach [ix, p] in arr2.entries() { println("On index: " + ix + " is item: " + p); } 35 | // => 36 | // On index: 0 is item: 0 37 | // On index: 1 is item: 2 38 | // On index: 2 is item: 4 39 | // On index: 3 is item: 6 40 | 41 | arr3 = [](4, {_ * 5}); // [0, 5, 10, 15] 42 | println(arr3[3]); // => 15 43 | // println(arr3[4]); // at runtime => Index out of bounds! Exiting! 44 | // loop over the array: 45 | arr3.each( { println(_); } ); 46 | 47 | num = 9; 48 | arr4 = [](num, {_ / 2}); 49 | println(arr4[5]); // 4 / 2 => 2 50 | arr4.each( { print(_ + " - "); } ); // => 0 - 0 - 1 - 1 - 2 - 2 - 3 - 3 - 4 - 51 | println(""); 52 | 53 | n = 2; 54 | m = 7; 55 | len = n + m; 56 | arr5 = [](len, {_ / 2}); 57 | println(arr5[6]); // 6 / 2 => 3 58 | 59 | arr6 = initArr(); 60 | arr6.each( { print(_ + " - "); } ); // => 0 - 100 - 200 - 300 - 400 - 500 - 600 - 61 | println(""); 62 | } 63 | 64 | func initArr() Array { 65 | [](7, { _ * 100 }) 66 | } 67 | -------------------------------------------------------------------------------- /data_structures/data_structures.md: -------------------------------------------------------------------------------- 1 | **tuples.vale**: shows how to define a tuple with [ ], and how to address and change its elements with the . and [ix] notation 2 | 3 | **arrays.vale**: shows how to define an array with the MakeArray function, how to acces and change its elements with the . and [ix] notation, and how to print out or loop over an entire array arr with arr.each 4 | 5 | **lists.vale**: shows how to define a List, how to read and change elements of a list, showing the length of a list with len, looping over a list with .each, the contains and remove methods, splitting a string to a List, joining the elements of a List to a string. 6 | (command to compile: python ..\valec.py build lists.vale ..\vstl\list.vale) -------------------------------------------------------------------------------- /data_structures/lists.vale: -------------------------------------------------------------------------------- 1 | 2 | // build command: python ..\valec.py build lists.vale ..\vstl\list.vale 3 | 4 | import stdlib.*; 5 | import stdlib.collections.*; 6 | import stdlib.stringutils.*; 7 | 8 | exported func main() { 9 | // a list of integers: 10 | lst = List(); 11 | lst.add(1); 12 | lst.add(3); 13 | lst.add(7); 14 | println(lst.get(2)); // => 7 15 | 16 | // length of the list: 17 | println(len(&lst)); // => 3 18 | 19 | // looping over a list: 20 | lst.each( { println(_); } ); 21 | // => 22 | // 1 23 | // 3 24 | // 7 25 | // simpler form: 26 | foreach p in &lst { println(p); } 27 | // => 28 | // 1 29 | // 3 30 | // 7 31 | 32 | // changing an element: 33 | ix = 2; 34 | val = 99; 35 | lst.set(ix, val); 36 | println(lst.get(2)); // => 99 37 | 38 | lst.each( { println(_); } ); 39 | // 1 40 | // 3 41 | // 99 42 | 43 | // check if list contains a given value: 44 | println(lst.contains(3)); // => true 45 | 46 | // remove an element: 47 | set ix = 1; 48 | lst.remove(ix); 49 | lst.each( { println(_); } ); 50 | // 1 51 | // 99 52 | 53 | // split a string to return a List: 54 | s = "Hail Hydra!".split(" "); // split used as a method 55 | // s has type List 56 | println(s.get(0)); // => Hail 57 | println(s.get(1)); // => Hydra! 58 | s2 = split("Hail Hydra!", " "); // split used as a function 59 | println(s2.get(0)); // => Hail 60 | println(s2.get(1)); // => Hydra! 61 | 62 | // join a list to get a string: 63 | lst2 = List(); 64 | lst2.add("Hail"); 65 | lst2.add("Hydra!"); 66 | foreach x in lst2 { println(x); } 67 | // => 68 | // "Hail" 69 | // "Hydra!" 70 | } -------------------------------------------------------------------------------- /data_structures/tuples.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | t1 = (23, 108, 37, 42, 49); // tuple with same element type int 5 | println(t1.1); // => 108 6 | 7 | t2 = (5, true, "V"); // different element types 8 | println("Babylon " + t2.0); // => Babylon 5 9 | 10 | [a, b, c] = t2; // extract elements from tuple 11 | println(a); // => 5 12 | println(b); // => true 13 | println(c); // => V 14 | } 15 | -------------------------------------------------------------------------------- /ffi_c - Shortcut.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/Vale_Examples/4a50a3e4e42388f4a348a3b63e28c3e4785b3559/ffi_c - Shortcut.lnk -------------------------------------------------------------------------------- /ffi_c/calling_c.md: -------------------------------------------------------------------------------- 1 | **readInt.vale / readInt.c**: Vale calls an external C function readInt, defined in readInt.c; notice that in Vale readInt must be defined as extern (postfix), and the same in the C source (prefix) 2 | 3 | **externstrlen.vale / externstrlen.c**: Vale calls an external C function extStrLen, defined in externstrlen.c; 4 | 5 | **triple.vale / triple.c**: C code can call into Vale code.Here, a Vale main is calling into a C cMain function, which is calling into a Vale exported triple function.Vale automatically provides a header file so C can call the function. 6 | 7 | **structtoc.vale / structtoc.c**: passing a Vale struct into C code 8 | 9 | **mutstructtoc.vale / mutstructtoc.c**: passing a mutable Vale struct into C code 10 | -------------------------------------------------------------------------------- /ffi_c/extern.vale: -------------------------------------------------------------------------------- 1 | extern func sqrt(x float) float; 2 | 3 | exported func main() { 4 | println(int(sqrt(float(16)))); // => 4 5 | } 6 | -------------------------------------------------------------------------------- /ffi_c/externstrlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mysample/extStrLen.h" 5 | #include "ValeBuiltins.h" 6 | 7 | extern ValeInt mysample_extStrLen(ValeStr *haystackContainerStr) 8 | { 9 | char *haystackContainerChars = haystackContainerStr->chars; 10 | int64_t result = strlen(haystackContainerChars); 11 | return result; 12 | } 13 | -------------------------------------------------------------------------------- /ffi_c/externstrlen.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | extern func extStrLen(haystackStr str) int; 4 | 5 | exported func main() { 6 | len = extStrLen("sprogwoggle"); 7 | println(len); // => 11 8 | } 9 | 10 | 11 | // build with: 12 | // python ../valec.py build externstrlen.vale 13 | // then replace 3rd stage with: 14 | // cl.exe /ENTRY:"main" /SUBSYSTEM:CONSOLE /Fe:main.exe build.obj C:\Vale\builtins\assert.c 15 | // C:\Vale\builtins\census.c C:\Vale\builtins\file.c C:\Vale\builtins\genHeap.c C:\Vale\builtins\mainargs.c 16 | // C:\Vale\builtins\math.c C:\Vale\builtins\stdio.c C:\Vale\builtins\strings.c C:\Vale\builtins\weaks.c 17 | // c:\Vale\code_examples\externstrlen.c -------------------------------------------------------------------------------- /ffi_c/mutstructtoc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Ship.h" 3 | #include "getFuel.h" 4 | 5 | extern int halfFuel(ShipRef s) 6 | { 7 | return getFuel(s) / 2; 8 | } -------------------------------------------------------------------------------- /ffi_c/mutstructtoc.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported struct Ship { 4 | fuel int; 5 | } 6 | 7 | exported func getFuel(s &Ship) int { 8 | s.fuel 9 | } 10 | 11 | exported func main() { 12 | s = Ship(42); 13 | h = halfFuel(&s); 14 | println(h); // => 21 15 | } 16 | 17 | extern func halfFuel(s &Ship) int; -------------------------------------------------------------------------------- /ffi_c/readInt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | extern int64_t readInt() 4 | { 5 | int64_t x = 0; 6 | scanf("%lld", &x); 7 | return x; 8 | } -------------------------------------------------------------------------------- /ffi_c/readInt.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | i = readInt(); 5 | println("User entered: " + i); 6 | } 7 | 8 | extern func readInt() int; 9 | 10 | // main 11 | // 5 // <-- input 12 | // => User entered: 5 13 | // compile with: 14 | // 15 | // replace Cl phaze with: 16 | // cl.exe /ENTRY:"main" /SUBSYSTEM:CONSOLE /Fe:main.exe /fsanitize=address 17 | // clang_rt.asan_dynamic-x86_64.lib clang_rt.asan_dynamic_runtime_thunk-x86_64.lib build.obj C:\Vale\builtins\assert.c C:\Vale\builtins\census.c C:\Vale\builtins\file.c C:\Vale\builtins\genHeap.c C:\Vale\builtins\mainargs.c C:\Vale\builtins\math.c C:\Vale\builtins\stdio.c C:\Vale\builtins\strings.c 18 | // C:\Vale\builtins\twinpages.c C:\Vale\builtins\weaks.c readInt.c -------------------------------------------------------------------------------- /ffi_c/structtoc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Vec3.h" 3 | 4 | extern int sum(Vec3 *v) 5 | { 6 | return v->x + v->y + v->z; 7 | } -------------------------------------------------------------------------------- /ffi_c/structtoc.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Vec3 export imm { 4 | x int; y int; z int; 5 | } 6 | 7 | exported func main() { 8 | v = Vec3(10, 11, 12); 9 | s = sum(v); 10 | println(s); 11 | } 12 | 13 | extern func sum(v Vec3) int; -------------------------------------------------------------------------------- /ffi_c/triple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "triple.h" 4 | extern void cMain() 5 | { 6 | printf("%d", triple(14)); 7 | } -------------------------------------------------------------------------------- /ffi_c/triple.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | extern func cMain(); 4 | exported func main() { cMain(); } 5 | 6 | exported func triple(x int) int { 7 | x * 3 8 | } 9 | 10 | // compile with: python ../valec.py build triple.vale 11 | // replace 3rd stage with: 12 | // cl.exe /ENTRY:"main" /SUBSYSTEM:CONSOLE /Fe:main.exe build.obj C:\Vale\builtins\assert.c 13 | // C:\Vale\builtins\census.c C:\Vale\builtins\file.c C:\Vale\builtins\genHeap.c 14 | // C:\Vale\builtins\mainargs.c C:\Vale\builtins\math.c C:\Vale\builtins\stdio.c 15 | // C:\Vale\builtins\strings.c C:\Vale\builtins\weaks.c c:\Vale\code_examples\triple.c -------------------------------------------------------------------------------- /functions/functions.md: -------------------------------------------------------------------------------- 1 | **functions_lambdas.vale**: shows how to define a function, with return-type or return-type inferred; also shows how to define a lambda. 2 | 3 | **lambdas_param.vale**: shows that a lambda can be used as a function parameter 4 | 5 | **recursion.vale**: shows a recursive function fact 6 | 7 | **overloads.vale**: shows an overloaded function add; also how to define and overload operators 8 | -------------------------------------------------------------------------------- /functions/functions_lambdas.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | println("Half-Life " + double(1)); // => Half-Life 2 5 | println("Half-Life " + double_infer(1)); // => Half-Life 2 6 | println("Half-Life " + double_1line(1)); // => Half-Life 2 7 | 8 | double_lambda = (x int) => { x * 2 }; // a lambda function 9 | double_infer = (x) => { x * 2 }; 10 | double_short = { _ * 2 }; 11 | 12 | println("Half-Life " + double_lambda(1)); // => Half-Life 2 13 | println("Half-Life " + double_infer(1)); // => Half-Life 2 14 | println("Half-Life " + double_short(1)); // => Half-Life 2 15 | } 16 | 17 | func double(x int) int { 18 | // ret x * 2; 19 | x * 2 20 | } 21 | 22 | // inferring the return type: 23 | func double_infer(x int) infer-ret { 24 | x * 2 25 | } 26 | 27 | // a one-line function: 28 | func double_1line(x int) int { x * 2 } 29 | 30 | -------------------------------------------------------------------------------- /functions/lambdas_param.vale: -------------------------------------------------------------------------------- 1 | // a lambda as a function parameter 2 | 3 | import stdlib.*; 4 | 5 | exported func main() { 6 | a = do({ 42 }); 7 | println(a); // => 42 8 | 9 | b = 10; 10 | lam = { mut b = 42; }; 11 | lam(); // the lambda which is called changes b to 42 12 | println(b); // => 42 13 | 14 | // double closures: 15 | d = 7; 16 | e = { { d }() }(); 17 | println(e); // => 7 18 | } 19 | 20 | func do(callable C) int { // callable is a lambda, which returns 42 21 | callable() // callable is called 22 | } 23 | 24 | -------------------------------------------------------------------------------- /functions/overloads.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | println(add(3, 3)); // => 6 5 | println(add("Vale is ", "lovely")); // => Vale is lovely 6 | 7 | println(3 ~ 3); // => 6 8 | println(+("Perfect ", 5)); 9 | println(+(3, " Holy")); 10 | println(+("Magnificent ", true)); 11 | } 12 | 13 | // function add is overloaded: 14 | func add(a int, b int) infer-ret {+(a, b)} 15 | func add(a str, b str) infer-ret {+(a, b)} 16 | 17 | // defining the ~ operator: 18 | func ~(a int, b int) infer-ret {+(a, b)} 19 | 20 | // overloading the + operator: (// from builtins\castutils.vale) 21 | // commented out, because gives error 22 | // builtins/castutils.vale:14:1: Function FunctionName2(+,List(),List(Coord(Share,Readonly,Str2()), Coord(Share,Readonly,Bool2()))) already exists! Previous declaration at: 23 | // functions\overloads.vale:20:1 24 | // func +(s str, b bool) str { s + str(b) } 25 | // func +(i int, s str) str { str(i) + s } 26 | // func +(s str, i int) str { s + str(i) } 27 | 28 | 29 | -------------------------------------------------------------------------------- /functions/recursion.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | println(fact(5)); // => 120 5 | } 6 | 7 | func fact(x int) int { 8 | if x == 0 { 1 } 9 | else { x * fact(x - 1) } 10 | } 11 | -------------------------------------------------------------------------------- /games/games.md: -------------------------------------------------------------------------------- 1 | **roguelike.vale**: 2 | A basic terminal roguelike game developed by Vale's designer Evan Ovadia. 3 | 4 | - Game map: 5 | 6 | ########## 7 | #......g.# 8 | #........# 9 | #..g..g..# 10 | #..@...g.# 11 | #.g......# 12 | #.g.g..g.# 13 | #g...g...# 14 | #........# 15 | ########## 16 | 17 | # is border / . is position to move to / @ is player / g is a goblin 18 | You (@) can walk inside the arena (bounded by #) and bump into enemy goblins (g) to defeat them). 19 | 20 | - Controls: 21 | w+ENTER: move up 22 | a+ENTER: move left 23 | s+ENTER: move down 24 | d+ENTER: move right 25 | Q+ENTER: quit 26 | 27 | When you attempt to move onto a space occupied by a goblin, it will 28 | destroy that goblin. Destroy all goblins to win! 29 | 30 | - Compile command: 31 | python ..\valec.py build roguelike.vale ..\vstl\hashmap.vale ..\vstl\list.vale 32 | Run it with: main (on Windows) or ./a.out (on Linux) -------------------------------------------------------------------------------- /games/roguelike.vale: -------------------------------------------------------------------------------- 1 | // roguelike.vale - A simple Roguelike game, made in Vale. 2 | // 3 | // To build: 4 | // python3 valec.py build samples/programs/roguelike.vale vstl/hashmap.vale vstl/list.vale 5 | // 6 | // This program displays a map like: 7 | // ########## RCols---> 8 | // #......g.# o 9 | // #........# w 10 | // #..g..g..# s 11 | // #..@...g.# | 12 | // #.g......# 13 | // #.g.g..g.# 14 | // #g...g...# 15 | // #........# 16 | // ########## 17 | // where the player controls the @. When the player tries to move onto a space 18 | // already occupied by a goblin ("g"), it will destroy the goblin. 19 | 20 | import stdlib.*; 21 | import stdlib.stdin.*; 22 | import stdlib.collections.list.*; 23 | import stdlib.collections.hashmap.*; 24 | import stdlib.collections.hashset.*; 25 | 26 | struct Vec where N int { // generics 27 | values [#N]T; // a struct with field values, 28 | // which is an immutable array of N integers 29 | } 30 | 31 | struct Goblin { // "g" on the map 32 | location Vec<2, int>; // a struct with field location 33 | } 34 | 35 | // if as an expression 36 | // initializing a 2D-array with a size 10 * 10 and a lambda: 37 | func makeBoard() Array> { 38 | ret 39 | [](10, (row) => { 40 | [](10, (col) => { 41 | if row == 0 { "#" } 42 | else if col == 0 { "#" } 43 | else if row == 9 { "#" } 44 | else if col == 9 { "#" } 45 | else { "." } 46 | }) 47 | }); 48 | } 49 | 50 | // looping 51 | // logical and in an if 52 | // using a hashmap: keys() - each - get 53 | // optional type: maybeGoblin 54 | func display( 55 | board &Array>, 56 | goblins &HashMap, 57 | playerRow int, 58 | playerCol int) { 59 | toPrint = ""; 60 | foreach [rowI, row] in board.entries() { 61 | foreach [cellI, cell] in row.entries() { 62 | charToPrint = cell; 63 | // display player: 64 | if rowI == playerRow and cellI == playerCol { 65 | set charToPrint = "@"; 66 | } 67 | else { // display goblins: 68 | foreach key in goblins.keys() { 69 | maybeGoblin = goblins.get(key); // maybeGoblin is an optional boolean 70 | goblin = (maybeGoblin).get(); 71 | if rowI == goblin.location.values.1 and cellI == goblin.location.values.0 { 72 | set charToPrint = "g"; 73 | } 74 | } 75 | } 76 | set toPrint = toPrint + charToPrint; // add to same row 77 | } 78 | set toPrint = toPrint + "\n"; 79 | } // next row 80 | print(toPrint); // print out the map 81 | } 82 | 83 | func inputKey() int { 84 | key = 0; 85 | while true { 86 | set key = getch(); // Vale extern routine to get a character from standard input 87 | if (key == 10) {} // Enter key, do nothing 88 | else { ret key; } 89 | } 90 | panic("unreachable"); // should be unreachable 91 | } 92 | 93 | func goblinAt( 94 | goblins &HashMap, 95 | goblinKey int, 96 | row int, 97 | col int) bool { 98 | a = goblins.get(goblinKey); 99 | b = (a).get(); // to get the value out of an optional 100 | [goblinCol, goblinRow] = b.location.values; 101 | ret and(row == goblinRow, col == goblinCol); 102 | } 103 | 104 | exported func main() { 105 | // print instructions: 106 | println("Welcome to the ridiculously simplistic roguelike game!"); 107 | println("Controls:"); 108 | println(" w+enter: move up"); 109 | println(" a+enter: move left"); 110 | println(" s+enter: move down"); 111 | println(" d+enter: move right"); 112 | println(" Q+enter: quit"); 113 | println("When you attempt to move onto a space occupied by a goblin, it will"); 114 | println("destroy that goblin. Destroy all goblins to win!"); 115 | 116 | board = makeBoard(); 117 | 118 | playerRow = 4; 119 | playerCol = 3; 120 | 121 | // hashmap of key int, value a Goblin struct 122 | goblins = HashMap(IntHasher(), IntEquator()); 123 | goblins.add(13, Goblin(Vec(#[#][6, 3]))); // [col, row] 124 | goblins.add(14, Goblin(Vec(#[#][2, 6]))); 125 | goblins.add(15, Goblin(Vec(#[#][5, 7]))); 126 | goblins.add(17, Goblin(Vec(#[#][2, 5]))); 127 | goblins.add(19, Goblin(Vec(#[#][7, 1]))); 128 | goblins.add(23, Goblin(Vec(#[#][3, 3]))); 129 | goblins.add(24, Goblin(Vec(#[#][1, 7]))); 130 | goblins.add(25, Goblin(Vec(#[#][7, 6]))); 131 | goblins.add(27, Goblin(Vec(#[#][4, 6]))); 132 | goblins.add(29, Goblin(Vec(#[#][7, 4]))); 133 | 134 | running = true; 135 | while running { // game loop 136 | 137 | display(&board, &goblins, playerRow, playerCol); 138 | 139 | newPlayerRow = playerRow; 140 | newPlayerCol = playerCol; 141 | 142 | key = inputKey(); 143 | if (key == 81) { // Q 144 | set running = false; // --> jump out of game loop 145 | } else if (key == 119) { // w - up 146 | set newPlayerRow = newPlayerRow - 1; 147 | } else if (key == 115) { // s - down 148 | set newPlayerRow = newPlayerRow + 1; 149 | } else if (key == 97) { // a - left 150 | set newPlayerCol = newPlayerCol - 1; 151 | } else if (key == 100) { // d - right 152 | set newPlayerCol = newPlayerCol + 1; 153 | } else { 154 | println("Unknown key command, try again"); 155 | } 156 | 157 | killedGoblin = false; 158 | // check if a goblin is destroyed: 159 | foreach goblin_id in goblins.keys() { 160 | // is there a goblin on the new player position? 161 | if goblinAt(&goblins, goblin_id, newPlayerRow, newPlayerCol) { 162 | goblins.remove(goblin_id); 163 | set killedGoblin = true; 164 | } // --> player does not move! 165 | } 166 | 167 | if (not killedGoblin) { // move player only when no goblin is killed 168 | if board[newPlayerRow][newPlayerCol] == "." { 169 | set playerRow = newPlayerRow; 170 | set playerCol = newPlayerCol; 171 | } 172 | } 173 | 174 | // Test Game-over: 175 | if (len(goblins.keys()) == 0) { // all goblins are dead! 176 | println("You win!"); 177 | set running = false; 178 | } 179 | } 180 | } -------------------------------------------------------------------------------- /generics/generic_structs.vale: -------------------------------------------------------------------------------- 1 | // Compile with: python ..\valec.py build generic_structs.vale ..\vstl\list.vale 2 | 3 | import stdlib.*; 4 | import stdlib.collections.list.*; 5 | 6 | struct Firefly { } 7 | 8 | func crazyIvan(f &Firefly) { println("My name is Crazy Ivan!"); } 9 | 10 | struct Flock 11 | { 12 | ships List; 13 | } 14 | 15 | exported func main() { 16 | f = Flock(List()); 17 | f.ships.add(Firefly()); 18 | f.ships.add(Firefly()); 19 | 20 | firstShip = f.ships.get(0); 21 | firstShip.crazyIvan(); // => My name is Crazy Ivan! 22 | } -------------------------------------------------------------------------------- /generics/generics.md: -------------------------------------------------------------------------------- 1 | **generic_structs.vale**: shows how a struct Flock containing a List is implemented for the type Firefly 2 | 3 | **using_generics.vale**: longerShip takes a generic type T -------------------------------------------------------------------------------- /generics/using_generics.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | interface ISpaceship { 4 | func length(virtual self &ISpaceship) int; 5 | func honk(virtual self &ISpaceship); 6 | } 7 | 8 | func longerShip (a &T, b &T) &T { 9 | if (a.length() > b.length()) { ret a; } 10 | else { ret b; } 11 | } 12 | 13 | struct Raza { } 14 | impl ISpaceship for Raza; 15 | func length(r &Raza impl ISpaceship) int { 4 } 16 | func honk(r &Raza impl ISpaceship) { } 17 | 18 | struct Firefly { } 19 | impl ISpaceship for Firefly; 20 | func length(f &Firefly impl ISpaceship) int { 3 } 21 | func honk(f &Firefly impl ISpaceship) { } 22 | 23 | func crazyIvan(f &Firefly) { 24 | println("It works!"); // => It works! 25 | println("The ships length is: "); // => The ships length is: 26 | println(length(f)); // => 3 27 | } 28 | 29 | exported func main() { 30 | flametail = Firefly(); 31 | serenity = Firefly(); 32 | ship = longerShip(&flametail, &serenity); 33 | ship.crazyIvan(); 34 | } 35 | -------------------------------------------------------------------------------- /getting_input/cmd_args.vale: -------------------------------------------------------------------------------- 1 | // call with: main 1 2 2 | 3 | import stdlib.*; 4 | 5 | exported func main() { 6 | println(getMainArg(0)); // => main 7 | println(getMainArg(1)); // => 1 8 | println(getMainArg(2)); // => 2 9 | 10 | println("Number of arguments: " + numMainArgs()); // => Number of arguments: 3 11 | } 12 | 13 | 14 | // extern func numMainArgs() int; 15 | // extern func getMainArg(i int) str; 16 | -------------------------------------------------------------------------------- /getting_input/getting_input.md: -------------------------------------------------------------------------------- 1 | **cmd_args.vale**: shows how to get the command-line arguments to the program and their number 2 | 3 | **keyboard_input.vale**: shows how to read in a number with stdinReadInt(), or a random key character with __getch() 4 | -------------------------------------------------------------------------------- /getting_input/keyboard_input.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | import stdlib.stdin.*; 3 | 4 | exported func main() { 5 | // stdinReadInt reads an integer from the user's keyboard 6 | println("Give a number > 0 and < 100: "); 7 | n = stdinReadInt(); 8 | if (n <= 0 or n >= 100) { println(" Incorrect input!"); } 9 | println("The input was: " + n); // e.g. => The input was: 4 10 | 11 | arr = [](n, {_ * 5}); // type of arr here is Array. 12 | arr.each({ println(_); }); 13 | // => 14 | // 0 15 | // 5 16 | // 10 17 | // 15 18 | 19 | println("Type a random key on your keyboard: "); 20 | m = getch(); 21 | println("The key code is: " + m); // e.g. :> The key is: 115 22 | } 23 | -------------------------------------------------------------------------------- /hello_world.vale: -------------------------------------------------------------------------------- 1 | // Your first Vale program: 2 | // => ... means: program output is: ... 3 | 4 | import stdlib.*; 5 | 6 | exported func main() { 7 | println("Hello world from Vale!"); // => Hello world from Vale! 8 | } -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/Vale_Examples/4a50a3e4e42388f4a348a3b63e28c3e4785b3559/images/logo.png -------------------------------------------------------------------------------- /interfaces/interfaces.md: -------------------------------------------------------------------------------- 1 | **using_interfaces.vale**: shows how to define and use an interface in Vale - the structs Human and DarkElf both implement the interface Bipedal; the hopscotch function accepts any Bipedal as argument, so it can be called for both Human's and DarkElf's 2 | 3 | **open_interfaces.vale**: demonstrates the use of Open Interface Constructors. -------------------------------------------------------------------------------- /interfaces/open_interfaces.vale: -------------------------------------------------------------------------------- 1 | // 2021 Jan 30 2 | // Running: java -cp C:\Vale\Valestrom.jar net.verdagon.vale.driver.Driver build -o build.vast open_interfaces2.vale 3 | 4 | // internal(-13337) Conflict in determining ordinary rules' runes: InferSolveFailure(Map(ImplicitRune2(CitizenTemplateName2(IShip,0:0),0) -> MutabilityTemplataType, CodeRune2(Functor0) -> CoordTemplataType, AnonymousSubstructParentInterfaceRune2() -> KindTemplataType),Map(),None,Inferences(Map(ImplicitRune2(CitizenTemplateName2(IShip,0:0),0) -> MutabilityTemplataType, CodeRune2(Functor0) -> CoordTemplataType, AnonymousSubstructParentInterfaceRune2() -> KindTemplataType),Map(ImplicitRune2(CitizenTemplateName2(IShip,0:0),0) -> MutabilityTemplata(Mutable), AnonymousSubstructParentInterfaceRune2() -> KindTemplata(InterfaceRef2(FullName2(List(),CitizenName2(IShip,List()))))),Map()),RangeS(CodeLocationS(-13337,0),CodeLocationS(-13337,0)),Not enough to solve! Couldn't figure out: Set(CodeRune2(Functor0)),List()) 5 | 6 | import stdlib.*; 7 | 8 | interface IShip { 9 | func launch(virtual ship &IShip); 10 | } 11 | 12 | exported func main() { 13 | x = IShip({ println("Launching!"); }); 14 | // x is an unnamed substruct which 15 | // implements IShip. 16 | 17 | x.launch(); // => Launching! 18 | } -------------------------------------------------------------------------------- /interfaces/using_interfaces.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | interface Bipedal { 4 | func hop(virtual b &Bipedal) void; 5 | func skip(virtual b &Bipedal) void; 6 | } 7 | 8 | func hopscotch(b &Bipedal) { 9 | b.hop(); 10 | b.skip(); 11 | b.hop(); 12 | } 13 | 14 | struct Human { } 15 | func hop(h &Human) { println("A Human hops!"); } 16 | func skip(h &Human) { println("A Human skips!"); } 17 | impl Bipedal for Human; 18 | 19 | struct DarkElf { } 20 | func hop(s &DarkElf) { println("A DarkElf hops!"); } 21 | func skip(s &DarkElf) { println("A DarkElf skips!"); } 22 | impl Bipedal for DarkElf; 23 | 24 | exported func main() { 25 | wulfgar = Human(); 26 | hopscotch(&wulfgar); 27 | drizzt = DarkElf(); 28 | hopscotch(&drizzt); 29 | } 30 | 31 | // A Human hops! 32 | // A Human skips! 33 | // A Human hops! 34 | // A DarkElf hops! 35 | // A DarkElf skips! 36 | // A DarkElf hops! -------------------------------------------------------------------------------- /miscellaneous/main_ret.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() int { 4 | // ret 42; 5 | // = 42; 6 | 42 7 | } -------------------------------------------------------------------------------- /miscellaneous/miscellaneous.md: -------------------------------------------------------------------------------- 1 | **main_ret.vale**: shows that main() can also return a value to the calling script 2 | 3 | **cmd_args.vale**: shows how to get the command-line arguments to the program and their number 4 | 5 | **vassert.vale**: shows the vassert function, which is the assert functionality in Vale 6 | 7 | **panic.vale**: shows the use of the __panic() and panic(message) functions, which stop a program, and in the case of panic(message), first displays a message to standard output 8 | 9 | **unreachable.vale**: demonstrates the use of panic(message) in unreachable code; if ever this panic() is reached, it shows this line could be reached! -------------------------------------------------------------------------------- /miscellaneous/panic.vale: -------------------------------------------------------------------------------- 1 | // panic with a string argument prints the message and exits, 2 | // __panic exits immediately. 3 | 4 | import stdlib.*; 5 | 6 | exported func main() { 7 | println("before panic1"); 8 | // panic 1: 9 | panic(); // exits program without message 10 | // when panic1 is commented out: 11 | println("between panic1 and 2"); 12 | // panic 2: 13 | panic("panic 2: How on earth did this happen?"); // => panic 2: How on earth did this happen? 14 | println("after panic2"); // never printed 15 | } -------------------------------------------------------------------------------- /miscellaneous/unreachable.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() int { 4 | while true { 5 | if true { 6 | ret 42; 7 | } 8 | // continue loop 9 | } 10 | // never reached: 11 | panic("should be unreachable"); 12 | } 13 | -------------------------------------------------------------------------------- /miscellaneous/vassert.vale: -------------------------------------------------------------------------------- 1 | // vassert(boolean expression, message): 2 | // the expression must return either true or false 3 | // if true, nothing happens; if false, the message is printed out. 4 | 5 | // The program stops at the 1st vassert that fails, displaying the error message. 6 | 7 | import stdlib.*; 8 | 9 | exported func main() { 10 | vassert(true, "Test 1 succeeded!"); 11 | vassert(false, "Test 2 failed!"); // program exits here with => Test 2 failed! 12 | 13 | vassert(2 == 2, "Ok"); 14 | vassert(2 < 5, "Also ok"); 15 | vassert(2 > 5, "Not so true!"); // => Not so true! 16 | } -------------------------------------------------------------------------------- /patterns/destructuring.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Vec3 imm { 4 | x int; 5 | y int; 6 | z int; 7 | } 8 | 9 | func makeVec() Vec3 { Vec3(3, 4, 5) } 10 | 11 | exported func main() { 12 | // Without destructure pattern: 13 | tempVec = makeVec(); 14 | a = tempVec.x; 15 | b = tempVec.y; 16 | c = tempVec.z; 17 | 18 | println("a, b and c are resp.: " + a + ", " + b + ", " + c); 19 | // => a, b and c are resp.: 3, 4, 5 20 | 21 | // Equivalent, using a destructure: 22 | Vec3[d, e, f] = makeVec(); 23 | 24 | // Equivalent; can leave off the type: 25 | [g, h, i] = makeVec(); 26 | 27 | println("a: " + a); // => 3 28 | println("d: " + d); // => 3 29 | println("g: " + g); // => 3 30 | } -------------------------------------------------------------------------------- /patterns/patterns.md: -------------------------------------------------------------------------------- 1 | **destructuring.vale**: the contents of a Vec struct is destructured into three locals in one line: (g, h, i) = makeVec(); -------------------------------------------------------------------------------- /patterns/tuple_destructuring.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | n = 5; 5 | [g, h] = double(5); 6 | println("The double of " + g + " is: " + h); 7 | // => The double of 5 is: 10 8 | } 9 | 10 | func double(x int) infer-ret { 11 | ret (x, x * 2); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /programming_idioms/pi1.vale: -------------------------------------------------------------------------------- 1 | // 1- Print Hello World 2 | // Print a literal string on standard output 3 | 4 | import stdlib.*; 5 | 6 | exported func main() { 7 | println("Hello world!"); // --> Hello world! 8 | } 9 | 10 | -------------------------------------------------------------------------------- /programming_idioms/pi12.vale: -------------------------------------------------------------------------------- 1 | // 12 - Check if list contains a given value x 2 | // Compile command: 3 | // python ..\valec.py build pi12.vale ..\vstl\list.vale 4 | 5 | import stdlib.*; 6 | import stdlib.collections.list.*; 7 | 8 | exported func main() { 9 | l = List(); 10 | l.add(1); 11 | l.add(3); 12 | l.add(7); 13 | l.add(42); 14 | l.add(75); 15 | l.add(81); 16 | l.add(99); 17 | l.add(108); 18 | 19 | x = 42; 20 | println(l.contains(x)); // => true 21 | y = 33; 22 | println(l.contains(y)); // => false 23 | } -------------------------------------------------------------------------------- /programming_idioms/pi13.vale: -------------------------------------------------------------------------------- 1 | // 13 - Iterate over map keys and values 2 | // Access each key k with its value x from an associative array mymap, and print them. 3 | // Compile withcommand: 4 | // python ..\valec.py build pi13.vale ..\vstl\hashmap.vale ..\vstl\list.vale 5 | 6 | import stdlib.*; 7 | import stdlib.collections.hashmap.*; 8 | import stdlib.collections.hashset.*; 9 | 10 | exported func main() { 11 | // hashmap of key int, value string 12 | map = HashMap(IntHasher(), IntEquator()); 13 | map.add(1, "one"); 14 | map.add(2, "two"); 15 | map.add(3, "three"); 16 | 17 | map.keys().each((key) => { 18 | print(key + " : "); 19 | maybeWord = map.get(key); 20 | word = (maybeWord).get(); 21 | println(word); 22 | }); 23 | } 24 | 25 | // 1 : one 26 | // 2 : two 27 | // 3 : three -------------------------------------------------------------------------------- /programming_idioms/pi19.vale: -------------------------------------------------------------------------------- 1 | // Idiom #19 Reverse a list 2 | // Reverse the order of the elements of list x. 3 | // This may reverse "in-place" and destroy the original ordering. 4 | // Compile command: 5 | // python ..\valec.py build pi19.vale ..\vstl\list.vale 6 | 7 | import stdlib.*; 8 | import stdlib.collections.list.*; 9 | 10 | exported func main() { 11 | lst = List(); 12 | lst.add(1); 13 | lst.add(3); 14 | lst.add(7); 15 | lst.add(42); 16 | lst.add(75); 17 | lst.add(81); 18 | lst.add(99); 19 | lst.add(108); 20 | 21 | println(lst.get(0)); // => 1 22 | println(lst.get(len(&lst) - 1)); // => 108 23 | lst.each( { print(_ + " / "); } ); // => 1 / 3 / 7 / 42 / 75 / 81 / 99 / 108 / 24 | println(""); 25 | 26 | i = 0; 27 | j = len(&lst) - 1; 28 | while i < j { 29 | temp = lst.get(i); 30 | lst.set(i, lst.get(j)); 31 | lst.set(j, temp); 32 | set i = i + 1; 33 | set j = j - 1; 34 | } 35 | 36 | println(lst.get(0)); // => 108 37 | println(lst.get(len(&lst) - 1)); // => 1 38 | lst.each( { print(_ + " / "); } ); // => 108 / 99 / 81 / 75 / 42 / 7 / 3 / 1 / 39 | } -------------------------------------------------------------------------------- /programming_idioms/pi2.vale: -------------------------------------------------------------------------------- 1 | // 2- Print Hello World 10 times 2 | // Loop to execute some code a constant number of times num 3 | 4 | import stdlib.*; 5 | 6 | exported func main() { 7 | num int = 1; 8 | while num <= 10 { 9 | println(num + ": Hello"); 10 | set num = num + 1; 11 | } 12 | } 13 | 14 | // 1: Hello 15 | // 2: Hello 16 | // 3: Hello 17 | // 4: Hello 18 | // 5: Hello 19 | // 6: Hello 20 | // 7: Hello 21 | // 8: Hello 22 | // 9: Hello 23 | // 10: Hello -------------------------------------------------------------------------------- /programming_idioms/pi20.vale: -------------------------------------------------------------------------------- 1 | // Idiom #20 - Return two values 2 | // Implement a function search which looks for item x in a 2D matrix m. 3 | // Return indices i, j of the matching cell. 4 | // Think of the most idiomatic way in the language to return 5 | // the two values at the same time. 6 | 7 | import stdlib.*; 8 | 9 | exported func main() { 10 | sm = [#][ [#][1, 2, 3], [#][4, 5, 6], [#][7, 8, 9] ]; 11 | to_search = 4; 12 | 13 | found = false; 14 | foreach [i, m1] in sm.entries() { 15 | foreach [j, m2] in m1.entries() { 16 | if m2 == to_search { 17 | set found = true; 18 | println("The number " + to_search + " was found on row " + i + " and column " + j); 19 | } 20 | } 21 | } 22 | if not found { 23 | println("The number " + to_search + " was not found!"); 24 | } 25 | // => The number 4 was found on row 1 and column 0 26 | 27 | // searching in a range (s is number to search): 28 | s = 1; 29 | while s <= 11 { 30 | set found = false; 31 | foreach [i, m1] in sm.entries() { 32 | foreach [j, m2] in m1.entries() { 33 | if m2 == s { 34 | set found = true; 35 | println("The number " + s + " was found on row " + i + " and column " + j); 36 | } 37 | } 38 | } 39 | if not found { 40 | println("The number " + s + " was not found!"); 41 | } 42 | set s = s + 2; 43 | } 44 | // => 45 | // The number 1 was found on row 0 and column 0 46 | // The number 3 was found on row 0 and column 2 47 | // The number 5 was found on row 1 and column 1 48 | // The number 7 was found on row 2 and column 0 49 | // The number 9 was found on row 2 and column 2 50 | // The number 11 was not found! 51 | } -------------------------------------------------------------------------------- /programming_idioms/pi21.vale: -------------------------------------------------------------------------------- 1 | // Idiom # 21 - Swap values 2 | 3 | import stdlib.*; 4 | 5 | exported func main() { 6 | a = 1; 7 | b = 2; 8 | 9 | println("a is: " + a); // => a is: 1 10 | println("b is: " + b); // => b is: 2 11 | 12 | temp = a; 13 | set a = b; 14 | set b = temp; 15 | 16 | println("a is: " + a); // => a is: 2 17 | println("b is: " + b); // => b is: 1 18 | } -------------------------------------------------------------------------------- /programming_idioms/pi3.vale: -------------------------------------------------------------------------------- 1 | // 3- Create a procedure 2 | // Like a function which doesn't return any value, thus has only side effects 3 | // (e.g. Print to standard output) 4 | 5 | import stdlib.*; 6 | 7 | exported func main() { 8 | finish("All"); 9 | } 10 | 11 | func finish(name str) { 12 | println("My job here is done. Good bye " + name + "!"); 13 | } 14 | 15 | // => My job here is done. Good bye All! 16 | -------------------------------------------------------------------------------- /programming_idioms/pi4.vale: -------------------------------------------------------------------------------- 1 | // 4- Create a function which returns the square of an integer 2 | 3 | import stdlib.*; 4 | 5 | exported func main() { 6 | println(square(9)); 7 | } 8 | 9 | func square(i int) int { 10 | i * i 11 | } 12 | 13 | // --> 81 14 | // different variations possible, also as inner function 15 | -------------------------------------------------------------------------------- /programming_idioms/pi5.vale: -------------------------------------------------------------------------------- 1 | // 5- Create a 2D Point data structure 2 | // Declare a container type for two floating-point numbers x and y 3 | // Feb 12 2021 - no print for float exist, --> int 4 | 5 | import stdlib.*; 6 | 7 | struct Point { 8 | x int; 9 | y int; 10 | } 11 | 12 | exported func main() { 13 | p1 = Point(2, 3); 14 | println(p1.x); // => 2 15 | println(p1.y); // => 3 16 | } -------------------------------------------------------------------------------- /programming_idioms/pi6.vale: -------------------------------------------------------------------------------- 1 | // 6 - Iterate over list values 2 | // Do something with each item x of an array-like collection items, regardless indexes. 3 | 4 | import stdlib.*; 5 | 6 | exported func main() { 7 | lst = [#]["Storm", "Earth", "Fire"]; // this is a static-sized array in Vale 8 | foreach x in lst { 9 | println(x); 10 | } 11 | } 12 | 13 | // => 14 | // Storm 15 | // Earth 16 | // Fire -------------------------------------------------------------------------------- /programming_idioms/pi7.vale: -------------------------------------------------------------------------------- 1 | // 7 - Iterate over list indexes and values 2 | // Print each index i with its value x from an array-like collection items 3 | 4 | import stdlib.*; 5 | 6 | exported func main() { 7 | lst = [#]["Storm", "Earth", "Fire"]; // this is a static-sized array in Vale 8 | foreach [i, x] in lst.entries() { 9 | println(i + ": " + x); 10 | } 11 | } 12 | 13 | // => 14 | // 0: Storm 15 | // 1: Earth 16 | // 2: Fire -------------------------------------------------------------------------------- /programming_idioms/pi8.vale: -------------------------------------------------------------------------------- 1 | // 8 - Initialize a new map (associative array) 2 | // Create a new map object x, and provide some (key, value) pairs as initial 3 | // see roguelike.vale 4 | // Compile command: 5 | // python ..\valec.py build pi8.vale ..\vstl\hashmap.vale ..\vstl\list.vale 6 | 7 | import stdlib.*; 8 | import stdlib.collections.hashmap.*; 9 | import stdlib.collections.hashset.*; 10 | 11 | exported func main() { 12 | // hashmap of key int, value string 13 | map = HashMap(IntHasher(), IntEquator()); 14 | map.add(1, "one"); 15 | map.add(2, "two"); 16 | map.add(3, "three"); 17 | 18 | println(map.ContainsKey(2)); // => true 19 | println(map.ContainsKey(42)); // => false 20 | map.add(42, "forty-two"); 21 | println(map.ContainsKey(42)); // => true 22 | println(map.len()); // => 4 23 | 24 | arrK = map.keys(); 25 | arrK.each( { print(_ + " / "); } ); // => 1 / 2 / 3 / 42 / 26 | println(""); 27 | 28 | map.remove(3); 29 | println(map.ContainsKey(3)); // => false 30 | 31 | arrV = map.values(); 32 | arrV.each( { print(_ + " / "); } ); // => one / two / forty-two / 33 | println(""); 34 | 35 | println(map.len()); // => 3 36 | } -------------------------------------------------------------------------------- /programming_idioms/pi9.vale: -------------------------------------------------------------------------------- 1 | // 9- Create a binary tree data structure 2 | // The structure must be recursive because left child and right child are binary trees too. 3 | // A node has access to children nodes, but not to its parent. 4 | 5 | import stdlib.*; 6 | 7 | struct BinTreeNode { 8 | value int; 9 | left Opt; 10 | right Opt; 11 | } 12 | 13 | exported func main() { 14 | root = 15 | BinTreeNode( 16 | 7, 17 | None(), 18 | Some( 19 | BinTreeNode( 20 | 42, 21 | None(), 22 | None()))); 23 | } -------------------------------------------------------------------------------- /programming_idioms/programming_idioms.md: -------------------------------------------------------------------------------- 1 | In this folder, a number of programming idioms tasks from [programming idioms](https://www.programming-idioms.org/about#about-block-all-idioms) are implemented 2 | code in piIdiom #n.vale , where n = 1 .. 3 | 4 | # 1: Print Hello World 5 | # 2: Print Hello 10 times 6 | # 3: Create a procedure 7 | # 4: Create a function which returns the square of an integer 8 | # 5: Create a 2D Point data structure 9 | # 6: Iterate over list values 10 | # 7: Iterate over list indexes and values 11 | # 8: Initialize a new map (associative array) 12 | # 9: Create a binary tree data structure 13 | # 12: Check if list contains a value 14 | # 13: Iterate over map keys and values 15 | # 19: Reverse a list 16 | # 20: Return two values 17 | # 21: Swap values 18 | 19 | -------------------------------------------------------------------------------- /push.bat: -------------------------------------------------------------------------------- 1 | cd d:\Vale\Vale_Examples 2 | git add . 3 | git commit -m "new examples ffi to c" 4 | git push -------------------------------------------------------------------------------- /references/constraint_ref.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Carrier { 4 | hp int; 5 | interceptors int; 6 | } 7 | 8 | struct Spaceship { 9 | name str; 10 | numWings int; 11 | } 12 | 13 | func display(s &Spaceship) { 14 | println(s.name); 15 | } 16 | 17 | exported func main() { 18 | carrier = Carrier(400, 8); 19 | ref = &carrier; 20 | println(ref.interceptors); // => 8 21 | 22 | ship = Spaceship("Serenity", 2); 23 | display(&ship); // => Serenity 24 | // you can still use the owning reference ship: 25 | println(ship.numWings); // => 2 26 | } -------------------------------------------------------------------------------- /references/constraint_ref_del1.vale: -------------------------------------------------------------------------------- 1 | // When running: 2 | // Error: Dangling pointers detected! 3 | 4 | import stdlib.*; 5 | 6 | struct Marine { hp int; } 7 | 8 | exported func main() { 9 | m = Marine(7); 10 | b = &m; 11 | drop(m); // halts in Assist mode 12 | println(b.hp); // halts in Resilient mode 13 | } 14 | -------------------------------------------------------------------------------- /references/constraint_ref_del2.vale: -------------------------------------------------------------------------------- 1 | // Name: Serenity 2 | // Assertion failed! Expected 1 to equal 0. 3 | // Tried to free concrete that had nonzero RC! Exiting! 4 | // Solutions: constraint_ref_del_solution1.vale / constraint_ref_del_solution2.vale 5 | 6 | import stdlib.*; 7 | 8 | struct Spaceship { 9 | name str; 10 | numWings int; 11 | } 12 | 13 | func takeAndDestroy(ship Spaceship) { 14 | println("Name: " + ship.name); 15 | // ship is destroyed here, so constraint ref shipCRef is violated! 16 | } 17 | 18 | // Halting version: 19 | exported func main() { 20 | ship = Spaceship("Serenity", 2); // ship contains an owning ref 21 | shipCRef = &ship; // shipCRef contains a constraint ref 22 | 23 | // Move (the ownership of) ship into a function: 24 | takeAndDestroy(ship); 25 | // program halts here in Assist mode, even without the println line below 26 | 27 | // try to acces ship via constraint ref, but ship is already destroyed: 28 | // println("Wings: " + shipCRef.numWings); // --> halts here in Resilient mode 29 | } -------------------------------------------------------------------------------- /references/constraint_ref_del2_solution.vale: -------------------------------------------------------------------------------- 1 | // Solution 1: Use a local to store the data you still need, 2 | // instead of a constraint ref: 3 | 4 | import stdlib.*; 5 | 6 | struct Spaceship { 7 | name str; 8 | numWings int; 9 | } 10 | 11 | func takeAndDestroy(ship Spaceship) { 12 | println("Name: " + ship.name); 13 | // Ship is destroyed here, so constraint ref is violated! 14 | } 15 | 16 | exported func main() { 17 | ship = Spaceship("Serenity", 2); // ship contains an owning ref 18 | // shipCRef = &ship; // don't create a constraint ref! 19 | // use a local to store the data: 20 | wings = ship.numWings; 21 | // Move (the ownership of) ship into a function. 22 | takeAndDestroy(ship); // Name: Serenity 23 | println("Wings: " + wings); // => Wings: 2 24 | } 25 | -------------------------------------------------------------------------------- /references/references.md: -------------------------------------------------------------------------------- 1 | **refto_immutables.vale**: shows that immutable structs can have multiple owning references 2 | 3 | **constraint_ref.vale**: shows that when a constraint reference is made to a mutable struct, the owning reference can still be used 4 | 5 | **constraint_ref_del1.vale**: 6 | **constraint_ref_del2.vale**: show that when a mutable struct is dropped, while there is still a constraint reference to it, the program halts when running in Assist mode 7 | How to solve this: 8 | - Use locals: **constraint_ref_del2_solution.vale** 9 | 10 | **weak_references.vale**: shows how to lock a weak ref to extract possible contents 11 | 12 | Inlining can be used for optimization 13 | **simple_inlining.vale** 14 | **structs_inline.vale** 15 | 16 | -------------------------------------------------------------------------------- /references/refto_immutables.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Vec3 imm { 4 | x int; 5 | y int; 6 | z int; 7 | } 8 | 9 | exported func main() { 10 | firstRef = Vec3(3, 4, 5); 11 | otherRef = firstRef; 12 | // otherRef = &firstRef; // works also as a constrained reference 13 | thirdRef = firstRef; 14 | // Can use all references freely: 15 | println(firstRef.x + otherRef.y + thirdRef.z); // => 12 16 | } -------------------------------------------------------------------------------- /references/simple_inlining.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Spaceship { 4 | name str; 5 | numWings int; 6 | } 7 | 8 | exported func main() { 9 | ship = inl Spaceship("Enterprise", 4); 10 | println(ship.name); // => Enterprise 11 | } -------------------------------------------------------------------------------- /references/structs_inline.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Engine { 4 | model str; 5 | fuel int; 6 | } 7 | 8 | struct Spaceship { 9 | name str; 10 | engine Engine; 11 | } 12 | 13 | exported func main() { 14 | ship = Spaceship( 15 | "Serenity", 16 | Engine("TCB", 10)); 17 | println(ship.name); // => Serenity 18 | println(ship.engine.model); // => TCB 19 | println(ship.engine.fuel); // => 10 20 | } -------------------------------------------------------------------------------- /references/weak_references.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | weakable struct Base { 4 | name str; 5 | } 6 | 7 | struct Spaceship { 8 | name str; 9 | origin **Base; 10 | } 11 | 12 | func printShipBase(ship &Spaceship) { 13 | maybeOrigin = lock(ship.origin); 14 | if not maybeOrigin.isEmpty() { 15 | o = maybeOrigin.get(); 16 | println("Ship base: " + o.name); 17 | } else { 18 | println("Ship base unknown!"); 19 | } 20 | } 21 | 22 | exported func main() { 23 | base = Base("Zion"); 24 | ship = Spaceship("Neb", **base); 25 | 26 | printShipBase(&ship); // => Ship base: Zion 27 | drop(base); // Destroys base. 28 | printShipBase(&ship); // => Ship base unknown! 29 | } -------------------------------------------------------------------------------- /strings/string_functions.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | import stdlib.stringutils.*; 3 | 4 | exported func main() { 5 | // compare with spaceship operator <=> (useful for sorting) 6 | println("abc" <=> "abc"); // => 0 7 | println("abc" <=> "abd"); // => -1 8 | println("abc" <=> "abb"); // => 1 9 | println("abc" <=> "ab"); // => 1 10 | println("abc" <=> "abce"); // => -1 11 | 12 | testString = "Hello world!"; 13 | // slicing: 14 | println(slice(testString, 1, 7)); // => ello w 15 | println(slice(testString, 1, 7).str()); // => ello w 16 | 17 | // find: 18 | println(find(testString, "bork").isEmpty()); // => true 19 | println(find(testString, "world").get()); // => 6 20 | 21 | // startsWith: 22 | println(testString.startsWith("Hel")); // => true 23 | println(not testString.startsWith("Bork")); // => true 24 | 25 | // endsWith 26 | println(testString.endsWith("ld!")); // => true 27 | println(not testString.endsWith("Bork")); // => true 28 | } 29 | -------------------------------------------------------------------------------- /strings/strings.md: -------------------------------------------------------------------------------- 1 | **strings.vale**: declaring strings, length, concatenating strings, converting other types to string 2 | 3 | **string_functions.vale**: common string functionality like <=>, slicing, find, startsWith, endsWith 4 | 5 | split, join: see **lists** 6 | -------------------------------------------------------------------------------- /strings/strings.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | // declaring strings: 5 | // immutable: 6 | a str = "hello!"; 7 | b = "goodbye!"; 8 | // mutable: 9 | c = "end"; 10 | set c = "beginning"; 11 | 12 | // length of a string: 13 | println(len("Orion")); // => 5 14 | // both work, because of UFCS (Universal Function Call Syntax): 15 | println(len(c)); // => 9 16 | println(c.len()); // => 9 17 | 18 | empty = ""; // empty string 19 | println(empty); // => 20 | println(len(empty)); // => 0 21 | 22 | // adding (concatenating) strings: 23 | str1 = "Glory to the"; 24 | str2 = "Lizard People"; 25 | combined = str1 + " " + str2; // inserting a space 26 | println(combined); // => Glory to the Lizard People 27 | println("Escape from the " + str2); // => Escape from the Lizard People 28 | // concatenation of string and integer: 29 | println("The holy number is: " + 108); // => The holy number is: 108 30 | 31 | // equality (==) / not equal (!=): 32 | println(combined == "Glory to the Lizard People"); // => true 33 | println("abc" == "def"); // => false 34 | println("abc" != "def"); // => true 35 | 36 | // conversion from int and bool to str: 37 | s = str(108); 38 | println(s); // => 108 39 | 40 | bool1 = str(false); 41 | println(bool1); // => false 42 | println("***********************************"); 43 | 44 | // ' and escape sequences: 45 | s1 = "I'm always working to improve Vale!"; // => I'm always working to improve Vale! 46 | println(s1); 47 | 48 | // escape sequences (\n, \r, \t, ...) work: 49 | println("\tT"); // => T 50 | 51 | // escaping characters: 52 | println("\\"); // => \ 53 | println("\""); // => " 54 | println("\u0000"); // => 55 | } -------------------------------------------------------------------------------- /structs/embedding_structs.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct MyStruct { a int; } 4 | struct OtherStruct { b MyStruct; } 5 | 6 | struct Outer { 7 | inner Inner; 8 | } 9 | 10 | struct Inner { 11 | x! int; 12 | } 13 | 14 | exported func main() { 15 | ms = OtherStruct(MyStruct(11)); 16 | println(ms.b.a); // => 11 17 | 18 | o = Outer(Inner(73)); 19 | set o.inner.x = 42; 20 | println(o.inner.x); // => 42 21 | } -------------------------------------------------------------------------------- /structs/embedding_structs2.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Thing { 4 | v! Vec3i; 5 | } 6 | 7 | struct Vec3i { 8 | x int; 9 | y int; 10 | z int; 11 | } 12 | 13 | func bork(thing &Thing, v Vec3i) { 14 | set thing.v = v; 15 | } 16 | 17 | exported func main() { 18 | thing = Thing(Vec3i(7, 8, 9)); 19 | println(thing.v.y); // => 8 20 | bork(&thing, Vec3i(4, 5, 6)); 21 | println(thing.v.y); // => 5 22 | } 23 | -------------------------------------------------------------------------------- /structs/immutable_structs.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Spaceship imm { 4 | name str; 5 | numWings int; 6 | } 7 | 8 | struct Soldier imm { 9 | hp int; 10 | mp int; 11 | armor int; 12 | strength int; 13 | agility int; 14 | intelligence int; 15 | } 16 | 17 | struct Vec3i imm { 18 | x int; 19 | y int; 20 | z int; 21 | } 22 | 23 | exported func main() { 24 | ship = Spaceship("Serenity", 2); 25 | println(ship.numWings); // => 2 26 | // ship.name = "XXX"; // error: expected `;` or `}` after expression, but found: = "XXX"; 27 | ship2 = ship; 28 | println(ship.numWings); // => 2 29 | println(ship2.numWings); // => 2 30 | 31 | sd = Soldier(4, 5, 6, 7, 42, 9); 32 | println(sd.agility); // => 42 33 | 34 | println(Vec3i(4, 5, 6).y); // => 5 35 | } -------------------------------------------------------------------------------- /structs/lending.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Spaceship { 4 | name str; 5 | numWings int; 6 | } 7 | 8 | exported func main() { 9 | owningRef = Spaceship("Serenity", 2); 10 | nonOwningRef = &owningRef; // nonOwningRef is a constraint reference 11 | println(owningRef.name); // => Serenity 12 | println(nonOwningRef.name); // => Serenity 13 | } -------------------------------------------------------------------------------- /structs/list_structs.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | import stdlib.collections.list.*; 3 | 4 | struct Ship { 5 | name str; 6 | size int; 7 | } 8 | 9 | exported func main() { 10 | allShips = List(); 11 | allShips.add(Ship("Serenity", 9)); 12 | allShips.add(Ship("Raza", 7)); 13 | allShips.add(Ship("Dark Star", 42)); 14 | 15 | println(len(&allShips)); // => 3 16 | 17 | second = allShips.get(1); 18 | println("The size of the second ship is: " + second.size); 19 | // => The size of the second ship is: 7 20 | } -------------------------------------------------------------------------------- /structs/move_function.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Spaceship { 4 | name str; 5 | numWings int; 6 | } 7 | 8 | func display(b Spaceship) { 9 | println(b.name); // => Enterprise 10 | // b will be dropped after the closing } 11 | } 12 | 13 | exported func main() { 14 | a = Spaceship("Enterprise", 4); 15 | // Move the Spaceship from a into display's argument b 16 | display(a); 17 | // Can't use anymore - a will be dropped after the closing } 18 | } -------------------------------------------------------------------------------- /structs/moving.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Spaceship { 4 | name str; 5 | numWings int; 6 | } 7 | 8 | exported func main() { 9 | a = Spaceship("Serenity", 2); 10 | b = a; // Move the ownership from a to b 11 | // b now owns the Spaceship: 12 | println(b.name); // Serenity 13 | // println(a.name); // error: Can't use local that was already moved 14 | } -------------------------------------------------------------------------------- /structs/struct_constructor.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | struct Spaceship { 4 | name str; 5 | numWings int; 6 | } 7 | 8 | // constructor: 9 | func Spaceship() Spaceship { 10 | Spaceship("Serenity", 2) 11 | } 12 | 13 | struct Marine { 14 | hp int; 15 | cool bool; 16 | } 17 | 18 | func Marine() Marine { 19 | // alternative for Marine(10, true) 20 | self.hp = 10; 21 | self.cool = true; 22 | } 23 | 24 | struct Carrier { 25 | hp int; 26 | interceptors int; 27 | } 28 | 29 | exported func main() { 30 | ship = Spaceship(); 31 | println(ship.name); // => Serenity 32 | 33 | mar = Marine(); 34 | println(mar.hp); // => 10 35 | 36 | mar2 = Marine(9, false); 37 | println(mar2.cool); // => false 38 | 39 | println(Carrier(400, 8).interceptors); // => 8 40 | } -------------------------------------------------------------------------------- /structs/struct_definition.vale: -------------------------------------------------------------------------------- 1 | // struct with immutable fields: 2 | 3 | import stdlib.*; 4 | 5 | struct Spaceship { 6 | name str; 7 | numWings int; 8 | } 9 | 10 | // structs with mutable fields: 11 | struct MSpaceship { 12 | name! str; 13 | numWings! int; 14 | } 15 | 16 | // immutable struct: 17 | struct ImmSpaceship imm { 18 | name str; 19 | numWings int; 20 | } 21 | 22 | struct Marine { hp! int; } 23 | 24 | struct Carrier { 25 | hp int; 26 | interceptors! int; 27 | } 28 | 29 | exported func main() { 30 | ship = Spaceship("Serenity", 2); // <-- ship is an owning reference 31 | println(ship.name); // => Serenity 32 | 33 | shipI = ImmSpaceship("Sol", 6); // <-- shipI is an owning reference 34 | println(shipI.name); // => Sol 35 | 36 | // how to change struct values: 37 | ship2 = MSpaceship("Serenity", 2); 38 | set ship2.name = "Enterprise"; 39 | set ship2.numWings = 3; 40 | println(ship2.name); // => Enterprise 41 | println(ship2.numWings); // => 3 42 | 43 | m = Marine(9); 44 | set m.hp = 4; 45 | println(m.hp); // => 4 46 | 47 | c = Carrier(400, 8); 48 | set c.interceptors = 42; 49 | println(c.interceptors); // => 42 50 | // implicitly drops ship by calling implicit ship^.drop(), 51 | // same for ship2, m and c 52 | } 53 | 54 | // Implicit: 55 | // func drop(s Spaceship) { 56 | // destruct s; // frees the memory 57 | // } -------------------------------------------------------------------------------- /structs/structs.md: -------------------------------------------------------------------------------- 1 | **struct_definition.vale**: how to define a struct with mutable fields or an immutable struct; 2 | 3 | **struct_constructor.vale**: how to define and use a struct constructor; 4 | 5 | **lending.vale**: shows an owning reference and a constraint (non-owning) reference to a struct instance 6 | 7 | **moving.vale**: shows the moving of ownership to another local 8 | 9 | **move_function.vale**: shows the moving of ownership into a function 10 | 11 | **immutable_structs.vale**: shows that immutable structs can have multiple owning references 12 | 13 | **embedding_structs.vale**: shows how a struct can contain fields of other structs 14 | 15 | **embedding_structs2.vale**: shows how a field of an immutable struct type can be mutable 16 | 17 | **list_structs.vale**: shows how to make a list of structs 18 | 19 | 20 | -------------------------------------------------------------------------------- /variables/locals.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | // typed locals: 5 | b bool = true; 6 | n int = 42; 7 | v str = "Vale"; 8 | 9 | // type inference at assignment: 10 | x = "Hi all!"; 11 | println(x); // => Hi all! 12 | } 13 | 14 | -------------------------------------------------------------------------------- /variables/locals_mut.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | n int = 73; 5 | // mutate variable: 6 | set n = 42; 7 | println(n); // => 42 8 | 9 | // variable with type inference: 10 | x = "Europe!"; 11 | set x = "Antarctica!"; 12 | println(x); // => Antarctica! 13 | } -------------------------------------------------------------------------------- /variables/nested_shadowed.vale: -------------------------------------------------------------------------------- 1 | import stdlib.*; 2 | 3 | exported func main() { 4 | a = 1; 5 | println("Oops!"); // => Oops! 6 | { 7 | println("Nested code block"); // => Nested code block 8 | a = 54; 9 | println(a); // => 54 10 | }(); 11 | println(a); // => 1 12 | b = 5; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /variables/variables.md: -------------------------------------------------------------------------------- 1 | **locals.vale**: shows how to declare local variables (locals) with explicit type and with type inference; variables are by default immutable 2 | 3 | **locals_mut.vale**: shows how to declare mutable variables 4 | 5 | **add_ints.vale**: shows adding integers --------------------------------------------------------------------------------