Skip to content

Commit 3c80b27

Browse files
authored
Merge pull request #140 from onyx-lang/rc-v0.1.11
Release: 0.1.11
2 parents 0192d57 + 019c81b commit 3c80b27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+1833
-839
lines changed

CHANGELOG

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
11
Release 0.1.11
22
--------------
3-
Not released yet
3+
21st April 2024
44

55
Additions:
66
- Ability specify where piped arguments are placed using `_`.
77
- `x |> foo(y, _) == foo(y, x)`
8+
- Alternative syntax for `case #default ...`. You can now just write `case _ ...`.
9+
- Alternative syntax for binding documentation using `///`.
10+
- **Experimental** compiler extensions feature, currently used to create procedural macros.
11+
- `core.misc.any_deep_copy`
12+
- Ability to explicitly specify tag value for tagged unions.
13+
- `Variant as value: type`, i.e. `Foo as 3: i32`
814

915
Removals:
16+
- Deprecated the use of `#default` in case statements. Use `_` instead.
17+
- Removed `iter.take_one`. Use `iter.next` instead.
1018

1119
Changes:
20+
There are several *breaking* changes in this release related to core library APIs.
21+
- `Iterator.next` now returns `? T` instead of `(T, bool)`
22+
- `io.Stream` uses `Result(T, Error)` for return types instead of `(Error, T)`
23+
- `switch` over a `range` is no longer inclusive by default, since `..=` exists now.
24+
- Enabled optional semicolons by default.
25+
- `//+optional-semicolons` is no longer necessary.
26+
27+
There are also several non-breaking changes.
28+
- The internal memory layout is different. See pull request #133 for details.
1229

1330
Bugfixes:
1431

1532
Contributors:
1633

1734

35+
1836
Release 0.1.10
1937
---------------
2038
30th March 2024

build.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@echo off
22

33
REM Compile the compiler
4-
set SOURCE_FILES=compiler/src/onyx.c compiler/src/astnodes.c compiler/src/builtins.c compiler/src/checker.c compiler/src/clone.c compiler/src/doc.c compiler/src/entities.c compiler/src/errors.c compiler/src/lex.c compiler/src/parser.c compiler/src/symres.c compiler/src/types.c compiler/src/utils.c compiler/src/wasm_emit.c compiler/src/wasm_runtime.c
4+
set SOURCE_FILES=compiler/src/onyx.c compiler/src/astnodes.c compiler/src/builtins.c compiler/src/checker.c compiler/src/clone.c compiler/src/doc.c compiler/src/entities.c compiler/src/errors.c compiler/src/lex.c compiler/src/parser.c compiler/src/symres.c compiler/src/types.c compiler/src/utils.c compiler/src/wasm_emit.c compiler/src/wasm_runtime.c compiler/src/extensions.c
55

