diff --git a/README.md b/README.md index 62418b3..2aabe16 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The text is backed by some 300 complete working Jai examples and growing. They a Many thanks to Daniel Tan for setting up the [Jai-Community](https://jai.community/) and the [Jai Wiki](https://github.com/Jai-Community/Jai-Community-Library/wiki). Also thanks to mehlian, seneca, ramin-asadi-2021 and Jakub Arnold(@darthdeus) for their remarks and contributions. -[Text content adapted and code tested to compile/run with Jai version beta 0.1.065, built on June 4 2023] +[Text content adapted and code tested to compile/run with Jai version beta 0.1.069, built on 24 June 2023] _Table of Contents_ diff --git a/book/12_Basics of structs.md b/book/12_Basics of structs.md index daae3de..6cc8002 100644 --- a/book/12_Basics of structs.md +++ b/book/12_Basics of structs.md @@ -569,7 +569,7 @@ can be divided into: ## 12.11 Struct alignment By aligning certain member fields of structs to 64 bit, we can make memory allocation cache-aligned on 64 bit systems. This can also be done for global variables. -The **#align** directive takes care of aligning struct member fields relative to the start of the struct. If the start is 64 bit aligned, and a member field has #align 64, then this field will also be 64 bit aligned. The same goes for `#align 32` and `#align 16`. +The **#align** directive takes care of aligning struct member fields relative to the start of the struct. If the start is 64 bit aligned, and a member field has #align 64, then this field will also be 64 bit aligned. The same goes for `#align 32` and `#align 16`. It also works for declarations on the stack. The start of the struct must be #align-ed correctly, otherwise it won't work. This enhances memory efficiency and reduces cache misses for cache-sensitive data-structures. Use it when you want to do SIMD (see § 28) or you need something with a bigger alignment. It is used in the following example: diff --git a/book/13_Unions and enums.md b/book/13_Unions and enums.md index 430f12d..7d34435 100644 --- a/book/13_Unions and enums.md +++ b/book/13_Unions and enums.md @@ -258,7 +258,7 @@ main :: () { d &= ~SOUTH; // (1) mask the SOUTH flag print("d is %\n", d); // => d is EAST | NORTH | WEST - e: Direction = Direction.WEST | .EAST; // (1) + e: Direction = .WEST | .EAST; // (1) f: Direction = .WEST; g: Direction = 1; h: Direction = Direction.WEST + 1; diff --git a/book/17_Basics of procedures.md b/book/17_Basics of procedures.md index 78f1bc6..4feea54 100644 --- a/book/17_Basics of procedures.md +++ b/book/17_Basics of procedures.md @@ -322,7 +322,8 @@ The returned values are assigned to an equal number of variables in the left-han It is not necessary to assign all return values, as in (2B) where we ignore the 2nd return value. It is better to return things by value; this avoids having extra stack copies like in C. -**The _ token** +**The _ identifier** +The name `_` represents values you do not care about. You can use this in cases when you would otherwise make up a temporary junk variable name. _ always exists and does not have to be declared. If you would like to discard one or more of the return values, use `_` instead of a variable as in Go, like this: `result, ok, _ := to_integer(text);` Here we discard the 3rd return value, which is a `remainder` string in which we are not interested. diff --git a/book/1B_What_is_Jai - more in depth.md b/book/1B_What_is_Jai - more in depth.md index 8a95ef2..d25896b 100644 --- a/book/1B_What_is_Jai - more in depth.md +++ b/book/1B_What_is_Jai - more in depth.md @@ -198,4 +198,5 @@ Blow's videos about the design and making of Jai are very popular: They get view 2022 Nov 13: 300 people on Discord 2022 Dec 12: 328 people enrolled in the closed beta 2023 Jan 2: 349 people enrolled in the closed beta -2023 Feb 21: Reddit subscribers: 1762 \ No newline at end of file +2023 Feb 21: Reddit subscribers: 1762 +2023 Jun 20: 550 people enrolled in the closed beta \ No newline at end of file diff --git a/book/30_Integrated_build_system.md b/book/30_Integrated_build_system.md index cf3535f..4e712f2 100644 --- a/book/30_Integrated_build_system.md +++ b/book/30_Integrated_build_system.md @@ -215,7 +215,7 @@ See *30.12_placeholder.jai*: #run { #import "Compiler"; options := get_build_options(); - add_build_string("TRUTH :: true;"); // (2) + add_build_string("TRUTH :: true;", -1); // (2) } main :: () { @@ -224,7 +224,7 @@ main :: () { } ``` The **#placeholder** directive specifies to the compiler that a particular symbol will be defined/generated by the compile-time meta-program. -In the program code, the constant TRUTH is 'announced' in line (1), it only gets declared in the #run block with the proc `add_build_string` in line (2). Note how `#import "Compiler";` also can be done in the #run block. +In the program code, the constant TRUTH is 'announced' in line (1), it only gets declared in the #run block with the proc `add_build_string` in line (2). The 2nd argument in line (2) is the workspace, -1 is a value indicating the current workspace. Note how `#import "Compiler";` also can be done in the #run block. `add_build_string` adds a string as a piece of code to the program. The first argument is a string, the second argument is the workspace (see § 30.1) you want to add it to. You can do all sorts of complex string manipulation to create complex meta-programming code, then add it to your build in string format. diff --git a/book/5_Constants, variables, types and operations.md b/book/5_Constants, variables, types and operations.md index 6278383..b06bb66 100644 --- a/book/5_Constants, variables, types and operations.md +++ b/book/5_Constants, variables, types and operations.md @@ -361,6 +361,14 @@ main :: () { print("n4 is % and m4 is %\n", n4, m4); // => n4 is 0 and m4 is 0 n4, m4 = 1, 2; print("n4 is % and m4 is %\n", n4, m4); // => n4 is 1 and m4 is 2 + + // advanced compound assignment: + b := 5; + a, b=, c := 1, 2, 3; // (4) + print("a is % b is % c is %\n", a, b, c); // => a is 1 b is 2 c is 3 + a, d:, c = 4, 5, 6; // (5) + print("a is % c is % d is %\n", a, c, d); // => a is 4 c is 6 d is 5 + } ``` @@ -370,6 +378,9 @@ A compound assignment like in line (2) is not allowed, but you can write: `n3, m3 := 12, 13;` The right-hand sides in such a _multiple assignment_ can also contain expressions, even calculated at compile-time with #run. If wanted, declaration and assignment can be on separate lines. +Modification assignments and declarations can be combined in one assignment: +In line (4), b is modified, a and c are declared. +In line (5), d is declared, a and c are modified. ## 5.6 - Swapping values See *5.5_swapping.jai*: @@ -380,8 +391,8 @@ See *5.5_swapping.jai*: main :: () { n := 2; m := 3; - // n, m = m, n; - print("n is % and m is %\n", n, m); // (1) => n is 3 and m is 3 + n, m = m, n; + print("n is % and m is %\n", n, m); // (1) => n is 3 and m is 2 s, p := "abc", 13; // this gives an error: @@ -389,9 +400,9 @@ main :: () { } ``` -A swap like n, m = m, n; is allowed, but doesn't work in Jai like you would expect (see line (1)): both variables get the same value. It works like this: `x, y = y, x` does `x = y; y = x;` and not like in Python for example. The reason is when one gets too picky about what order things happen in, this causes problems for compiler optimizations. -Also when n and m are of different types an error results, because then the variables would have to change type, which is not allowed. -But see § 17.10 for a swap procedure and § 22.2.3 for built-in versions. +A compound assignment like n, m = m, n; is allowed, and results in a swap of the values. +When n and m are of different types an error results, because then the variables would have to change type, which is not allowed. +(See § 17.10 for a swap procedure and § 22.2.3 for built-in versions.) ## 5.7 - More about printing print is a native routine. diff --git a/examples/13/13.3_enum_flags.jai b/examples/13/13.3_enum_flags.jai index 8763fc5..b7b31f6 100644 --- a/examples/13/13.3_enum_flags.jai +++ b/examples/13/13.3_enum_flags.jai @@ -19,7 +19,7 @@ main :: () { d &= ~SOUTH; // mask the SOUTH flag print("d is %\n", d); - e: Direction = Direction.WEST | .EAST; // (1) + e: Direction = .WEST | .EAST; // (1) f: Direction = .WEST; g: Direction = 1; h: Direction = Direction.WEST + 1; diff --git a/examples/30/30.12_placeholder.jai b/examples/30/30.12_placeholder.jai index 9774f69..06db68c 100644 --- a/examples/30/30.12_placeholder.jai +++ b/examples/30/30.12_placeholder.jai @@ -5,7 +5,7 @@ #run { #import "Compiler"; options := get_build_options(); - add_build_string("TRUTH :: true;"); // (2) + add_build_string("TRUTH :: true;", -1); // (2) } main :: () { diff --git a/examples/5/5.4_variable_declarations2.jai b/examples/5/5.4_variable_declarations2.jai index 0546901..3417bab 100644 --- a/examples/5/5.4_variable_declarations2.jai +++ b/examples/5/5.4_variable_declarations2.jai @@ -22,7 +22,7 @@ main :: () { s, t := 2 + 3, 2 * 3; print("s is % and t is %\n", s, t); s1, t1 := #run(2 + 3), #run(2 * 3); - print("s1 is % and t1 is %\n", s1, t1); // => s is 5 and t is 6 + print("s1 is % and t1 is %\n", s1, t1); // => s is 5 and t is 6 // i, j : int; // i, j = n1 + 1, m1 + 1; @@ -34,6 +34,13 @@ main :: () { print("n4 is % and m4 is %\n", n4, m4); // => n4 is 0 and m4 is 0 n4, m4 = 1, 2; print("n4 is % and m4 is %\n", n4, m4); // => n4 is 1 and m4 is 2 + + // advanced compound assignment: + b := 5; + a, b=, c := 1, 2, 3; // (4) + print("a is % b is % c is %\n", a, b, c); // => a is 1 b is 2 c is 3 + a, d:, c = 4, 5, 6; // (5) + print("a is % c is % d is %\n", a, c, d); // => a is 4 c is 6 d is 5 } /* Output: @@ -45,4 +52,6 @@ s is 5 and t is 6 s1 is 5 and t1 is 6 n4 is 0 and m4 is 0 n4 is 1 and m4 is 2 +a is 1 b is 2 c is 3 +a is 4 c is 6 d is 5 */ \ No newline at end of file diff --git a/examples/5/5.5_swapping.jai b/examples/5/5.5_swapping.jai index d76c489..b47a1f5 100644 --- a/examples/5/5.5_swapping.jai +++ b/examples/5/5.5_swapping.jai @@ -3,17 +3,16 @@ main :: () { n := 2; m := 3; - // swap doesn't work like you would expect: - // n, m = m, n; - // print("n is % and m is %\n", n, m); // => n is 3 and m is 3 + n, m = m, n; + print("n is % and m is %\n", n, m); // => n is 3 and m is 2 s, p := "abc", 13; // this gives an error: // s, p = p, s; // => Error: Type mismatch. Type wanted: string; type given: s64. - // But there our swapping procedure in Basic: + // There are swapping procedures in Basic: Swap(*n, *m); - print("n is % and m is %\n", n, m); // => n is 3 and m is 2 + print("n is % and m is %\n", n, m); // => n is 2 and m is 3 n2 := 2; m2 := 3; n2, m2 = swap(n2, m2); @@ -22,5 +21,6 @@ main :: () { /* n is 3 and m is 2 +n is 2 and m is 3 n2 is 3 and m2 is 2 */ \ No newline at end of file