From: Brendan Hansen Date: Mon, 10 Jan 2022 02:20:47 +0000 (-0600) Subject: made even quicker procedures X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8af5c5c1ce101e8904f77ccfc3d2a03456719f6d;p=onyx.git made even quicker procedures --- diff --git a/core/container/list.onyx b/core/container/list.onyx index 9d8ee581..56e2f240 100644 --- a/core/container/list.onyx +++ b/core/container/list.onyx @@ -8,11 +8,11 @@ ListElem :: struct (T: type_expr) { data: T; } -List :: struct (T: type_expr) { +List :: struct (Elem_Type: type_expr) { allocator: Allocator; - first: ^ListElem(T) = null; - last: ^ListElem(T) = null; + first: ^ListElem(Elem_Type) = null; + last: ^ListElem(Elem_Type) = null; // "Method" like things free :: free @@ -32,7 +32,7 @@ make :: ($T: type_expr, allocator := context.allocator) -> List(T) { return .{ allocator = allocator }; } -free :: (list: ^List($T)) { +free :: (list: ^List) { elem := list.first; while elem != null { to_delete := elem; @@ -41,7 +41,7 @@ free :: (list: ^List($T)) { } } -push_end :: (list: ^List($T), x: T) { +push_end :: (list: ^List, x: list.Elem_Type) { new_elem := allocate_elem(list); new_elem.data = x; @@ -52,7 +52,7 @@ push_end :: (list: ^List($T), x: T) { if list.first == null do list.first = new_elem; } -push_begin :: (list: ^List($T), x: T) { +push_begin :: (list: ^List, x: list.Elem_Type) { new_elem := allocate_elem(list); new_elem.data = x; @@ -85,7 +85,7 @@ pop_begin :: (list: ^List($T), default: T = __zero_value(T)) -> T { return begin.data; } -count :: (list: ^List($T)) -> i32 { +count :: (list: ^List) -> i32 { c := 0; elem := list.first; while elem != null { @@ -96,7 +96,7 @@ count :: (list: ^List($T)) -> i32 { return c; } -at :: (list: ^List($T), index: i32) -> ^T { +at :: (list: ^List, index: i32) -> ^T { elem := list.first; while elem != null { if index == 0 do return ^elem.data; @@ -107,7 +107,7 @@ at :: (list: ^List($T), index: i32) -> ^T { return null; } -contains :: (list: ^List($T), x: T) -> bool { +contains :: (list: ^List, x: list.Elem_Type) -> bool { elem := list.first; while elem != null { if elem.data == x do return true; diff --git a/src/parser.c b/src/parser.c index 188dcde0..24944d6b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -294,7 +294,13 @@ static void parse_arguments(OnyxParser* parser, TokenType end_token, Arguments* while (!consume_token_if_next(parser, end_token)) { if (parser->hit_unexpected_token) return; - if (next_tokens_are(parser, 2, Token_Type_Symbol, '=')) { + // + // This has a weird condition to avoid the problem of using a quick function as an argument: + // f(x => x + 1) + // This shouldn't be a named argument, but this should: + // f(g = x => x + 1) + // + if (next_tokens_are(parser, 2, Token_Type_Symbol, '=') && peek_token(2)->type != '>') { OnyxToken* name = expect_token(parser, Token_Type_Symbol); expect_token(parser, '='); @@ -440,6 +446,11 @@ static AstTyped* parse_factor(OnyxParser* parser) { } case Token_Type_Symbol: { + if (parse_possible_quick_function_definition(parser, &retval)) { + ENTITY_SUBMIT(retval); + break; + } + OnyxToken* sym_token = expect_token(parser, Token_Type_Symbol); AstTyped* sym_node = make_node(AstTyped, Ast_Kind_Symbol); sym_node->token = sym_token; @@ -2435,6 +2446,12 @@ typedef struct QuickParam { } QuickParam; static b32 parse_possible_quick_function_definition_no_consume(OnyxParser* parser) { + // + // x => x + 1 case. + if (next_tokens_are(parser, 3, Token_Type_Symbol, '=', '>')) { + return 1; + } + if (parser->curr->type != '(') return 0; OnyxToken* matching_paren = find_matching_paren(parser->curr); @@ -2451,26 +2468,35 @@ static b32 parse_possible_quick_function_definition_no_consume(OnyxParser* parse static b32 parse_possible_quick_function_definition(OnyxParser* parser, AstTyped** ret) { if (!parse_possible_quick_function_definition_no_consume(parser)) return 0; - OnyxToken* proc_token = expect_token(parser, '('); - bh_arr(QuickParam) params=NULL; bh_arr_new(global_heap_allocator, params, 4); + OnyxToken* proc_token; - while (parser->curr->type != ')') { - if (parser->hit_unexpected_token) return 0; - + if (parser->curr->type == Token_Type_Symbol) { QuickParam param = { 0 }; - if (consume_token_if_next(parser, '$')) param.is_baked = 1; param.token = expect_token(parser, Token_Type_Symbol); - + proc_token = param.token; bh_arr_push(params, param); - if (parser->curr->type != ')') { - expect_token(parser, ','); + } else { + proc_token = expect_token(parser, '('); + while (parser->curr->type != ')') { + if (parser->hit_unexpected_token) return 0; + + QuickParam param = { 0 }; + if (consume_token_if_next(parser, '$')) param.is_baked = 1; + param.token = expect_token(parser, Token_Type_Symbol); + + bh_arr_push(params, param); + + if (parser->curr->type != ')') { + expect_token(parser, ','); + } } + + expect_token(parser, ')'); } - expect_token(parser, ')'); expect_token(parser, '='); expect_token(parser, '>'); diff --git a/src/polymorph.h b/src/polymorph.h index 95781d77..744cbfa4 100644 --- a/src/polymorph.h +++ b/src/polymorph.h @@ -875,7 +875,7 @@ b32 potentially_convert_function_to_polyproc(AstFunction *func) { case Ast_Kind_Array_Type: to_replace = &((AstArrayType *) *to_replace)->elem; param_type = ((AstArrayType *) param_type)->elem; break; case Ast_Kind_Slice_Type: to_replace = &((AstSliceType *) *to_replace)->elem; param_type = ((AstSliceType *) param_type)->elem; break; case Ast_Kind_DynArr_Type: to_replace = &((AstDynArrType *) *to_replace)->elem; param_type = ((AstDynArrType *) param_type)->elem; break; - case Ast_Kind_Alias: param_type = ((AstAlias *) param_type)->alias; break; + case Ast_Kind_Alias: param_type = (AstType *) ((AstAlias *) param_type)->alias; break; case Ast_Kind_Type_Alias: param_type = ((AstTypeAlias *) param_type)->to; break; case Ast_Kind_Poly_Struct_Type: { AutoPolymorphVariable apv; diff --git a/src/symres.c b/src/symres.c index dc00eff9..d6e1ae50 100644 --- a/src/symres.c +++ b/src/symres.c @@ -4,6 +4,8 @@ #include "astnodes.h" #include "errors.h" +// :EliminatingSymres - notes the places where too much work is being done in symbol resolution + // Variables used during the symbol resolution phase. static Scope* curr_scope = NULL; static b32 report_unresolved_symbols = 1; @@ -216,7 +218,7 @@ static SymresStatus symres_type(AstType** type) { case Ast_Kind_Alias: { AstAlias* alias = (AstAlias *) *type; - SYMRES_INVISIBLE(type, alias, &alias->alias); + SYMRES_INVISIBLE(type, alias, (AstType **) &alias->alias); break; } @@ -356,6 +358,7 @@ static SymresStatus symres_pipe(AstBinaryOp** pipe) { if ((*pipe)->left == NULL) return Symres_Error; + // :EliminatingSymres bh_arr_insertn(call_node->args.values, 0, 1); call_node->args.values[0] = (AstTyped *) make_argument(context.ast_alloc, (*pipe)->left); call_node->next = (*pipe)->next; @@ -386,14 +389,15 @@ static SymresStatus symres_method_call(AstBinaryOp** mcall) { SYMRES(expression, &(*mcall)->left); if ((*mcall)->left == NULL) return Symres_Error; + // :EliminatingSymres if (((*mcall)->flags & Ast_Flag_Has_Been_Symres) == 0) { AstFieldAccess* implicit_field_access = make_field_access(context.ast_alloc, (*mcall)->left, NULL); implicit_field_access->token = call_node->callee->token; call_node->callee = (AstTyped *) implicit_field_access; + (*mcall)->flags |= Ast_Flag_Has_Been_Symres; } SYMRES(expression, (AstTyped **) &call_node); - (*mcall)->flags |= Ast_Flag_Has_Been_Symres; return Symres_Success; } @@ -411,6 +415,7 @@ static SymresStatus symres_unaryop(AstUnaryOp** unaryop) { static SymresStatus symres_struct_literal(AstStructLiteral* sl) { if (sl->stnode != NULL) SYMRES(expression, &sl->stnode); + // :EliminatingSymres sl->type_node = (AstType *) sl->stnode; while (sl->type_node && sl->type_node->kind == Ast_Kind_Type_Alias) sl->type_node = ((AstTypeAlias *) sl->type_node)->to; @@ -423,6 +428,7 @@ static SymresStatus symres_struct_literal(AstStructLiteral* sl) { static SymresStatus symres_array_literal(AstArrayLiteral* al) { if (al->atnode != NULL) SYMRES(expression, &al->atnode); + // :EliminatingSymres al->type_node = (AstType *) al->atnode; while (al->type_node && al->type_node->kind == Ast_Kind_Type_Alias) al->type_node = ((AstTypeAlias *) al->type_node)->to; @@ -468,6 +474,7 @@ static SymresStatus symres_expression(AstTyped** expr) { SYMRES(expression, &((AstRangeLiteral *)(*expr))->low); SYMRES(expression, &((AstRangeLiteral *)(*expr))->high); + // :EliminatingSymres SYMRES(type, &builtin_range_type); (*expr)->type_node = builtin_range_type; @@ -539,7 +546,7 @@ static SymresStatus symres_expression(AstTyped** expr) { case Ast_Kind_Param: if ((*expr)->flags & Ast_Flag_Param_Symbol_Dirty) { assert((*expr)->token->type == Token_Type_Symbol); - *expr = make_symbol(context.ast_alloc, (*expr)->token); + *expr = (AstTyped *) make_symbol(context.ast_alloc, (*expr)->token); SYMRES(expression, expr); } break; @@ -657,6 +664,7 @@ static SymresStatus symres_switch(AstSwitch* switchnode) { static SymresStatus symres_use(AstUse* use) { SYMRES(expression, &use->expr); + // :EliminatingSymres if (use->expr->kind == Ast_Kind_Package) { AstPackage* package = (AstPackage *) use->expr; SYMRES(package, package); @@ -728,6 +736,7 @@ static SymresStatus symres_use(AstUse* use) { if (use->expr->type_node == NULL && use->expr->type == NULL) goto cannot_use; + // :EliminatingSymres AstType* effective_type = use->expr->type_node; if (effective_type->kind == Ast_Kind_Pointer_Type) effective_type = ((AstPointerType *) effective_type)->elem; @@ -956,6 +965,7 @@ SymresStatus symres_function(AstFunction* func) { scope_enter(func->scope); if ((func->flags & Ast_Flag_Has_Been_Symres) == 0) { + // :EliminatingSymres bh_arr_each(AstParam, param, func->params) { // CLEANUP: Currently, in order to 'use' parameters, the type must be completely // resolved and built. This is excessive because all that should need to be known @@ -1064,6 +1074,7 @@ static SymresStatus symres_enum(AstEnumType* enum_node) { scope_enter(enum_node->scope); + // :EliminatingSymres u64 next_assign_value = enum_node->is_flags ? 1 : 0; bh_arr_each(AstEnumValue *, value, enum_node->values) { if ((*value)->flags & Ast_Flag_Has_Been_Checked) continue; @@ -1187,6 +1198,7 @@ static SymresStatus symres_static_if(AstIf* static_if) { } static SymresStatus symres_process_directive(AstNode* directive) { + // :EliminatingSymres switch (directive->kind) { case Ast_Kind_Directive_Add_Overload: { AstDirectiveAddOverload *add_overload = (AstDirectiveAddOverload *) directive; @@ -1325,6 +1337,7 @@ static SymresStatus symres_constraint(AstConstraint* constraint) { } static SymresStatus symres_polyquery(AstPolyQuery *query) { + // :EliminatingSymres query->successful_symres = 0; if (query->function_header->scope == NULL) diff --git a/tests/lazy_iterators.onyx b/tests/lazy_iterators.onyx index a87ff4cc..2363483a 100644 --- a/tests/lazy_iterators.onyx +++ b/tests/lazy_iterators.onyx @@ -42,7 +42,7 @@ main :: (args: [] cstr) { quick_iterator := count_iterator(1.0f, 20.0f) - |> iter.map((x) => x * 2) + |> iter.map(x => x * 2) |> iter.filter(lower_bound, (x, l) => x > ~~l) |> iter.map(addition, (x, addition) => x + ~~addition) |> iter.take(5); @@ -70,9 +70,9 @@ main :: (args: [] cstr) { println("\nStarting the zipped iteration..."); zipped_iterator := count_iterator(1, 10) - |> iter.map((x) => x * 2) - |> iter.filter((x) => x > 10) - |> iter.map((x) => x + 42) + |> iter.map(x => x * 2) + |> iter.filter(x => x > 10) + |> iter.map(x => x + 42) |> iter.zip(iter.const(42.0f)); for value: zipped_iterator {