66
if "%1" == "1" (
77
set FLAGS=/Od /MTd /Z7

compiler/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
C_FILES="onyx astnodes builtins checker clone doc entities errors lex parser symres types utils wasm_emit "
3+
C_FILES="onyx astnodes builtins checker clone doc entities errors lex parser symres types utils wasm_emit extensions "
44
LIBS="-lpthread -ldl -lm"
55
INCLUDES="-I./include -I../shared/include -I../shared/include/dyncall"
66

compiler/include/astnodes.h

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#define VERSION_MAJOR 0
55
#define VERSION_MINOR 1
6-
#define VERSION_PATCH 10
6+
#define VERSION_PATCH 11
77

88
#include "stb_ds.h"
99
#include "lex.h"
@@ -120,7 +120,11 @@
120120
\
121121
NODE(ZeroValue) \
122122
\
123-
NODE(JsNode)
123+
NODE(JsNode) \
124+
\
125+
NODE(CompilerExtension) \
126+
NODE(ProceduralMacro) \
127+
NODE(ProceduralExpansion)
124128

125129
#define NODE(name) typedef struct Ast ## name Ast ## name;
126130
AST_NODES
@@ -255,6 +259,10 @@ typedef enum AstKind {
255259

256260
Ast_Kind_Js_Code,
257261

262+
Ast_Kind_Compiler_Extension,
263+
Ast_Kind_Procedural_Macro,
264+
Ast_Kind_Procedural_Expansion,
265+
258266
Ast_Kind_Count
259267
} AstKind;
260268

@@ -1097,6 +1105,8 @@ struct AstUnionType {
10971105
struct AstUnionVariant {
10981106
AstTyped_base;
10991107
bh_arr(AstTyped *) meta_tags;
1108+
1109+
AstTyped *explicit_tag_value;
11001110
};
11011111
struct AstPolyUnionType {
11021112
AstType_base;
@@ -1635,6 +1645,33 @@ struct AstJsNode {
16351645
};
16361646

16371647

1648+
struct AstCompilerExtension {
1649+
AstNode_base;
1650+
1651+
OnyxToken *name;
1652+
bh_arr(AstProceduralMacro *) proc_macros;
1653+
1654+
i32 extension_id;
1655+
};
1656+
1657+
struct AstProceduralMacro {
1658+
AstNode_base;
1659+
1660+
// name is stored in the `token`
1661+
1662+
AstCompilerExtension *extension;
1663+
};
1664+
1665+
struct AstProceduralExpansion {
1666+
AstTyped_base;
1667+
1668+
AstTyped *proc_macro;
1669+
OnyxToken *expansion_body;
1670+
1671+
u32 expansion_id;
1672+
};
1673+
1674+
16381675
typedef struct EntityJobData {
16391676
enum TypeMatch (*func)(void *job_data);
16401677
void *job_data;
@@ -1671,6 +1708,8 @@ typedef enum EntityType {
16711708
Entity_Type_Static_If,
16721709
Entity_Type_String_Literal,
16731710
Entity_Type_File_Contents,
1711+
Entity_Type_Compiler_Extension,
1712+
Entity_Type_Procedural_Expansion,
16741713
Entity_Type_Enum,
16751714
Entity_Type_Enum_Value,
16761715
Entity_Type_Type_Alias,
@@ -1744,6 +1783,8 @@ typedef struct Entity {
17441783
AstDirectiveLibrary *library;
17451784
EntityJobData *job_data;
17461785
AstJsNode *js;
1786+
AstCompilerExtension *compiler_extension;
1787+
AstProceduralExpansion *proc_expansion;
17471788
};
17481789
} Entity;
17491790

@@ -1865,6 +1906,34 @@ typedef struct DefinedVariable {
18651906
} DefinedVariable;
18661907

18671908

1909+
typedef enum ProceduralMacroExpansionKind {
1910+
PMEK_Expression,
1911+
PMEK_Statement,
1912+
PMEK_Top_Level
1913+
} ProceduralMacroExpansionKind;
1914+
1915+
typedef enum CompilerExtensionState {
1916+
COMP_EXT_STATE_SPAWNING,
1917+
COMP_EXT_STATE_INITIATING,
1918+
COMP_EXT_STATE_READY,
1919+
COMP_EXT_STATE_EXPANDING,
1920+
} CompilerExtensionState;
1921+
1922+
typedef struct CompilerExtension {
1923+
u64 pid;
1924+
u64 send_file;
1925+
u64 recv_file;
1926+
1927+
char *name;
1928+
1929+
i32 current_expansion_id;
1930+
CompilerExtensionState state;
1931+
1932+
bh_arena arena;
1933+
1934+
b32 alive : 1;
1935+
} CompilerExtension;
1936+
18681937
typedef struct CompileOptions CompileOptions;
18691938
struct CompileOptions {
18701939
bh_allocator allocator;
@@ -1876,6 +1945,7 @@ struct CompileOptions {
18761945
b32 print_static_if_results : 1;
18771946
b32 no_colors : 1;
18781947
b32 no_file_contents : 1;
1948+
b32 no_compiler_extensions : 1;
18791949

18801950
b32 use_post_mvp_features : 1;
18811951
b32 use_multi_threading : 1;
@@ -1944,6 +2014,9 @@ struct Context {
19442014
struct SymbolInfoTable *symbol_info;
19452015
struct OnyxDocInfo *doc_info;
19462016

2017+
bh_arr(CompilerExtension) extensions;
2018+
u32 next_expansion_id;
2019+
19472020
CheckerData checker;
19482021
ContextCaches caches;
19492022
OnyxErrors errors;
@@ -2175,6 +2248,20 @@ void track_declaration_for_symbol_info(OnyxFilePos, AstNode *);
21752248
void track_documentation_for_symbol_info(AstNode *, AstBinding *);
21762249
void track_resolution_for_symbol_info(AstNode *original, AstNode *resolved);
21772250

2251+
2252+
// Compiler Extensions
2253+
TypeMatch compiler_extension_start(const char *name, const char *containing_filename, i32 *out_extension_id);
2254+
TypeMatch compiler_extension_expand_macro(
2255+
int extension_id,
2256+
ProceduralMacroExpansionKind kind,
2257+
const char *macro_name,
2258+
OnyxToken *body,
2259+
Entity *entity,
2260+
AstNode **out_node,
2261+
u32 *out_expansion_id,
2262+
b32 wait_for_response);
2263+
2264+
21782265
// NOTE: Useful inlined functions
21792266
static inline b32 is_lval(AstNode* node) {
21802267
node = strip_aliases(node);

compiler/include/lex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ typedef enum TokenType {
8989

9090
Token_Type_Doc_Comment,
9191

92+
Token_Type_Proc_Macro_Body,
93+
9294
Token_Type_Count,
9395
} TokenType;
9496

compiler/include/parser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,8 @@ void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstKind kind);
7070
OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer);
7171
void onyx_parser_free(OnyxParser* parser);
7272
void onyx_parse(OnyxParser *parser);
73+
AstTyped *onyx_parse_expression(OnyxParser *parser, Scope *scope);
74+
AstNode *onyx_parse_statement(OnyxParser *parser, Scope *scope);
75+
void onyx_parse_top_level_statements(OnyxParser *parser, Scope *scope);
7376

7477
#endif // #ifndef ONYXPARSER_H

compiler/src/astnodes.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ static const char* ast_node_names[] = {
119119

120120
"JS CODE",
121121

122+
"COMPILER EXTENSION",
123+
"PROCEDURAL MACRO",
124+
"PROCEDURAL EXPANSION",
125+
122126
"AST_NODE_KIND_COUNT",
123127
};
124128

@@ -167,6 +171,8 @@ const char* entity_type_strings[Entity_Type_Count] = {
167171
"Static If",
168172
"String Literal",
169173
"File Contents",
174+
"CompilerExtension",
175+
"Procedural Expansion",
170176
"Enum",
171177
"Enum Value",
172178
"Type Alias",
@@ -1469,6 +1475,8 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) {
14691475
TypeMatch implicit_cast_to_bool(AstTyped **pnode) {
14701476
AstTyped *node = *pnode;
14711477

1478+
if (!node->type) return TYPE_MATCH_YIELD;
1479+
14721480
if ((node->type->kind == Type_Kind_Basic && node->type->Basic.kind == Basic_Kind_Rawptr)
14731481
|| (node->type->kind == Type_Kind_Pointer)
14741482
|| (node->type->kind == Type_Kind_MultiPointer)) {

compiler/src/checker.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ CheckStatus check_for(AstFor* fornode) {
398398
// HACK: This assumes the Iterator type only has a single type argument.
399399
given_type = iter_type->Struct.poly_sln[0].type;
400400
fornode->loop_type = For_Loop_Iterator;
401+
fornode->var->flags |= Ast_Flag_Address_Taken;
401402
}
402403

403404
if (given_type == NULL)
@@ -612,8 +613,7 @@ CheckStatus check_switch(AstSwitch* switchnode) {
612613
i64 lower = ((AstNumLit *) rl->low)->value.l;
613614
i64 upper = ((AstNumLit *) rl->high)->value.l;
614615

615-
// NOTE: This is inclusive!!!!
616-
fori (case_value, lower, upper + 1) {
616+
fori (case_value, lower, upper) {
617617
if (add_case_to_switch_statement(switchnode, case_value, sc, rl->token->pos))
618618
return Check_Error;
619619
}
@@ -930,7 +930,10 @@ CheckStatus check_call(AstCall** pcall) {
930930

931931
char* err_msg = NULL;
932932
fill_in_arguments(&call->args, (AstNode *) callee, &err_msg, 0);
933-
if (err_msg != NULL) ERROR(call->token->pos, err_msg);
933+
if (err_msg != NULL) {
934+
onyx_report_error(callee->token->pos, Error_Critical, "Here is the function being called.");
935+
ERROR(call->token->pos, err_msg);
936+
}
934937

935938
bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values;
936939
bh_arr_each(AstArgument *, arg, arg_arr) {
@@ -2653,6 +2656,8 @@ CheckStatus check_expression(AstTyped** pexpr) {
26532656
case Ast_Kind_Foreign_Block: break;
26542657
case Ast_Kind_Zero_Value: break;
26552658
case Ast_Kind_Interface: break;
2659+
case Ast_Kind_Compiler_Extension: break;
2660+
case Ast_Kind_Procedural_Macro: break;
26562661

26572662
default:
26582663
retval = Check_Error;
@@ -3360,6 +3365,9 @@ CheckStatus check_union(AstUnionType *u_node) {
33603365
bh_arr_each(AstUnionVariant *, variant, u_node->variants) {
33613366
CHECK(type, &(* variant)->type_node);
33623367
CHECK(meta_tags, (* variant)->meta_tags);
3368+
if ((*variant)->explicit_tag_value) {
3369+
CHECK(expression, &(* variant)->explicit_tag_value);
3370+
}
33633371
}
33643372

33653373
type_build_from_ast(context.ast_alloc, (AstType *) u_node);

compiler/src/cli.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ static const char *build_docstring = DOCSTRING_HEADER
9494
C_LBLUE " --print-static-if-results " C_NORM "Prints the conditional result of every " C_YELLOW "#if" C_NORM " statement\n"
9595
"\n"
9696
C_LBLUE " --no-file-contents " C_NORM "Disables " C_YELLOW "#file_contents" C_NORM " for security\n"
97+
C_LBLUE " --no-compiler-extensions " C_NORM "Disables " C_YELLOW "#compiler_extension" C_NORM " for security\n"
9798
"\n";
9899

99100
static const char *self_upgrade_docstring = DOCSTRING_HEADER
@@ -271,6 +272,9 @@ static void cli_parse_compilation_options(CompileOptions *options, int arg_parse
271272
else if (!strcmp(argv[i], "--no-file-contents")) {
272273
options->no_file_contents = 1;
273274
}
275+
else if (!strcmp(argv[i], "--no-compiler-extensions")) {
276+
options->no_compiler_extensions = 1;
277+
}
274278
else if (!strcmp(argv[i], "--wasm-mvp")) {
275279
options->use_post_mvp_features = 0;
276280
}
@@ -429,7 +433,7 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg
429433
.no_stale_code = 0,
430434
.show_all_errors = 0,
431435

432-
.enable_optional_semicolons = 0,
436+
.enable_optional_semicolons = 1,
433437

434438
.runtime = Runtime_Onyx,
435439

@@ -501,7 +505,6 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg
501505
case ONYX_COMPILE_ACTION_RUN:
502506
case ONYX_COMPILE_ACTION_WATCH:
503507
case ONYX_COMPILE_ACTION_COMPILE:
504-
case ONYX_COMPILE_ACTION_RUN_WASM:
505508
cli_parse_compilation_options(&options, arg_parse_start, argc, argv);
506509
break;
507510

@@ -515,6 +518,7 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg
515518
}
516519
break;
517520

521+
case ONYX_COMPILE_ACTION_RUN_WASM:
518522
case ONYX_COMPILE_ACTION_PRINT_HELP:
519523
case ONYX_COMPILE_ACTION_PRINT_VERSION:
520524
case ONYX_COMPILE_ACTION_DOCUMENT:

compiler/src/entities.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,22 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s
431431
break;
432432
}
433433

434+
case Ast_Kind_Compiler_Extension: {
435+
ent.type = Entity_Type_Compiler_Extension;
436+
ent.compiler_extension = (AstCompilerExtension *) node;
437+
ent.state = Entity_State_Resolve_Symbols;
438+
ENTITY_INSERT(ent);
439+
break;
440+
}
441+
442+
case Ast_Kind_Procedural_Expansion: {
443+
ent.type = Entity_Type_Procedural_Expansion;
444+
ent.proc_expansion = (AstProceduralExpansion *) node;
445+
ent.state = Entity_State_Resolve_Symbols;
446+
ENTITY_INSERT(ent);
447+
break;
448+
}
449+
434450
default: {
435451
ent.type = Entity_Type_Expression;
436452
ent.expr = (AstTyped *) node;

0 commit comments

Comments
 (0)