From: Brendan Hansen Date: Thu, 21 Jan 2021 00:56:15 +0000 (-0600) Subject: made 'proc' keyword optional in certain cases; bug fixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=1ba99de38c32fbad38f0b75ea7042b8249f30c54;p=onyx.git made 'proc' keyword optional in certain cases; bug fixes --- diff --git a/bin/onyx b/bin/onyx index 707c6d4b..82a5f9a0 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/alloc/arena.onyx b/core/alloc/arena.onyx index 93ac3317..e30515f5 100644 --- a/core/alloc/arena.onyx +++ b/core/alloc/arena.onyx @@ -35,6 +35,10 @@ arena_alloc_proc :: proc (data: rawptr, aa: AllocationAction, size: u32, align: return null; } + if alloc_arena.size % align != 0 { + alloc_arena.size += align - (alloc_arena.size % align); + } + if alloc_arena.size + size >= alloc_arena.arena_size { new_arena := cast(^Arena) raw_alloc(alloc_arena.backing_allocator, alloc_arena.arena_size); if new_arena == null do return null; diff --git a/core/math.onyx b/core/math.onyx index 812c70f6..7ab959c3 100644 --- a/core/math.onyx +++ b/core/math.onyx @@ -2,9 +2,11 @@ package core.math use package core.intrinsics.wasm { sqrt_f32, sqrt_f64, - abs_f32, abs_f64 + abs_f32, abs_f64, + copysign_f32, copysign_f64 } +E :: 2.71828182845904523536f; PI :: 3.14159265f; TAU :: 6.28318330f; @@ -67,6 +69,8 @@ sqrt_i32 :: proc (x: i32) -> i32 do return ~~sqrt_f32(~~x); sqrt_i64 :: proc (x: i64) -> i64 do return ~~sqrt_f64(~~x); sqrt :: proc { sqrt_f32, sqrt_f64, sqrt_i32, sqrt_i64 } +copysign :: proc { copysign_f32, copysign_f64 } + abs_i32 :: proc (x: i32) -> i32 { if x >= 0 do return x; return -x; @@ -78,26 +82,51 @@ abs_i64 :: proc (x: i64) -> i64 { abs :: proc { abs_i32, abs_i64, abs_f32, abs_f64 } pow_int :: proc (base: $T, p: i32) -> T { - if base == 0 && p == 0 do return 1; - elseif p == 0 do return 1; + if base == 0 do return 0; + if p == 0 do return 1; + a := 1; - b := p; - c := base; - while b > 0 { - if b % 2 == 1 do a *= c; - b = b >> 1; - c *= c; + while p > 0 { + if p % 2 == 1 do a *= base; + p = p >> 1; + base *= base; } + return a; } -pow_float :: proc (base: $T, p: f32) -> T { - if base == 0 && p == 0 do return 1; - elseif p == 0 do return 1; +pow_float :: proc (base: $T, p: T) -> T { + if p >= 1 { + tmp := pow_float(p = p / 2, base = base); + return tmp * tmp; + } + + low : T = 0; + high : T = 1; + + sqr := sqrt(base); + acc := sqr; + mid := high / 2; + + while abs(mid - p) > 0.00001 { + sqr = sqrt(sqr); + + if mid <= p { + low = mid; + acc *= sqr; + } else { + high = mid; + acc /= sqr; + } + + mid = (low + high) / 2; + } + return acc; } pow :: proc { pow_int, pow_float } +exp :: proc (p: $T) -> T do return pow(base = cast(T) E, p = p); ln :: proc (a: f32) -> f32 { diff --git a/src/onyxparser.c b/src/onyxparser.c index 5f6e1016..9273549e 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -45,7 +45,8 @@ static AstType* parse_type(OnyxParser* parser); static AstStructType* parse_struct(OnyxParser* parser); static void parse_function_params(OnyxParser* parser, AstFunction* func); static b32 parse_possible_directive(OnyxParser* parser, const char* dir); -static AstFunction* parse_function_definition(OnyxParser* parser); +static b32 parse_possible_function_definition(OnyxParser* parser, AstTyped** ret); +static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* token); static AstTyped* parse_global_declaration(OnyxParser* parser); static AstEnumType* parse_enum_declaration(OnyxParser* parser); static AstTyped* parse_top_level_expression(OnyxParser* parser); @@ -85,6 +86,31 @@ static void find_token(OnyxParser* parser, TokenType token_type) { } } +static OnyxToken* find_matching_paren(OnyxToken* paren) { + TokenType match = 0; + switch ((u16) paren->type) { + case '(': match = ')'; break; + case '[': match = ']'; break; + case '{': match = '}'; break; + case '<': match = '>'; break; + default: return NULL; + } + + i32 paren_count = 1; + i32 i = 1; + while (paren_count > 0) { + TokenType type = (paren + i)->type; + if (type == Token_Type_End_Stream) return NULL; + + if (type == paren->type) paren_count++; + else if (type == match) paren_count--; + + i++; + } + + return paren + (i - 1); +} + // Advances to next token no matter what static OnyxToken* expect_token(OnyxParser* parser, TokenType token_type) { if (parser->hit_unexpected_token) return NULL; @@ -269,6 +295,12 @@ static AstTyped* parse_factor(OnyxParser* parser) { switch ((u16) parser->curr->type) { case '(': { + if (parse_possible_function_definition(parser, &retval)) { + // CLEANUP + add_node_to_process(parser, (AstNode *) retval); + break; + } + consume_token(parser); AstTyped* expr = parse_compound_expression(parser, 0); expect_token(parser, ')'); @@ -420,7 +452,8 @@ static AstTyped* parse_factor(OnyxParser* parser) { } case Token_Type_Keyword_Proc: { - retval = (AstTyped *) parse_function_definition(parser); + OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); + retval = (AstTyped *) parse_function_definition(parser, proc_token); retval->flags |= Ast_Flag_Function_Used; // TODO: Maybe move this somewhere else? @@ -684,7 +717,7 @@ static inline i32 get_precedence(BinaryOp kind) { } static BinaryOp binary_op_from_token_type(TokenType t) { - switch (t) { + switch ((u16) t) { case Token_Type_Equal_Equal: return Binary_Op_Equal; case Token_Type_Not_Equal: return Binary_Op_Not_Equal; case Token_Type_Less_Equal: return Binary_Op_Less_Equal; @@ -1937,12 +1970,10 @@ static void parse_function_params(OnyxParser* parser, AstFunction* func) { } // 'proc' ('->' )? * -static AstFunction* parse_function_definition(OnyxParser* parser) { - OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); - +static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* token) { if (parser->curr->type == '{') { AstOverloadedFunction* ofunc = make_node(AstOverloadedFunction, Ast_Kind_Overloaded_Function); - ofunc->token = proc_token; + ofunc->token = token; bh_arr_new(global_heap_allocator, ofunc->overloads, 4); @@ -1963,7 +1994,7 @@ static AstFunction* parse_function_definition(OnyxParser* parser) { } AstFunction* func_def = make_node(AstFunction, Ast_Kind_Function); - func_def->token = proc_token; + func_def->token = token; func_def->operator_overload = -1; bh_arr_new(global_heap_allocator, func_def->allocate_exprs, 4); @@ -2063,6 +2094,47 @@ static AstFunction* parse_function_definition(OnyxParser* parser) { } } +static b32 parse_possible_function_definition(OnyxParser* parser, AstTyped** ret) { + if (parser->curr->type == Token_Type_Keyword_Proc) { + OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); + AstFunction* func_node = parse_function_definition(parser, proc_token); + *ret = (AstTyped *) func_node; + return 1; + } + + if (parser->curr->type == '(') { + OnyxToken* matching_paren = find_matching_paren(parser->curr); + if (matching_paren == NULL) return 0; + + OnyxToken* token_after_paren = matching_paren + 1; + if (token_after_paren->type != Token_Type_Right_Arrow + && token_after_paren->type != '{' + && token_after_paren->type != Token_Type_Keyword_Do + && token_after_paren->type != Token_Type_Empty_Block) + return 0; + + b32 hit_colon = 0; + OnyxToken* tmp_token = parser->curr; + while (tmp_token < matching_paren) { + if (tmp_token->type == ':') { + hit_colon = 1; + break; + } + + tmp_token++; + } + + if (!hit_colon) return 0; + + OnyxToken* proc_token = parser->curr; + AstFunction* func_node = parse_function_definition(parser, proc_token); + *ret = (AstTyped *) func_node; + return 1; + } + + return 0; +} + // 'global' static AstTyped* parse_global_declaration(OnyxParser* parser) { AstGlobal* global_node = make_node(AstGlobal, Ast_Kind_Global); @@ -2161,7 +2233,8 @@ static AstEnumType* parse_enum_declaration(OnyxParser* parser) { // static AstTyped* parse_top_level_expression(OnyxParser* parser) { if (parser->curr->type == Token_Type_Keyword_Proc) { - AstFunction* func_node = parse_function_definition(parser); + OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); + AstFunction* func_node = parse_function_definition(parser, proc_token); add_node_to_process(parser, (AstNode *) func_node); diff --git a/tests/aoc-2020/day22.onyx b/tests/aoc-2020/day22.onyx index 7786c40c..393b0b8a 100644 --- a/tests/aoc-2020/day22.onyx +++ b/tests/aoc-2020/day22.onyx @@ -45,7 +45,7 @@ combat :: proc (player1: ^[..] u32, player2: ^[..] u32) -> u32 { encode_hands :: proc (alloc: Allocator, p1: ^[..] u32, p2: ^[..] u32) -> str { use package core.string.builder as b - builder := b.make(128, alloc); + builder := b.make(256, alloc); for n: *p1 { b.add_i64(^builder, ~~n, 64); b.add_str(^builder, ",");