}
AstNode* make_symbol(bh_allocator a, OnyxToken* sym) {
-- AstNode* symbol = onyx_ast_node_new(a, sizeof(AstNode), Ast_Kind_Symbol);
++ AstNode* symbol = onyx_ast_node_new(a, sizeof(AstTyped), Ast_Kind_Symbol);
symbol->token = sym;
return symbol;
}
while (!consume_token_if_next(parser, '}')) {
if (parser->hit_unexpected_token) break;
-- AstNode* poly_var = make_node(AstNode, Ast_Kind_Symbol);
++ AstNode* poly_var = (void *) make_node(AstTyped, Ast_Kind_Symbol);
poly_var->token = expect_token(parser, Token_Type_Symbol);
expect_token(parser, '=');
// INVESTIGATE: I don't know why, but appearantly, this has to be a
// symbol node, not a direct link to the local. There is an error about
// being unable to resolve the type of the local if it is immediately set.
-- AstNode* left_symbol = make_node(AstNode, Ast_Kind_Symbol);
++ AstTyped* left_symbol = make_node(AstTyped, Ast_Kind_Symbol);
left_symbol->token = symbol;
-- assignment->left = (AstTyped *) left_symbol;
++ assignment->left = left_symbol;
}
return 1;
consume_token(parser);
-- AstNode* symbol_node = make_node(AstNode, Ast_Kind_Symbol);
++ AstTyped* symbol_node = make_node(AstTyped, Ast_Kind_Symbol);
symbol_node->token = expect_token(parser, Token_Type_Symbol);
+ symbol_node->flags |= Ast_Flag_Symbol_Is_PolyVar;
AstNode *implicit_interface = NULL;
if (consume_token_if_next(parser, '/')) {
if (pv != NULL) {
bh_arr_push(pv, ((AstPolyParam) {
.kind = PPK_Poly_Type,
-- .poly_sym = symbol_node,
++ .poly_sym = (AstNode *) symbol_node,
.implicit_interface = implicit_interface,
// These will be filled out by function_params()
}
case Token_Type_Symbol: {
-- AstNode* symbol_node = make_node(AstNode, Ast_Kind_Symbol);
++ AstTyped* symbol_node = make_node(AstTyped, Ast_Kind_Symbol);
symbol_node->token = expect_token(parser, Token_Type_Symbol);
*next_insertion = (AstType *) symbol_node;
AstType* backing = (AstType *) &basic_type_u32;
if (consume_token_if_next(parser, '(')) {
-- AstNode* backing_sym = make_node(AstNode, Ast_Kind_Symbol);
++ AstTyped* backing_sym = make_node(AstTyped, Ast_Kind_Symbol);
backing_sym->token = expect_token(parser, Token_Type_Symbol);
backing = (AstType *) backing_sym;
parser.tag_depth = 0;
parser.overload_count = 0;
parser.injection_point = NULL;
+ parser.last_documentation_token = NULL;
+ parser.allow_package_expressions = 0;
parser.polymorph_context = (PolymorphicContext) {
.root_node = NULL,
Code :: struct {_:i32;}
-//
-// Define aliases for common datastructures in the core library, if the core library is available.
-// I'm on the fence about keeping this, as the programmer may want to use these names for their own
-// structures, but for the moment I don't see any harm. I'm also thinking about removing the '[..]'
-// syntax for dynamic arrays and just make them like Map's and Set's, i.e. Array(T). This would
-// remove some confusion around the 3 different array types as dynamic arrays would clearly just be
-// normal structures. With the recent addition of macros and iterators, there really wouldn't be much
-// difference anyway.
+#doc """
+ Define aliases for common datastructures in the core library, if the core library is available.
+ I'm on the fence about keeping this, as the programmer may want to use these names for their own
+ structures, but for the moment I don't see any harm. I'm also thinking about removing the '[..]'
+ syntax for dynamic arrays and just make them like Map's and Set's, i.e. Array(T). This would
+ remove some confusion around the 3 different array types as dynamic arrays would clearly just be
+ normal structures. With the recent addition of macros and iterators, there really wouldn't be much
+ difference anyway.
+"""
- #if #defined((package core.map).Map) {
- Map :: (package core.map).Map;
+ #if #defined(core.map.Map) {
+ Map :: core.map.Map;
}
- #if #defined((package core.set).Set) {
- Set :: (package core.set).Set;
+ #if #defined(core.set.Set) {
+ Set :: core.set.Set;
}
package core.map
- use core {array, hash, memory, math, conv, Optional}
+ use core
+ use core.array
+ use core.hash
+ use core.memory
+ use core.math
+ use core.conv
+
+ use core {Optional}
use core.intrinsics.onyx { __initialize }
-//
-// Map is a generic hash-map implementation that uses chaining.
-// Values can be of any type. Keys must of a type that supports
-// the core.hash.hash, and the '==' operator.
-//
+#doc """
+ Map is a generic hash-map implementation that uses chaining.
+ Values can be of any type. Keys must of a type that supports
+ the core.hash.hash, and the '==' operator.
+"""
@conv.Custom_Format.{ #solidify format_map {K=Key_Type, V=Value_Type} }
Map :: struct (Key_Type: type_expr, Value_Type: type_expr) where ValidKey(Key_Type) {
allocator : Allocator;
Enable_Custom_Formatters :: true
- use core {string, math}
+ use core.string
+ use core.math
-//
-// Converts a string into an integer. Works with positive and
-// negative integers. If given a pointer to a string, will
-// modify the string to extract the integer part.
+#doc """
+ Converts a string into an integer. Works with positive and
+ negative integers. If given a pointer to a string, will
+ modify the string to extract the integer part.
+"""
str_to_i64 :: #match #local {}
#overload
}
-//
-// This procedure converts any value into a string, using the type information system.
-// If a custom formatter is specified for the type, that is used instead.
-// This procedure is generally not used directly; instead, through format or format_va.
+#doc """
+ This procedure converts any value into a string, using the type information system.
+ If a custom formatter is specified for the type, that is used instead.
+ This procedure is generally not used directly; instead, through format or format_va.
+"""
format_any :: (output: &Format_Output, formatting: &Format, v: any) {
- use package runtime.info
- array :: package core.array;
+ use runtime.info {*};
//
// Dereference the any if the '*' format specifier was given.
package core.conv
- use core {map, string, array, math}
+ use core.map
+ use core.string
+ use core.array
+ use core.math
+ use runtime
-//
-// Parses many different types from a string into a value.
-// Uses a custom parser if one has been specified for the type given.
+#doc """
+ Parses many different types from a string into a value.
+ Uses a custom parser if one has been specified for the type given.
+"""
parse_any :: #match {}
#overload
//
// Helper procedure that prints something, then prints a newline.
println :: (x) => {
-- print(x);
-- print("\n");
++ use core
++ core.print(x);
++ core.print("\n");
}
//
package core.arg_parse
- use core
-//
-// This is currently a very basic argument parsing library.
-// The options are given through a structure like so:
-//
-// Options :: struct {
-// @"--option_1"
-// option_1: str;
-//
-// @"--option_2", "-o2"
-// option_2: bool;
-// }
-//
-// main :: (args) => {
-// o: Options;
-// arg_parse.arg_parse(args, &o);
-// }
-//
-// Options that are strings and integers expect an argument after
-// them to specify their value. Options that are bool default to
-// false and are true if one or more of the option values are present.
-//
-
+ use core {package, printf}
+ use core.iter
+ use core.conv
+ use core.string
+ use runtime
+#doc """
+ This is currently a very basic argument parsing library.
+ The options are given through a structure like so:
+
+ Options :: struct {
+ @"--option_1"
+ option_1: str;
+
+ @"--option_2", "-o2"
+ option_2: bool;
+ }
+
+ main :: (args) => {
+ o: Options;
+ arg_parse.arg_parse(args, &o);
+ }
+
+ Options that are strings and integers expect an argument after
+ them to specify their value. Options that are bool default to
+ false and are true if one or more of the option values are present.
+"""
arg_parse :: (c_args: [] cstr, output: any) -> bool {
arg_iter := iter.as_iter(c_args)
|> iter.map(string.from_cstr);
package core.sync
- use core.intrinsics.atomics
+ use runtime
+ use core
+ use core.intrinsics.atomics {*}
use core.thread { Thread_ID }
-//
-// A mutex represents a resource that can only be held by one
-// thread at a time. It is used to create sections of code that
-// only one thread can be in at a time.
-//
-// Mutexes in WebAssembly are very cheap, because they simply
-// use the atomic_cmpxchg intrinsic to operate. This only uses
-// memory, so no real resource allocation is necessary.
-//
-// `lock` has two states: 0, and 1.
-// 0 means unlocked
-// 1 means locked
-//
-// To lock it:
-// Try to store 1 if the value was already 0
-// Otherwise, if it was already 1, wait until it goes to 0.
-//
-// To unlock it:
-// Atomically set it to 0.
-// Notify at most 1 other thread about this change.
-//
+#doc """
+ A mutex represents a resource that can only be held by one
+ thread at a time. It is used to create sections of code that
+ only one thread can be in at a time.
+
+ Mutexes in WebAssembly are very cheap, because they simply
+ use the atomic_cmpxchg intrinsic to operate. This only uses
+ memory, so no real resource allocation is necessary.
+
+ `lock` has two states: 0, and 1.
+ 0 means unlocked, 1 means locked
+
+ To lock it:
+ Try to store 1 if the value was already 0.
+ Otherwise, if it was already 1, wait until it goes to 0.
+
+ To unlock it:
+ Atomically set it to 0.
+ Notify at most 1 other thread about this change.
+"""
Mutex :: struct {
lock : i32;
owner : Thread_ID;
package core.sync
+ use runtime
+ use core
+
use core.intrinsics.atomics
-//
-// A semaphore represents a counter that can only be incremented
-// and decremented by one thread at a time. "Waiting" on a semaphore
-// means decrementing the counter by 1 if it is greater than 0, otherwise
-// waiting until the counter is incremented. "Posting" on a semaphore
-// means incrementing the counter by a certain value, in turn releasing
-// other threads that might have been waiting for the value to change.
-//
-// Semaphores are generally used for controlling access to shared
-// resources. For a contrived example, say only 4 threads can use
-// a given network connection at a time. A semaphore would be created
-// with a value of 4. When a thread wants to use the network connection,
-// it would use `semaphore_wait` to obtain the resource, or wait if
-// the network is currently available. When it is done using the
-// network, it would call `semaphore_post` to release the resource,
-// allowing another thread to use it.
-//
+#doc """
+ A semaphore represents a counter that can only be incremented
+ and decremented by one thread at a time. "Waiting" on a semaphore
+ means decrementing the counter by 1 if it is greater than 0, otherwise
+ waiting until the counter is incremented. "Posting" on a semaphore
+ means incrementing the counter by a certain value, in turn releasing
+ other threads that might have been waiting for the value to change.
+
+ Semaphores are generally used for controlling access to shared
+ resources. For a contrived example, say only 4 threads can use
+ a given network connection at a time. A semaphore would be created
+ with a value of 4. When a thread wants to use the network connection,
+ it would use `semaphore_wait` to obtain the resource, or wait if
+ the network is currently available. When it is done using the
+ network, it would call `semaphore_post` to release the resource,
+ allowing another thread to use it.
+"""
Semaphore :: struct {
mutex : Mutex;
counter : i32;