Merge remote-tracking branch 'upstream/master' into parser-fix

This commit is contained in:
Daniel Gavin
2022-01-23 01:38:15 +01:00
40 changed files with 2078 additions and 229 deletions

View File

@@ -8,22 +8,34 @@ CC=clang
OS=$(shell uname)
ifeq ($(OS), Darwin)
ARCH=$(shell uname -m)
LLVM_CONFIG=llvm-config
LLVM_CONFIG=
# LLVM Version Setting
LLVM_VERSION_PATTERN="^11\."
LLVM_VERSION="11"
# allow for arm only llvm's with version 13
ifeq ($(ARCH), arm64)
LLVM_VERSION="13"
LLVM_VERSION_PATTERN="^13"
endif
LLVM_VERSIONS = "13.%.%"
else
# allow for x86 / amd64 all llvm versions begining from 11
LLVM_VERSIONS = "13.%.%" "12.0.1" "11.1.0"
endif
ifneq ($(shell llvm-config --version | grep $(LLVM_VERSION_PATTERN)),)
LLVM_VERSION_PATTERN_SEPERATOR = )|(
LLVM_VERSION_PATTERNS_ESCAPED_DOT = $(subst .,\.,$(LLVM_VERSIONS))
LLVM_VERSION_PATTERNS_REPLACE_PERCENT = $(subst %,.*,$(LLVM_VERSION_PATTERNS_ESCAPED_DOT))
LLVM_VERSION_PATTERN_REMOVE_ELEMENTS = $(subst " ",$(LLVM_VERSION_PATTERN_SEPERATOR),$(LLVM_VERSION_PATTERNS_REPLACE_PERCENT))
LLMV_VERSION_PATTERN_REMOVE_SINGLE_STR = $(subst ",,$(LLVM_VERSION_PATTERN_REMOVE_ELEMENTS))
LLVM_VERSION_PATTERN = "^(($(LLMV_VERSION_PATTERN_REMOVE_SINGLE_STR)))"
ifneq ($(shell llvm-config --version | grep -E $(LLVM_VERSION_PATTERN)),)
LLVM_CONFIG=llvm-config
else
$(error "Requirement: llvm-config must be version $(LLVM_VERSION)")
endif
ifeq ($(ARCH), arm64)
$(error "Requirement: llvm-config must be base version 13 for arm64")
else
$(error "Requirement: llvm-config must be base version greater than 11 for amd64/x86")
endif
endif
LDFLAGS:=$(LDFLAGS) -liconv
CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags)

View File

@@ -5,6 +5,9 @@
List of contributors:
Jeroen van Rijn: Initial implementation, optimization.
*/
// package compress is a collection of utilities to aid with other compression packages
package compress
import "core:io"

View File

@@ -27,7 +27,7 @@
// Construction history, or BSP trees would make the format too large to serve its purpose.
// The facilities of the formats to store meta data should make the format flexible enough
// for most uses. Adding HxA support should be something anyone can do in a days work.
//
// Structure:
// ----------
// HxA is designed to be extremely simple to parse, and is therefore based around conventions. It has
@@ -45,17 +45,17 @@
// of a number of named layers. All layers in the stack have the same number of elements. Each layer
// describes one property of the primitive. Each layer can have multiple channels and each layer can
// store data of a different type.
//
// HaX stores 3 kinds of nodes
// - Pixel data.
// - Polygon geometry data.
// - Meta data only.
//
// Pixel Nodes stores pixels in a layer stack. A layer may store things like Albedo, Roughness,
// Reflectance, Light maps, Masks, Normal maps, and Displacement. Layers use the channels of the
// layers to store things like color. The length of the layer stack is determined by the type and
// dimensions stored in the
//
// Geometry data is stored in 3 separate layer stacks for: vertex data, corner data and face data. The
// vertex data stores things like verities, blend shapes, weight maps, and vertex colors. The first
// layer in a vertex stack has to be a 3 channel layer named "position" describing the base position
@@ -63,7 +63,7 @@
// for things like UV, normals, and adjacency. The first layer in a corner stack has to be a 1 channel
// integer layer named "index" describing the vertices used to form polygons. The last value in each
// polygon has a negative - 1 index to indicate the end of the polygon.
//
// Example:
// A quad and a tri with the vertex index:
// [0, 1, 2, 3] [1, 4, 2]
@@ -72,7 +72,7 @@
// The face stack stores values per face. the length of the face stack has to match the number of
// negative values in the index layer in the corner stack. The face stack can be used to store things
// like material index.
//
// Storage
// -------
// All data is stored in little endian byte order with no padding. The layout mirrors the structs

View File

@@ -64,6 +64,7 @@ If not present, the width is whatever is necessary to represent the value.
Precision is specified after the (optional) width followed by a period followed by a decimal number.
If no period is present, a default precision is used.
A period with no following number specifies a precision of 0.
Examples:
%f default width, default precision
%8f width 8, default precision
@@ -84,7 +85,6 @@ Other flags:
add leading 0z for dozenal (%#z)
add leading 0x or 0X for hexadecimal (%#x or %#X)
remove leading 0x for %p (%#p)
' ' (space) leave a space for elided sign in numbers (% d)
0 pad with leading zeros rather than spaces

View File

@@ -6,6 +6,8 @@
Jeroen van Rijn: Initial implementation, optimization.
Ginger Bill: Cosmetic changes.
*/
// package image implements a general 2D image library to be used with other image related packages
package image
import "core:bytes"

View File

@@ -6,6 +6,11 @@
Jeroen van Rijn: Initial implementation.
Ginger Bill: Cosmetic changes.
*/
// package png implements a PNG image reader
//
// The PNG specification is at https://www.w3.org/TR/PNG/.
package png
import "core:compress"

View File

@@ -2,12 +2,10 @@
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
An arbitrary precision mathematics implementation in Odin.
For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
This file collects public proc maps and their aliases.
*/
package math_big
/*

View File

@@ -1,11 +1,9 @@
/*
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
An arbitrary precision mathematics implementation in Odin.
For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
*/
package math_big
import "core:intrinsics"

6
core/math/big/doc.odin Normal file
View File

@@ -0,0 +1,6 @@
/*
A BigInt implementation in Odin.
For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
*/
package math_big

View File

@@ -1,11 +1,9 @@
/*
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
An arbitrary precision mathematics implementation in Odin.
For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
*/
package math_big
import "core:intrinsics"

View File

@@ -1,12 +1,7 @@
//+ignore
/*
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
A BigInt implementation in Odin.
For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
========================== Low-level routines ==========================
IMPORTANT: `internal_*` procedures make certain assumptions about their input.
@@ -29,6 +24,9 @@
TODO: Handle +/- Infinity and NaN.
*/
//+ignore
package math_big
import "core:mem"

View File

@@ -8,6 +8,8 @@
This file contains logical operations like `and`, `or` and `xor`.
*/
package math_big
/*

View File

@@ -8,6 +8,8 @@
This file contains prime finding operations.
*/
package math_big
import rnd "core:math/rand"

View File

@@ -15,6 +15,8 @@
These aren't exported for the same reasons.
*/
package math_big
import "core:intrinsics"

View File

@@ -8,6 +8,8 @@
This file contains basic arithmetic operations like `add`, `sub`, `mul`, `div`, ...
*/
package math_big
import "core:intrinsics"

View File

@@ -12,6 +12,8 @@
- Use Barrett reduction for non-powers-of-two.
- Also look at extracting and splatting several digits at once.
*/
package math_big
import "core:intrinsics"

View File

@@ -1,4 +1,3 @@
//+ignore
/*
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
@@ -7,6 +6,8 @@
For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3.
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
*/
//+ignore
package math_big
import "core:time"

View File

@@ -11,7 +11,7 @@ String :: distinct Array(byte)
Version_Type_Major :: 0
Version_Type_Minor :: 2
Version_Type_Patch :: 2
Version_Type_Patch :: 3
Version_Type :: struct {
major, minor, patch: u8,
@@ -107,6 +107,8 @@ Entity_Flag :: enum u32le {
Var_Thread_Local = 40,
Var_Static = 41,
Private = 50,
}
Entity_Flags :: distinct bit_set[Entity_Flag; u64le]
@@ -122,6 +124,10 @@ Entity :: struct {
_: u32le, // reserved for init
comment: String,
docs: String,
// May be used by (Struct fields and procedure fields):
// .Variable
// .Constant
field_group_index: i32le,
// May used by:
// .Variable

View File

@@ -146,14 +146,14 @@ matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y:
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = +x[1, 1] / d
y[1, 0] = -x[1, 0] / d
y[0, 1] = -x[0, 1] / d
y[1, 0] = -x[0, 1] / d
y[0, 1] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = +x[1, 1] * id
y[1, 0] = -x[1, 0] * id
y[0, 1] = -x[0, 1] * id
y[1, 0] = -x[0, 1] * id
y[0, 1] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
@@ -214,16 +214,16 @@ matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
when intrinsics.type_is_integer(T) {
y[0, 0] = x[1, 1] / d
y[0, 1] = x[1, 0] / d
y[1, 0] = x[0, 1] / d
y[1, 1] = x[0, 0] / d
y[0, 0] = +x[1, 1] / d
y[0, 1] = -x[0, 1] / d
y[1, 0] = -x[1, 0] / d
y[1, 1] = +x[0, 0] / d
} else {
id := 1 / d
y[0, 0] = x[1, 1] * id
y[0, 1] = x[1, 0] * id
y[1, 0] = x[0, 1] * id
y[1, 1] = x[0, 0] * id
y[0, 0] = +x[1, 1] * id
y[0, 1] = -x[0, 1] * id
y[1, 0] = -x[1, 0] * id
y[1, 1] = +x[0, 0] * id
}
return
}

View File

@@ -5,13 +5,13 @@ package runtime
import "core:intrinsics"
when ODIN_BUILD_MODE == .Dynamic {
@(link_name="_odin_entry_point", linkage="strong", require, link_section=".init")
@(link_name="_odin_entry_point", linkage="strong", require/*, link_section=".init"*/)
_odin_entry_point :: proc "c" () {
context = default_context()
#force_no_inline _startup_runtime()
intrinsics.__entry_point()
}
@(link_name="_odin_exit_point", linkage="strong", require, link_section=".fini")
@(link_name="_odin_exit_point", linkage="strong", require/*, link_section=".fini"*/)
_odin_exit_point :: proc "c" () {
context = default_context()
#force_no_inline _cleanup_runtime()

View File

@@ -1,44 +1,43 @@
package sync
// A barrier enabling multiple threads to synchronize the beginning of some computation
/*
* Example:
*
* package example
*
* import "core:fmt"
* import "core:sync"
* import "core:thread"
*
* barrier := &sync.Barrier{};
*
* main :: proc() {
* fmt.println("Start");
*
* THREAD_COUNT :: 4;
* threads: [THREAD_COUNT]^thread.Thread;
*
* sync.barrier_init(barrier, THREAD_COUNT);
* defer sync.barrier_destroy(barrier);
*
*
* for _, i in threads {
* threads[i] = thread.create_and_start(proc(t: ^thread.Thread) {
* // Same messages will be printed together but without any interleaving
* fmt.println("Getting ready!");
* sync.barrier_wait(barrier);
* fmt.println("Off their marks they go!");
* });
* }
*
* for t in threads {
* thread.destroy(t); // join and free thread
* }
* fmt.println("Finished");
* }
*
*/
A barrier enabling multiple threads to synchronize the beginning of some computation
Example:
package example
import "core:fmt"
import "core:sync"
import "core:thread"
barrier := &sync.Barrier{};
main :: proc() {
fmt.println("Start");
THREAD_COUNT :: 4;
threads: [THREAD_COUNT]^thread.Thread;
sync.barrier_init(barrier, THREAD_COUNT);
defer sync.barrier_destroy(barrier);
for _, i in threads {
threads[i] = thread.create_and_start(proc(t: ^thread.Thread) {
// Same messages will be printed together but without any interleaving
fmt.println("Getting ready!");
sync.barrier_wait(barrier);
fmt.println("Off their marks they go!");
});
}
for t in threads {
thread.destroy(t); // join and free thread
}
fmt.println("Finished");
}
*/
Barrier :: struct {
mutex: Blocking_Mutex,
cond: Condition,

View File

@@ -67,44 +67,41 @@ wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) -
// A barrier enabling multiple threads to synchronize the beginning of some computation
/*
* Example:
*
* package example
*
* import "core:fmt"
* import "core:sync"
* import "core:thread"
*
* barrier := &sync.Barrier{}
*
* main :: proc() {
* fmt.println("Start")
*
* THREAD_COUNT :: 4
* threads: [THREAD_COUNT]^thread.Thread
*
* sync.barrier_init(barrier, THREAD_COUNT)
* defer sync.barrier_destroy(barrier)
*
*
* for _, i in threads {
* threads[i] = thread.create_and_start(proc(t: ^thread.Thread) {
* // Same messages will be printed together but without any interleaving
* fmt.println("Getting ready!")
* sync.barrier_wait(barrier)
* fmt.println("Off their marks they go!")
* })
* }
*
* for t in threads {
* thread.destroy(t) // join and free thread
* }
* fmt.println("Finished")
* }
*
*/
A barrier enabling multiple threads to synchronize the beginning of some computation
Example:
package example
import "core:fmt"
import "core:sync"
import "core:thread"
barrier := &sync.Barrier{}
main :: proc() {
fmt.println("Start")
THREAD_COUNT :: 4
threads: [THREAD_COUNT]^thread.Thread
sync.barrier_init(barrier, THREAD_COUNT)
for _, i in threads {
threads[i] = thread.create_and_start(proc(t: ^thread.Thread) {
// Same messages will be printed together but without any interleaving
fmt.println("Getting ready!")
sync.barrier_wait(barrier)
fmt.println("Off their marks they go!")
})
}
for t in threads {
thread.destroy(t) // join and free thread
}
fmt.println("Finished")
}
*/
Barrier :: struct {
mutex: Mutex,
cond: Cond,

View File

@@ -29,12 +29,12 @@ mutex_try_lock :: proc(m: ^Mutex) -> bool {
return _mutex_try_lock(m)
}
// Example:
//
// if mutex_guard(&m) {
// ...
// }
//
/*
Example:
if mutex_guard(&m) {
...
}
*/
@(deferred_in=mutex_unlock)
mutex_guard :: proc(m: ^Mutex) -> bool {
mutex_lock(m)
@@ -80,25 +80,24 @@ rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) {
rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
return _rw_mutex_try_shared_lock(rw)
}
// Example:
//
// if rw_mutex_guard(&m) {
// ...
// }
//
/*
Example:
if rw_mutex_guard(&m) {
...
}
*/
@(deferred_in=rw_mutex_unlock)
rw_mutex_guard :: proc(m: ^RW_Mutex) -> bool {
rw_mutex_lock(m)
return true
}
// Example:
//
// if rw_mutex_shared_guard(&m) {
// ...
// }
//
/*
Example:
if rw_mutex_shared_guard(&m) {
...
}
*/
@(deferred_in=rw_mutex_shared_unlock)
rw_mutex_shared_guard :: proc(m: ^RW_Mutex) -> bool {
rw_mutex_shared_lock(m)
@@ -127,13 +126,12 @@ recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
return _recursive_mutex_try_lock(m)
}
// Example:
//
// if recursive_mutex_guard(&m) {
// ...
// }
//
/*
Example:
if recursive_mutex_guard(&m) {
...
}
*/
@(deferred_in=recursive_mutex_unlock)
recursive_mutex_guard :: proc(m: ^Recursive_Mutex) -> bool {
recursive_mutex_lock(m)

View File

@@ -82,13 +82,12 @@ atomic_mutex_try_lock :: proc(m: ^Atomic_Mutex) -> bool {
return ok
}
// Example:
//
// if atomic_mutex_guard(&m) {
// ...
// }
//
/*
Example:
if atomic_mutex_guard(&m) {
...
}
*/
@(deferred_in=atomic_mutex_unlock)
atomic_mutex_guard :: proc(m: ^Atomic_Mutex) -> bool {
atomic_mutex_lock(m)
@@ -193,25 +192,24 @@ atomic_rw_mutex_try_shared_lock :: proc(rw: ^Atomic_RW_Mutex) -> bool {
return false
}
// Example:
//
// if atomic_rw_mutex_guard(&m) {
// ...
// }
//
/*
Example:
if atomic_rw_mutex_guard(&m) {
...
}
*/
@(deferred_in=atomic_rw_mutex_unlock)
atomic_rw_mutex_guard :: proc(m: ^Atomic_RW_Mutex) -> bool {
atomic_rw_mutex_lock(m)
return true
}
// Example:
//
// if atomic_rw_mutex_shared_guard(&m) {
// ...
// }
//
/*
Example:
if atomic_rw_mutex_shared_guard(&m) {
...
}
*/
@(deferred_in=atomic_rw_mutex_shared_unlock)
atomic_rw_mutex_shared_guard :: proc(m: ^Atomic_RW_Mutex) -> bool {
atomic_rw_mutex_shared_lock(m)
@@ -270,13 +268,12 @@ atomic_recursive_mutex_try_lock :: proc(m: ^Atomic_Recursive_Mutex) -> bool {
return true
}
// Example:
//
// if atomic_recursive_mutex_guard(&m) {
// ...
// }
//
/*
Example:
if atomic_recursive_mutex_guard(&m) {
...
}
*/
@(deferred_in=atomic_recursive_mutex_unlock)
atomic_recursive_mutex_guard :: proc(m: ^Atomic_Recursive_Mutex) -> bool {
atomic_recursive_mutex_lock(m)

View File

@@ -1,3 +1,4 @@
//+private
package sync2
import "core:time"

View File

@@ -1,12 +1,11 @@
package sync2
// Example:
//
// if guard(&m) {
// ...
// }
//
/*
Example:
if guard(&m) {
...
}
*/
guard :: proc{
mutex_guard,
rw_mutex_guard,
@@ -17,13 +16,12 @@ guard :: proc{
atomic_recursive_mutex_guard,
atomic_rw_mutex_guard,
}
// Example:
//
// if shared_guard(&m) {
// ...
// }
//
/*
Example:
if shared_guard(&m) {
...
}
*/
shared_guard :: proc{
rw_mutex_shared_guard,
atomic_rw_mutex_shared_guard,

View File

@@ -1,26 +1,47 @@
//+build windows
package all
import glfw "vendor:glfw"
import gl "vendor:OpenGL"
import rl "vendor:raylib"
import PM "vendor:portmidi"
import botan "vendor:botan"
import ENet "vendor:ENet"
import gl "vendor:OpenGL"
import glfw "vendor:glfw"
import microui "vendor:microui"
import miniaudio "vendor:miniaudio"
import PM "vendor:portmidi"
import rl "vendor:raylib"
import SDL "vendor:sdl2"
import IMG "vendor:sdl2/image"
import SDLNet "vendor:sdl2/net"
import IMG "vendor:sdl2/image"
import MIX "vendor:sdl2/mixer"
import TTF "vendor:sdl2/ttf"
import vk "vendor:vulkan"
import ENet "vendor:ENet"
_ :: glfw
import stb_easy_font "vendor:stb/easy_font"
import stbi "vendor:stb/image"
import stbrp "vendor:stb/rect_pack"
import stbtt "vendor:stb/truetype"
import stb_vorbis "vendor:stb/vorbis"
import vk "vendor:vulkan"
_ :: botan
_ :: ENet
_ :: gl
_ :: rl
_ :: glfw
_ :: microui
_ :: miniaudio
_ :: PM
_ :: rl
_ :: SDL
_ :: IMG
_ :: SDLNet
_ :: IMG
_ :: MIX
_ :: TTF
_ :: vk
_ :: ENet
_ :: stb_easy_font
_ :: stbi
_ :: stbrp
_ :: stbtt
_ :: stb_vorbis
_ :: vk

View File

@@ -109,11 +109,14 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
}
i32 field_src_index = 0;
i32 field_group_index = -1;
for_array(i, params) {
Ast *param = params[i];
if (param->kind != Ast_Field) {
continue;
}
field_group_index += 1;
ast_node(p, Field, param);
Ast *type_expr = p->type;
Type *type = nullptr;
@@ -152,6 +155,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
add_entity(ctx, ctx->scope, name, field);
field->Variable.field_group_index = field_group_index;
array_add(&fields_array, field);
String tag = p->tag.string;
if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) {
@@ -1366,11 +1370,13 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
isize variadic_index = -1;
bool is_c_vararg = false;
auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count);
i32 field_group_index = -1;
for_array(i, params) {
Ast *param = params[i];
if (param->kind != Ast_Field) {
continue;
}
field_group_index += 1;
ast_node(p, Field, param);
Ast *type_expr = unparen_expr(p->type);
Type *type = nullptr;
@@ -1671,9 +1677,11 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
param->Constant.field_group_index = field_group_index;
} else {
param = alloc_entity_param(scope, name->Ident.token, type, is_using, true);
param->Variable.param_value = param_value;
param->Variable.field_group_index = field_group_index;
}
}
if (p->flags&FieldFlag_no_alias) {
@@ -1767,7 +1775,10 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
}
auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count);
i32 field_group_index = -1;
for_array(i, results) {
field_group_index += 1;
ast_node(field, Field, results[i]);
Ast *default_value = unparen_expr(field->default_value);
ParameterValue param_value = {};
@@ -1798,6 +1809,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
token.string = str_lit("");
Entity *param = alloc_entity_param(scope, token, type, false, false);
param->Variable.param_value = param_value;
param->Variable.field_group_index = -1;
array_add(&variables, param);
} else {
for_array(j, field->names) {
@@ -1821,6 +1833,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
Entity *param = alloc_entity_param(scope, token, type, false, false);
param->flags |= EntityFlag_Result;
param->Variable.param_value = param_value;
param->Variable.field_group_index = field_group_index;
array_add(&variables, param);
add_entity(ctx, scope, name, param);
// NOTE(bill): Removes `declared but not used` when using -vet

View File

@@ -1253,7 +1253,7 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
// TODO(bill): This is O(n) and can be very slow
for_array(i, info->type_info_map.entries){
auto *e = &info->type_info_map.entries[i];
if (are_types_identical(e->key, type)) {
if (are_types_identical_unique_tuples(e->key, type)) {
entry_index = e->value;
// NOTE(bill): Add it to the search map
map_set(&info->type_info_map, type, entry_index);
@@ -1601,7 +1601,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) {
isize ti_index = -1;
for_array(i, c->info->type_info_map.entries) {
auto *e = &c->info->type_info_map.entries[i];
if (are_types_identical(t, e->key)) {
if (are_types_identical_unique_tuples(t, e->key)) {
// Duplicate entry
ti_index = e->value;
prev = true;
@@ -3446,6 +3446,13 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
}
}
if (entity_visibility_kind == EntityVisiblity_Public &&
(c->scope->flags&ScopeFlag_File) &&
c->scope->file &&
(c->scope->file->flags & AstFile_IsPrivate)) {
entity_visibility_kind = EntityVisiblity_PrivateToPackage;
}
if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) {
error(decl, "Attribute 'private' is not allowed on a non file scope entity");
}

View File

@@ -67,6 +67,14 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) {
#include "docs_format.cpp"
#include "docs_writer.cpp"
void print_doc_line(i32 indent, String const &data) {
while (indent --> 0) {
gb_printf("\t");
}
gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.text, data.len);
gb_printf("\n");
}
void print_doc_line(i32 indent, char const *fmt, ...) {
while (indent --> 0) {
gb_printf("\t");
@@ -86,6 +94,13 @@ void print_doc_line_no_newline(i32 indent, char const *fmt, ...) {
gb_printf_va(fmt, va);
va_end(va);
}
void print_doc_line_no_newline(i32 indent, String const &data) {
while (indent --> 0) {
gb_printf("\t");
}
gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.text, data.len);
}
bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
if (g == nullptr) {
@@ -106,8 +121,9 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
String comment = g->list[i].string;
String original_comment = comment;
bool slash_slash = comment[1] == '/';
bool slash_slash = false;
if (comment[1] == '/') {
slash_slash = true;
comment.text += 2;
comment.len -= 2;
} else if (comment[1] == '*') {
@@ -131,7 +147,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
}
if (slash_slash) {
print_doc_line(indent, "%.*s", LIT(comment));
print_doc_line(indent, comment);
count += 1;
} else {
isize pos = 0;
@@ -143,7 +159,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
}
}
String line = substring(comment, pos, end);
pos = end+1;
pos = end;
String trimmed_line = string_trim_whitespace(line);
if (trimmed_line.len == 0) {
if (count == 0) {
@@ -159,7 +175,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) {
line = substring(line, 2, line.len);
}
print_doc_line(indent, "%.*s", LIT(line));
print_doc_line(indent, line);
count += 1;
}
}
@@ -263,7 +279,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
}
GB_ASSERT(type_expr != nullptr || init_expr != nullptr);
print_doc_line_no_newline(2, "%.*s", LIT(e->token.string));
print_doc_line_no_newline(2, e->token.string);
if (type_expr != nullptr) {
gbString t = expr_to_string(type_expr);
gb_printf(": %s ", t);
@@ -298,7 +314,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
for_array(i, pkg->files) {
AstFile *f = pkg->files[i];
String filename = remove_directory_from_path(f->fullpath);
print_doc_line(2, "%.*s", LIT(filename));
print_doc_line(2, filename);
}
}

View File

@@ -15,7 +15,7 @@ struct OdinDocVersionType {
#define OdinDocVersionType_Major 0
#define OdinDocVersionType_Minor 2
#define OdinDocVersionType_Patch 2
#define OdinDocVersionType_Patch 3
struct OdinDocHeaderBase {
u8 magic[8];
@@ -172,6 +172,8 @@ enum OdinDocEntityFlag : u64 {
OdinDocEntityFlag_Var_Thread_Local = 1ull<<40,
OdinDocEntityFlag_Var_Static = 1ull<<41,
OdinDocEntityFlag_Private = 1ull<<50,
};
struct OdinDocEntity {
@@ -185,6 +187,7 @@ struct OdinDocEntity {
u32 reserved_for_init;
OdinDocString comment;
OdinDocString docs;
i32 field_group_index;
OdinDocEntityIndex foreign_library;
OdinDocString link_name;
OdinDocArray<OdinDocAttribute> attributes;

View File

@@ -292,8 +292,9 @@ bool odin_doc_append_comment_group_string(Array<u8> *buf, CommentGroup *g) {
String comment = g->list[i].string;
String original_comment = comment;
bool slash_slash = comment[1] == '/';
bool slash_slash = false;
if (comment[1] == '/') {
slash_slash = true;
comment.text += 2;
comment.len -= 2;
} else if (comment[1] == '*') {
@@ -330,7 +331,7 @@ bool odin_doc_append_comment_group_string(Array<u8> *buf, CommentGroup *g) {
}
}
String line = substring(comment, pos, end);
pos = end+1;
pos = end;
String trimmed_line = string_trim_whitespace(line);
if (trimmed_line.len == 0) {
if (count == 0) {
@@ -482,7 +483,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
for_array(i, w->type_cache.entries) {
// NOTE(bill): THIS IS SLOW
Type *other = w->type_cache.entries[i].key;
if (are_types_identical(type, other)) {
if (are_types_identical_unique_tuples(type, other)) {
OdinDocTypeIndex index = w->type_cache.entries[i].value;
map_set(&w->type_cache, type, index);
return index;
@@ -511,10 +512,16 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
doc_type.entities = odin_doc_add_entity_as_slice(w, type->Named.type_name);
break;
case Type_Generic:
doc_type.kind = OdinDocType_Generic;
doc_type.name = odin_doc_write_string(w, type->Generic.name);
if (type->Generic.specialized) {
doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized);
{
String name = type->Generic.name;
if (type->Generic.entity) {
name = type->Generic.entity->token.string;
}
doc_type.kind = OdinDocType_Generic;
doc_type.name = odin_doc_write_string(w, name);
if (type->Generic.specialized) {
doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized);
}
}
break;
case Type_Pointer:
@@ -808,7 +815,8 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
String link_name = {};
OdinDocEntityKind kind = OdinDocEntity_Invalid;
u32 flags = 0;
u64 flags = 0;
i32 field_group_index = -1;
switch (e->kind) {
case Entity_Invalid: kind = OdinDocEntity_Invalid; break;
@@ -838,6 +846,10 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
if (init_expr == nullptr) {
init_expr = e->Variable.init_expr;
}
field_group_index = e->Variable.field_group_index;
break;
case Entity_Constant:
field_group_index = e->Constant.field_group_index;
break;
case Entity_Procedure:
if (e->Procedure.is_foreign) { flags |= OdinDocEntityFlag_Foreign; }
@@ -854,6 +866,9 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
if (e->flags & EntityFlag_NoAlias) { flags |= OdinDocEntityFlag_Param_NoAlias; }
if (e->flags & EntityFlag_AnyInt) { flags |= OdinDocEntityFlag_Param_AnyInt; }
}
if (e->scope && (e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) && !is_entity_exported(e)) {
flags |= OdinDocEntityFlag_Private;
}
OdinDocString init_string = {};
if (init_expr) {
@@ -882,6 +897,7 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
doc_entity.init_string = init_string;
doc_entity.comment = odin_doc_comment_group_string(w, comment);
doc_entity.docs = odin_doc_comment_group_string(w, docs);
doc_entity.field_group_index = field_group_index;
doc_entity.foreign_library = 0; // Set later
doc_entity.link_name = odin_doc_write_string(w, link_name);
if (e->decl_info != nullptr) {

View File

@@ -160,10 +160,12 @@ struct Entity {
ExactValue value;
ParameterValue param_value;
u32 flags;
i32 field_group_index;
} Constant;
struct {
Ast *init_expr; // only used for some variables within procedure bodies
i32 field_index;
i32 field_group_index;
ParameterValue param_value;

View File

@@ -5412,6 +5412,15 @@ bool parse_file(Parser *p, AstFile *f) {
if (f->package_token.kind != Token_package) {
return false;
}
if (docs != nullptr) {
TokenPos end = token_pos_end(docs->list[docs->list.count-1]);
if (end.line == f->package_token.pos.line || end.line+1 == f->package_token.pos.line) {
// Okay
} else {
docs = nullptr;
}
}
Token package_name = expect_token_after(f, Token_Ident, "package");
if (package_name.kind == Token_Ident) {
if (package_name.string == "_") {

View File

@@ -2338,7 +2338,17 @@ Type *strip_type_aliasing(Type *x) {
return x;
}
bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names);
bool are_types_identical(Type *x, Type *y) {
return are_types_identical_internal(x, y, false);
}
bool are_types_identical_unique_tuples(Type *x, Type *y) {
return are_types_identical_internal(x, y, true);
}
bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
if (x == y) {
return true;
}
@@ -2487,6 +2497,11 @@ bool are_types_identical(Type *x, Type *y) {
if (xe->kind != ye->kind || !are_types_identical(xe->type, ye->type)) {
return false;
}
if (check_tuple_names) {
if (xe->token.string != ye->token.string) {
return false;
}
}
if (xe->kind == Entity_Constant && !compare_exact_values(Token_CmpEq, xe->Constant.value, ye->Constant.value)) {
// NOTE(bill): This is needed for polymorphic procedures
return false;
@@ -3933,7 +3948,7 @@ gbString write_type_to_string(gbString str, Type *type) {
str = gb_string_appendc(str, " = ");
str = write_exact_value_to_string(str, var->Constant.value);
} else {
str = gb_string_appendc(str, "=");
str = gb_string_appendc(str, " := ");
str = write_exact_value_to_string(str, var->Constant.value);
}
continue;
@@ -3961,14 +3976,10 @@ gbString write_type_to_string(gbString str, Type *type) {
str = gb_string_appendc(str, "typeid/");
str = write_type_to_string(str, var->type);
} else {
if (var->kind == Entity_TypeName) {
str = gb_string_appendc(str, "$");
str = gb_string_append_length(str, name.text, name.len);
str = gb_string_appendc(str, "=");
str = write_type_to_string(str, var->type);
} else {
str = gb_string_appendc(str, "typeid");
}
str = gb_string_appendc(str, "$");
str = gb_string_append_length(str, name.text, name.len);
str = gb_string_appendc(str, "=");
str = write_type_to_string(str, var->type);
}
}
}

View File

@@ -0,0 +1,45 @@
</div>
</main>
<footer class="odin-footer">
<div class="container pb-5 pt-5">
<div class="row g-4">
<div class="col">
<a class="navbar-brand" href="https://odin-lang.org">
<img class="mb-3" src="https://odin-lang.org/logo.svg" height="30" alt="Odin"></a>
<p>
The Data-Oriented Language for Sane Software Development.
</p>
</div>
<nav class="col-md-auto">
<h4 class="fw-normal">Resources</h4>
<ul class="list-unstyled">
<li><a href="https://odin-lang.org/docs" class="link-light">Docs</a></li>
<li><a href="https://pkg.odin-lang.org/" class="link-light">Packages</a></li>
<li><a href="https://odin-lang.org/news" class="link-light">News</a></li>
</ul>
</nav>
<nav class="col-md-auto">
<h4 class="fw-normal">Community</h4>
<ul class="list-unstyled">
<li><a href="https://github.com/odin-lang/Odin" target="_blank" class="link-light">GitHub</a></li>
<li><a href="https://discord.com/invite/sVBPHEv" target="_blank" class="link-light">Discord</a></li>
<li><a href="https://www.twitch.tv/ginger_bill" target="_blank" class="link-light">Twitch</a></li>
<li><a href="https://www.youtube.com/channel/UCUSck1dOH7VKmG4lRW7tZXg" target="_blank" class="link-light">YouTube</a></li>
</ul>
</nav>
<nav class="col-md-auto">
<h4 class="fw-normal">Contribute</h4>
<ul class="list-unstyled">
<li><a href="https://github.com/odin-lang/Odin/issues" target="_blank" class="link-light">Issues</a></li>
<li><a href="https://www.patreon.com/gingerbill" target="_blank" class="link-light">Donate</a></li>
</ul>
</nav>
</div>
<div class="mt-4 text-muted">© 20162022 Ginger Bill</div>
</div>
</footer>
<script src="https://odin-lang.org/lib/bootstrap/js/bootstrap.min.js"></script>
<script src="https://odin-lang.org/js/script.js"></script>
<script>hljs.highlightAll()</script>

View File

@@ -0,0 +1,36 @@
<!-- REMEMBER TO REMOVE -->
<script type="text/javascript" src="https://livejs.com/live.js"></script>
<link rel="stylesheet" type="text/css" href="https://odin-lang.org/scss/custom.min.css">
<link rel=stylesheet href=//odin-lang.org/lib/highlight/styles/github-dark.min.css>
<script src=//odin-lang.org/lib/highlight/highlight.min.js></script>
<script>hljs.registerLanguage("odin",function(a){return{aliases:["odin","odinlang","odin-lang"],keywords:{keyword:"auto_cast bit_set break case cast context continue defer distinct do dynamic else enum fallthrough for foreign if import in map not_in or_else or_return package proc return struct switch transmute type_of typeid union using when where",literal:"true false nil",built_in:"abs align_of cap clamp complex conj expand_to_tuple imag jmag kmag len max min offset_of quaternion real size_of soa_unzip soa_zip swizzle type_info_of type_of typeid_of"},illegal:"</",contains:[a.C_LINE_COMMENT_MODE,a.C_BLOCK_COMMENT_MODE,{className:"string",variants:[a.QUOTE_STRING_MODE,{begin:"'",end:"[^\\\\]'"},{begin:"`",end:"`"}]},{className:"number",variants:[{begin:a.C_NUMBER_RE+"[ijk]",relevance:1},a.C_NUMBER_MODE]}]}})</script>
<script>hljs.highlightAll()</script>
<link rel="stylesheet" type="text/css" href="https://odin-lang.org/css/style.css">
<link rel="stylesheet" type="text/css" href="/style.css">
</style>
</head>
<body>
<header class="sticky-top">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary odin-menu">
<div class="container">
<a class="navbar-brand" href="https://odin-lang.org/">
<img src="https://odin-lang.org/logo.svg" height="30" alt="Odin"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#odin-navbar-content" aria-controls="odin-navbar-content" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="odin-navbar-content">
<ul class="navbar-nav ms-md-auto">
<li class="nav-item"><a class="nav-link" href="https://odin-lang.org/">Home</a></li>
<li class="nav-item"><a class="nav-link" href="https://odin-lang.org/docs">Docs</a></li>
<li class="nav-item"><a class="nav-link active" href="/">Packages</a></li>
<li class="nav-item"><a class="nav-link" href="https://odin-lang.org/news">News</a></li>
<li class="nav-item"><a class="nav-link" href="https://odin-lang.org/community">Community</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/odin-lang/Odin" target="_blank">GitHub</a></li>
</ul>
</div>
</div>
</nav>
</header>
<main>
<div class="container">

View File

@@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{0:s}</title>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
/* doc directories */
table.directory {
/*border: 1px solid #ccc!important;*/
table-layout: fixed;
border-collapse: collapse;
}
header.collection-header ul {
margin-top: 1em;
margin-bottom: 0;
padding-left: 0.5em;
list-style-type: none;
}
hr.collection-hr {
margin: 0;
padding: 0;
}
.doc-directory tr {
padding-left: 1em!important;
border-top: 1px solid #ccc!important;
border-bottom: 1px solid #ccc!important;
}
.doc-directory td {
padding: 0.25em 0.5em;
}
.directory-child td {
padding-left: 2em!important;
}
.directory-child td+td {
position: relative;
left: -1.5em!important;
padding-right: 0;
}
.doc-directory tr[aria-expanded=true] td.pkg-name:before {
content: "\2193";
}
.doc-directory tr[aria-expanded=false] td.pkg-name:before {
content: "\2192"!important;
}
.doc-directory tr[aria-hidden=true] {
display: none;
}
/* doc page */
pre.doc-code {
white-space: pre-wrap;
word-break: keep-all;
word-wrap: break-word;
tab-size: 8;
background-color: #f8f8f8;
color: #202224;
border: 1px solid #c6c8ca;
border-radius: 0.25rem;
padding: 0.625rem;
}
pre.doc-code a {
font-family: Consolas,Liberation Mono,Menlo,monospace!important;
text-decoration: none;
color: #2179d8;
font-weight: 800;
}
pre.doc-code a.code-procedure {
color: #047919;
}
.pkg-line-doc {
color: #444;
width: 100%;
}
.doc-source {
display: inline;
float: right;
}
.doc-source a {
text-decoration: none;
color: #666666;
font-size: 0.75em;
}
.doc-source a:hover {
text-decoration: underline;
}
a > .a-hidden {
opacity: 0;
}
a:hover > .a-hidden {
opacity: 100;
}
section.documentation h3 {
font-size: calc(1.1rem + .2vw);
}
.pkg-index h3 {
margin-top: 0 !important;
padding-top: 0 !important;
}
.documentation .pkg-entity {
padding-bottom: 0.75rem;
border-bottom: 1px solid #d0d0d0;
}
details.doc-index > summary {
font-size: 1.75rem;
}
details.doc-index ul {
list-style-type: none;
}
details.odin-doc-toggle > summary.hideme span:before {
content: "Expand description";
}
details.odin-doc-toggle[open] > summary.hideme span:before {
content: "Close description";
opacity: 0.8;
}
details.odin-doc-toggle[open] > summary.hideme {
margin-bottom: 0.5em;
}
details.code-example > summary {
font-weight: 700;
}
@media only screen and (max-width: 991px) {
#pkg-sidebar {
display: none;
}
}
#pkg-sidebar ul {
list-style-type: none;
padding: 0;
}
#pkg-sidebar li:not(:last-child) {
margin-bottom: 0.25rem;
}
#pkg-sidebar li > ul {
padding-left: 1.25rem;
}
#pkg-sidebar a.active {
font-style: italic;
}