Skip to content

Commit 03ec04f

Browse files
committed
feat: implement function calls
1 parent 057a7cf commit 03ec04f

3 files changed

Lines changed: 68 additions & 1 deletion

File tree

src/chunk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ typedef enum
2929
OP_JUMP,
3030
OP_JUMP_IF_FALSE,
3131
OP_LOOP,
32+
OP_CALL,
3233
OP_RETURN,
3334
} OpCode;
3435

src/compiler.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,26 @@ static void define_variable(u8 global, bool is_immutable)
363363
emit_bytes(OP_DEFINE_GLOBAL, global);
364364
}
365365

366+
static u8 arguments_list()
367+
{
368+
u8 arg_count = 0;
369+
370+
if (!check(TOKEN_RIGHT_PAREN))
371+
{
372+
do
373+
{
374+
expression();
375+
if (arg_count == 255)
376+
{
377+
error("Can't have more than 255 arguments");
378+
}
379+
arg_count++;
380+
} while (match(TOKEN_COMMA));
381+
}
382+
consume(TOKEN_RIGHT_PAREN, "Expect ')' after arguments");
383+
return arg_count;
384+
}
385+
366386
static void and_(bool can_assign)
367387
{
368388
int end_jump = emit_jump(OP_JUMP_IF_FALSE);
@@ -417,6 +437,12 @@ static void binary(bool can_assign)
417437
}
418438
}
419439

440+
static void call(bool can_assign)
441+
{
442+
u8 arg_count = arguments_list();
443+
emit_bytes(OP_CALL, arg_count);
444+
}
445+
420446
static void literal(bool can_assign)
421447
{
422448
switch (parser.previous.type)
@@ -534,7 +560,7 @@ static void unary(bool can_assign)
534560
}
535561
// clang-format off
536562
ParseRule rules[] = {
537-
[TOKEN_LEFT_PAREN] = { grouping, NULL, PREC_NONE },
563+
[TOKEN_LEFT_PAREN] = { grouping, call, PREC_CALL },
538564
[TOKEN_RIGHT_PAREN] = { NULL, NULL, PREC_NONE },
539565
[TOKEN_LEFT_BRACE] = { NULL, NULL, PREC_NONE },
540566
[TOKEN_RIGHT_BRACE] = { NULL, NULL, PREC_NONE },

src/vm.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <linux/limits.h>
12
#include <stdarg.h>
23
#include <stdio.h>
34
#include <string.h>
@@ -68,6 +69,35 @@ static Value peek(int distance)
6869
return vm.stack_top[-1 - distance];
6970
}
7071

72+
static bool call(ObjFunction* function, int arg_count)
73+
{
74+
CallFrame* frame = &vm.frames[vm.frame_count++];
75+
frame->function = function;
76+
frame->ip = function->chunk.code;
77+
frame->slots = vm.stack_top - arg_count - 1;
78+
return true;
79+
}
80+
81+
static bool call_value(Value callee, int arg_count)
82+
{
83+
if (!IS_OBJ(callee))
84+
{
85+
runtime_error("Can only call functions and classes");
86+
return false;
87+
}
88+
89+
switch (OBJ_TYPE(callee))
90+
{
91+
case OBJ_FUNCTION:
92+
{
93+
return call(AS_FUNCTION(callee), arg_count);
94+
}
95+
default:
96+
// No callable shit
97+
break;
98+
}
99+
}
100+
71101
static bool is_falsey(Value value)
72102
{
73103
return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
@@ -262,6 +292,16 @@ static InterpretResult run()
262292
frame->ip -= offset;
263293
break;
264294
}
295+
case OP_CALL:
296+
{
297+
u8 arg_count = READ_BYTE();
298+
if (!call_value(peek(arg_count), arg_count))
299+
{
300+
return INTERPRET_RUNTIME_ERROR;
301+
}
302+
frame = &vm.frames[vm.frame_count - 1];
303+
break;
304+
}
265305
case OP_RETURN:
266306
return INTERPRET_OK;
267307
}

0 commit comments

Comments
 (0)