Skip to content

Commit 1ce791b

Browse files
committed
refactor: introduce functions so each chunk will be executed should be wrapped by a function
1 parent 91e4067 commit 1ce791b

5 files changed

Lines changed: 90 additions & 14 deletions

File tree

src/compiler.c

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,17 @@ typedef struct
5353
bool is_immutable;
5454
} Local;
5555

56+
typedef enum
57+
{
58+
TYPE_FUNCTION,
59+
TYPE_SCRIPT,
60+
} FunctionType;
61+
5662
typedef struct
5763
{
64+
ObjFunction* function;
65+
FunctionType type;
66+
5867
Local locals[UINT8_COUNT];
5968
int local_count;
6069
int scope_depth;
@@ -63,12 +72,12 @@ typedef struct
6372
static bool immutable_globals[UINT8_MAX];
6473

6574
Parser parser;
66-
Compiler* current;
75+
Compiler* current = NULL;
6776
Chunk* compiling_chunk;
6877

6978
static Chunk* current_chunk()
7079
{
71-
return compiling_chunk;
80+
return &current->function->chunk;
7281
}
7382

7483
static inline void error_at(Token* token, const char* message)
@@ -201,20 +210,33 @@ static void patch_jump(int offset)
201210
current_chunk()->code[offset] = (jump >> 8) & 0xff;
202211
current_chunk()->code[offset + 1] = jump & 0xff;
203212
}
204-
static void init_compiler(Compiler* compiler)
213+
static void init_compiler(Compiler* compiler, FunctionType type)
205214
{
215+
compiler->function = NULL;
216+
compiler->type = type;
206217
compiler->local_count = 0;
207218
compiler->scope_depth = 0;
208219
current = compiler;
220+
221+
Local* local = &current->locals[current->local_count++];
222+
local->depth = 0;
223+
local->name.start = "";
224+
local->name.length = 0;
209225
}
210226

211-
static void end_compiler()
227+
static ObjFunction* end_compiler()
212228
{
213229
emit_return();
230+
ObjFunction* function = current->function;
231+
214232
#ifdef DEBUG_PRINT_CODE
215233
if (!parser.had_error)
216-
disassemble_chunk(current_chunk(), "code");
234+
disassemble_chunk(current_chunk(), function->name != NULL
235+
? function->name->chars
236+
: "<script>");
217237
#endif
238+
239+
return function;
218240
}
219241

220242
static void begin_scope()
@@ -615,7 +637,7 @@ static void expression_statement()
615637
emit_byte(OP_POP);
616638
}
617639

618-
static void for_satement()
640+
static void for_statement()
619641
{
620642
begin_scope();
621643
consume(TOKEN_LEFT_PAREN, "Expect '(' after 'for'");
@@ -779,11 +801,11 @@ static inline void init_parser()
779801
parser.panic_mode = false;
780802
}
781803

782-
bool compile(const char* source, Chunk* chunk)
804+
ObjFunction* compile(const char* source, Chunk* chunk)
783805
{
784806
init_scanner(source);
785807
Compiler compiler;
786-
init_compiler(&compiler);
808+
init_compiler(&compiler, TYPE_SCRIPT);
787809
compiling_chunk = chunk;
788810
init_parser();
789811

@@ -794,5 +816,6 @@ bool compile(const char* source, Chunk* chunk)
794816
}
795817

796818
end_compiler();
797-
return !parser.had_error;
819+
ObjFunction* function = end_compiler();
820+
return parser.had_error ? NULL : function;
798821
}

src/compiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
#define clox_compiler_h
33

44
#include "chunk.h"
5+
#include "object.h"
56

6-
bool compile(const char* source, Chunk* chunk);
7+
ObjFunction* compile(const char* source, Chunk* chunk);
78

89
#endif

src/memory.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <stdlib.h>
22

