1414#include "debug.h"
1515#endif
1616
17+ #define PARAMETERS_MAX 255
18+
1719typedef struct
1820{
1921 Token previous ;
@@ -59,10 +61,11 @@ typedef enum
5961 TYPE_SCRIPT ,
6062} FunctionType ;
6163
62- typedef struct
64+ typedef struct Compiler
6365{
64- ObjFunction * function ;
65- FunctionType type ;
66+ struct Compiler * enclosing ;
67+ ObjFunction * function ;
68+ FunctionType type ;
6669
6770 Local locals [UINT8_COUNT ];
6871 int local_count ;
@@ -212,12 +215,19 @@ static void patch_jump(int offset)
212215}
213216static void init_compiler (Compiler * compiler , FunctionType type )
214217{
218+ compiler -> enclosing = current ;
215219 compiler -> function = NULL ;
216220 compiler -> type = type ;
217221 compiler -> local_count = 0 ;
218222 compiler -> scope_depth = 0 ;
219223 current = compiler ;
220224
225+ if (type != TYPE_SCRIPT )
226+ {
227+ current -> function -> name =
228+ copy_string (parser .previous .start , parser .previous .length );
229+ }
230+
221231 Local * local = & current -> locals [current -> local_count ++ ];
222232 local -> depth = 0 ;
223233 local -> name .start = "" ;
@@ -236,6 +246,7 @@ static ObjFunction* end_compiler()
236246 : "<script>" );
237247#endif
238248
249+ current = current -> enclosing ;
239250 return function ;
240251}
241252
@@ -337,6 +348,8 @@ static u8 parse_variable(bool is_immutable, char* error_message)
337348
338349static void mark_initialized ()
339350{
351+ if (current -> scope_depth == 0 )
352+ return ;
340353 current -> locals [current -> local_count - 1 ].depth = current -> scope_depth ;
341354}
342355
@@ -611,6 +624,45 @@ static void block()
611624 consume (TOKEN_RIGHT_BRACE , "Expect '}' after block" );
612625}
613626
627+ static void function (FunctionType type )
628+ {
629+ Compiler compiler ;
630+ init_compiler (& compiler , type );
631+ begin_scope ();
632+
633+ consume (TOKEN_LEFT_PAREN , "Expect '(' after function name" );
634+
635+ if (!check (TOKEN_RIGHT_PAREN ))
636+ {
637+ do
638+ {
639+ if (++ current -> function -> arity > PARAMETERS_MAX )
640+ {
641+ error_at_current ("Can't have more than 255 parameters" );
642+ }
643+
644+ u8 param_const = parse_variable (false, "Expect parameter name" );
645+ define_variable (param_const , false);
646+
647+ } while (match (TOKEN_COMMA ));
648+ }
649+ consume (TOKEN_RIGHT_PAREN , "Expect ')' after function parameters" );
650+
651+ consume (TOKEN_LEFT_BRACE , "Expect '{' before function body" );
652+ block ();
653+
654+ ObjFunction * function = end_compiler ();
655+ emit_bytes (OP_CONSTANT , make_constant (OBJ_VAL (function )));
656+ }
657+
658+ static void fun_declaration ()
659+ {
660+ u8 global = parse_variable (false, "Expect function name" );
661+ mark_initialized ();
662+ function (TYPE_FUNCTION );
663+ define_variable (global , false);
664+ }
665+
614666static void var_declaration ()
615667{
616668 bool is_immutable = parser .previous .type == TOKEN_VAL ;
@@ -766,7 +818,11 @@ static void synchronize()
766818
767819static void declaration ()
768820{
769- if (match (TOKEN_VAR ) || match (TOKEN_VAL ))
821+ if (match (TOKEN_FUN ))
822+ {
823+ fun_declaration ();
824+ }
825+ else if (match (TOKEN_VAR ) || match (TOKEN_VAL ))
770826 var_declaration ();
771827 else
772828 statement ();
0 commit comments