return ~~(str1[i] - str2[i]);
}
-#operator == equal
equal :: (str1: str, str2: str) -> bool {
if str1.count != str2.count do return false;
while i := 0; i < str1.count {
return true;
}
+#operator == equal
+#operator != macro (s1: str, s2: str) => !(s1 == s2);
+
starts_with :: (s: str, prefix: str) -> bool {
if s.count < prefix.count do return false;
while i := 0; i < prefix.count {
return true;
}
+
+enum_name :: (value: $Backing_Type) -> str {
+ info := get_type_info(Backing_Type);
+ if info.kind != .Enum do return null_str;
+
+ etype := cast(^Type_Info_Enum) info;
+ for ^member: etype.members {
+ if member.value == ~~value do return member.name;
+ }
+
+ return null_str;
+}
+
+enum_value :: ($E: type_expr, name: str) -> E {
+ info := get_type_info(E);
+ if info.kind != .Enum do return ~~0;
+
+ etype := cast(^Type_Info_Enum) info;
+ for ^member: etype.members {
+ if member.name == name do return ~~member.value;
+ }
+
+ return ~~0;
+}
{
// Checking the magic string
- magic_buffer: [4] u8;
+ magic_buffer: [4] u8;
@Bug // If these are string literals, then the null byte messes up the compiler and it thinks its a 0-character string.
- if !(io.read_bytes(^reader, cast([] u8) magic_buffer) == ~~u8.[ 0, #char "a", #char "s", #char "m" ]) do return false;
- if !(io.read_bytes(^reader, cast([] u8) magic_buffer) == ~~u8.[ 1, 0, 0, 0 ]) do return false; // This may not be necessary
+ if io.read_bytes(^reader, magic_buffer) != u8.[ 0, #char "a", #char "s", #char "m" ] do return false;
+ if io.read_bytes(^reader, magic_buffer) != u8.[ 1, 0, 0, 0 ] do return false; // This may not be necessary
}
while !io.stream_end_of_file(^stream) {
switch ((u16) parser->curr->type) {
case '(': {
- if (parse_possible_function_definition(parser, &retval)) break;
- if (parse_possible_quick_function_definition(parser, &retval)) break;
+ if (parse_possible_function_definition(parser, &retval)) {
+ ENTITY_SUBMIT(retval);
+ break;
+ }
+ if (parse_possible_quick_function_definition(parser, &retval)) {
+ ENTITY_SUBMIT(retval);
+ break;
+ }
consume_token(parser);
retval = parse_compound_expression(parser, 0);
OnyxToken* proc_token = parser->curr;
AstFunction* func_node = parse_function_definition(parser, proc_token);
- ENTITY_SUBMIT(func_node);
*ret = (AstTyped *) func_node;
return 1;
}
}
poly_proc->base_func = func_node;
- ENTITY_SUBMIT(poly_proc);
*ret = (AstTyped *) poly_proc;
bh_arr_free(params);
static AstMacro* parse_macro(OnyxParser* parser) {
AstMacro* macro = make_node(AstMacro, Ast_Kind_Macro);
macro->token = expect_token(parser, Token_Type_Keyword_Macro);
-
- // First try quick function
- if (!parse_possible_quick_function_definition(parser, ¯o->body)) {
- // Otherwise, do a normal function
- macro->body = (AstTyped *) parse_function_definition(parser, macro->token);
+
+ if (parse_possible_function_definition(parser, ¯o->body)) {
+ ENTITY_SUBMIT(macro);
+ return macro;
+ }
+
+ if (parse_possible_quick_function_definition(parser, ¯o->body)) {
+ ENTITY_SUBMIT(macro);
+ return macro;
}
- ENTITY_SUBMIT(macro);
- return macro;
+ onyx_report_error(parser->curr->pos, "'macro' expects to be followed by a producure definition.");
+ return NULL;
}
static AstTyped* parse_top_level_expression(OnyxParser* parser) {
WIL(WI_LOCAL_SET, rptr_local);
WIL(WI_LOCAL_SET, lptr_local);
+ WIL(WI_LOCAL_GET, rptr_local);
+ WID(WI_I32_CONST, 0);
+ WI(WI_I32_NE);
+ emit_enter_structured_block(mod, &code, SBT_Basic_If);
+
if (elem_count <= 2) {
// Inline copying for a small number of elements. It still may be faster to do this in a tight loop.
bh_arr_last(code).type = WI_LOCAL_TEE;
else
WIL(WI_LOCAL_GET, lptr_local);
- WIL(WI_PTR_CONST, offset);
- WI(WI_PTR_ADD);
+
+ if (offset != 0) {
+ WIL(WI_PTR_CONST, offset);
+ WI(WI_PTR_ADD);
+ }
WIL(WI_LOCAL_GET, rptr_local);
WIL(WI_I32_CONST, elem_count * elem_size);
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
}
+ WI(WI_ELSE);
+
+ { // If the source ptr is null (0), then just copy in 0 bytes.
+ WIL(WI_LOCAL_GET, lptr_local);
+ if (offset != 0) {
+ WIL(WI_PTR_CONST, offset);
+ WI(WI_PTR_ADD);
+ }
+
+ WIL(WI_I32_CONST, 0);
+
+ WIL(WI_I32_CONST, elem_count * elem_size);
+
+ if (context.options->use_post_mvp_features) {
+ WI(WI_MEMORY_FILL);
+ } else {
+ emit_intrinsic_memory_fill(mod, &code);
+ }
+ }
+
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
+ emit_leave_structured_block(mod, &code);
*pcode = code;
return;
}
type_linear_member_lookup(type, i, &two);
emit_zero_value_for_type(mod, &code, two.type, where);
}
-
}
else if (type->kind == Type_Kind_Function) {
WID(WI_I32_CONST, mod->null_proc_func_idx);