3+
#include "chunk.h"
34
#include "memory.h"
45
#include "object.h"
56
#include "value.h"
@@ -23,6 +24,13 @@ static void free_object(Obj* object)
2324
{
2425
switch (object->type)
2526
{
27+
case OBJ_FUNCTION:
28+
{
29+
ObjFunction* function = (ObjFunction*)object;
30+
free_chunk(&function->chunk);
31+
FREE(ObjFunction, object);
32+
break;
33+
}
2634
case OBJ_STRING:
2735
{
2836
ObjString* string = (ObjString*)object;

src/object.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <string.h>
44
#include <sys/types.h>
55

6+
#include "chunk.h"
67
#include "common.h"
78
#include "memory.h"
89
#include "object.h"
@@ -22,6 +23,16 @@ static Obj* allocate_object(size_t size, ObjType type)
2223
return object;
2324
}
2425

26+
ObjFunction* new_function()
27+
{
28+
ObjFunction* function = ALLOCATE_OBJ(ObjFunction, OBJ_FUNCTION);
29+
30+
function->arity = 0;
31+
function->name = NULL;
32+
init_chunk(&function->chunk);
33+
return function;
34+
}
35+
2536
static ObjString* allocate_string(char* chars, int length, u32 hash)
2637
{
2738
ObjString* string = ALLOCATE_OBJ(ObjString, OBJ_STRING);
@@ -75,13 +86,31 @@ ObjString* copy_string(const char* chars, int length)
7586
return allocate_string(heap_chars, length, hash);
7687
}
7788

89+
static void print_function(ObjFunction* function)
90+
{
91+
if (function->name == NULL)
92+
{
93+
printf("<script>");
94+
return;
95+
}
96+
printf("<fn %s>", function->name->chars);
97+
}
98+
7899
void print_object(Value value)
79100
{
80101

81102
switch (OBJ_TYPE(value))
82103
{
104+
case OBJ_FUNCTION:
105+
{
106+
print_function(AS_FUNCTION(value));
107+
break;
108+
}
83109
case OBJ_STRING:
110+
{
111+
84112
printf("%s", AS_CSTRING(value));
85113
break;
86114
}
115+
}
87116
}

src/object.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
#ifndef clox_object_h
22
#define clox_object_h
33

4+
#include "chunk.h"
45
#include "common.h"
56
#include "value.h"
67

78
#define OBJ_TYPE(value) (AS_OBJ(value)->type)
9+
10+
#define IS_FUNCTION(value) is_obj_type(value, OBJ_FUNCTION);
11+
#define AS_FUNCTION(value) (((ObjFunction*)AS_OBJ(value)))
12+
813
#define IS_STRING(value) is_obj_type(value, OBJ_STRING)
914
#define AS_STRING(value) ((ObjString*)AS_OBJ(value))
1015
#define AS_CSTRING(value) (((ObjString*)AS_OBJ(value))->chars)
1116

1217
typedef enum
1318
{
14-
OBJ_STRING
19+
OBJ_STRING,
20+
OBJ_FUNCTION,
1521
} ObjType;
1622

1723
struct Obj
@@ -20,6 +26,14 @@ struct Obj
2026
struct Obj* next;
2127
};
2228

29+
typedef struct
30+
{
31+
Obj obj;
32+
int arity;
33+
Chunk chunk;
34+
ObjString* name;
35+
} ObjFunction;
36+
2337
struct ObjString
2438
{
2539
Obj obj;
@@ -28,9 +42,10 @@ struct ObjString
2842
u32 hash;
2943
};
3044

31-
ObjString* take_string(char* chars, int length);
32-
ObjString* copy_string(const char* chars, int length);
33-
void print_object(Value value);
45+
ObjFunction* new_function();
46+
ObjString* take_string(char* chars, int length);
47+
ObjString* copy_string(const char* chars, int length);
48+
void print_object(Value value);
3449

3550
static inline bool is_obj_type(Value value, ObjType type)
3651
{

0 commit comments

Comments
 (0)