@@ -364,7 +364,7 @@ fn void Parser.parseTopLevel(Parser* p) {
364364 break;
365365 case KW_fn:
366366 if (p.tokenizer.c_mode) goto invalid_c;
367- p.parseFuncDecl(is_public);
367+ p.parseFuncDecl(is_public, false );
368368 break;
369369 case KW_import:
370370 p.error("no imports allowed after declarations");
@@ -496,27 +496,73 @@ fn void Parser.applyAttributes(Parser* p, Decl* d, u32 count) {
496496 if (count) p.builder.applyAttributes(d, count);
497497}
498498
499- fn void Parser.parseFuncDecl(Parser* p, bool is_public) {
500- p.consumeToken();
499+ fn u32 Parser.createLocalName(Parser* p, u32 name, SrcLoc loc, u32* plen) {
500+ char[128] buf;
501+ *plen = (u32)snprintf(buf, sizeof(buf), "%s__%d", p.pool.idx2str(name), loc);
502+ return p.pool.addStr(buf, true);
503+ }
504+
505+ fn Expr* Parser.parseLocalFuncExpr(Parser* p) {
506+ SrcLoc loc = p.tok.loc;
507+ FunctionDecl* f = p.parseFuncDecl(false, true);
508+ Decl* d = f.asDecl();
509+ u32 name = d.getNameIdx();
510+ u32 len;
511+ u32 local_name = p.createLocalName(name, loc, &len);
512+ d.setNameIdx(local_name);
513+ p.builder.addSymbol(local_name, d);
514+ return p.builder.actOnIdentifier(loc, local_name, len);
515+ }
516+
517+ fn Stmt* Parser.parseLocalFuncStmt(Parser* p) {
518+ SrcLoc loc = p.tok.loc;
519+ FunctionDecl* f = p.parseFuncDecl(false, true);
520+ Decl* d = f.asDecl();
521+ u32 name = d.getNameIdx();
522+ u32 len;
523+ u32 local_name = p.createLocalName(name, loc, &len);
524+ d.setNameIdx(local_name);
525+ p.builder.addSymbol(local_name, d);
526+ Expr* fexpr = p.builder.actOnIdentifier(loc, local_name, len);
527+ // TODO: use auto typing
528+ TypeRefHolder ref.init();
529+ ref.setVoid(loc);
530+ ref.addPointer();
531+ VarDecl* decl = p.builder.actOnVarDecl(name, loc, &ref, loc, fexpr, false, false);
532+ return p.builder.actOnDeclStmt(&decl, 1);
533+ }
534+
535+ fn FunctionDecl* Parser.parseFuncDecl(Parser* p, bool is_public, bool is_local) {
536+ u32 func_name = 0;
537+ SrcLoc func_loc = p.tok.loc;
538+ Ref prefix_ref;
539+ Ref* prefix = nil;
540+
541+ p.consumeToken(); // fn
501542
502543 TypeRefHolder rtype.init();
503544 // Note: dont check arrays in this phase, but in Analyser
504545 p.parseTypeSpecifier(&rtype);
505546
506- p.expectIdentifier();
507- u32 func_name = p.tok.name_idx;
508- SrcLoc func_loc = p.tok.loc;
509- p.consumeToken();
510-
511- p.parseFunctionDecl2(func_name, func_loc, is_public, &rtype);
547+ if (p.tok.kind == Identifier || !is_local) {
548+ p.expectIdentifier();
549+ func_name = p.tok.name_idx;
550+ func_loc = p.tok.loc;
551+ p.consumeToken();
552+ }
553+ return p.parseFunctionDecl2(func_name, func_loc, is_public, is_local, &rtype);
512554}
513555
514- fn void Parser.parseFunctionDecl2(Parser* p, u32 func_name, SrcLoc func_loc,
515- bool is_public, TypeRefHolder* rtype)
556+ fn FunctionDecl* Parser.parseFunctionDecl2(Parser* p, u32 func_name, SrcLoc func_loc,
557+ bool is_public, bool is_local , TypeRefHolder* rtype)
516558{
517559 Ref prefix_ref;
518560 Ref* prefix = nil;
561+
519562 if (p.tok.kind == Dot) {
563+ if (is_local) {
564+ p.error("local functions cannot be type functions");
565+ }
520566 p.consumeToken();
521567 p.expectIdentifier();
522568
@@ -529,16 +575,27 @@ fn void Parser.parseFunctionDecl2(Parser* p, u32 func_name, SrcLoc func_loc,
529575 p.consumeToken();
530576 }
531577
532- if (!p.checkName(func_name, p.is_interface)) {
578+ if (func_name && !p.checkName(func_name, p.is_interface)) {
533579 p.errorAt(func_loc, "a function name must start with a lower case character");
534580 }
535581
536582 DeclList params.init();
537583
538584 bool is_variadic = p.parseFunctionParams(¶ms, is_public, true);
539585
586+ if (p.tok.kind == LSquare && is_local) {
587+ // TODO: parse capture specification
588+ while (!p.tok.done && p.tok.kind != RSquare) {
589+ p.consumeToken();
590+ }
591+ p.expectAndConsume(RSquare);
592+ }
593+
540594 FunctionDecl* f;
541595 if (p.tok.kind == KW_template) {
596+ if (is_local) {
597+ p.error("local functions cannot be template functions");
598+ }
542599 p.consumeToken();
543600 p.expectIdentifier();
544601
@@ -564,19 +621,21 @@ fn void Parser.parseFunctionDecl2(Parser* p, u32 func_name, SrcLoc func_loc,
564621 prefix,
565622 (VarDecl**)params.getDecls(),
566623 params.size(),
567- is_variadic);
624+ is_variadic, is_local );
568625 }
569626
570627 params.free();
571628
572- u32 num_attr = p.parseOptionalAttributes();
573- p.applyAttributes((Decl*)f, num_attr);
629+ if (!is_local) {
630+ u32 num_attr = p.parseOptionalAttributes();
631+ p.applyAttributes((Decl*)f, num_attr);
632+ }
574633
575634 if (p.is_interface) {
576635 if (p.tok.kind == Semicolon) {
577636 // function without body (eg. i32 printf(..); ) is allowed
578637 p.consumeToken();
579- return;
638+ return f ;
580639 }
581640
582641 if (func_name != p.main_idx) {
@@ -585,9 +644,10 @@ fn void Parser.parseFunctionDecl2(Parser* p, u32 func_name, SrcLoc func_loc,
585644 }
586645 }
587646
588- p.stmt_list_count = 0;
647+ if (!is_local) p.stmt_list_count = 0;
589648 CompoundStmt* body = p.parseCompoundStmt();
590649 p.builder.actOnFunctionBody(f, body);
650+ return f;
591651}
592652
593653fn bool Parser.parseFunctionParams(Parser* p, DeclList* params, bool is_public, bool accept_default) {
@@ -762,7 +822,7 @@ fn void Parser.parseVarDecl(Parser* p, bool is_public) {
762822 if (!p.tokenizer.c_mode) {
763823 p.error("function definitions require the 'fn' keyword");
764824 }
765- p.parseFunctionDecl2(name, loc, is_public, &ref);
825+ p.parseFunctionDecl2(name, loc, is_public, false, &ref);
766826 return;
767827 }
768828
@@ -772,7 +832,7 @@ fn void Parser.parseVarDecl(Parser* p, bool is_public) {
772832 // Either a function definition or an init call
773833 if (!p.tokenizer.c_mode)
774834 p.error("global variables cannot have an init call");
775- p.parseFunctionDecl2(name, loc, is_public, &ref);
835+ p.parseFunctionDecl2(name, loc, is_public, false, &ref);
776836 return;
777837 }
778838 p.error("global type variables not supported");
0 commit comments