File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -3,7 +3,7 @@ CFLAGS = -std=c99 -Wall -Wextra -Wno-unused-parameter -g
33CTEST_FLAGS = -std=c99 -g
44LDFLAGS = -lcriterion
55
6- SOURCES = src/scanner.c src/chunk.c src/compiler.c src/debug.c src/memory.c src/value.c src/vm.c src/object.c src/table.c
6+ SOURCES = src/scanner.c src/chunk.c src/compiler.c src/debug.c src/memory.c src/value.c src/vm.c src/object.c src/table.c src/native_fn.c
77TEST_SOURCES = tests/scanner_test.c
88
99all : clox
Original file line number Diff line number Diff line change @@ -31,6 +31,11 @@ static void free_object(Obj* object)
3131 FREE (ObjFunction , object );
3232 break ;
3333 }
34+ case OBJ_NATIVE :
35+ {
36+ FREE (ObjNative , object );
37+ break ;
38+ }
3439 case OBJ_STRING :
3540 {
3641 ObjString * string = (ObjString * )object ;
Original file line number Diff line number Diff line change 1+ #include "native_fn.h"
2+ #include <time.h>
3+
4+ Value clock_native (int arg_count , Value * args )
5+ {
6+ return NUMBER_VAL ((double )clock () / CLOCKS_PER_SEC );
7+ }
Original file line number Diff line number Diff line change 1+ #ifndef clox_native_fn_c
2+ #define clox_native_fn_c
3+
4+ #include "value.h"
5+
6+ Value clock_native (int arg_count , Value * args );
7+
8+ #endif
Original file line number Diff line number Diff line change @@ -33,6 +33,13 @@ ObjFunction* new_function()
3333 return function ;
3434}
3535
36+ ObjNative * new_native (NativeFn function )
37+ {
38+ ObjNative * native = ALLOCATE_OBJ (ObjNative , OBJ_NATIVE );
39+ native -> function = function ;
40+ return native ;
41+ }
42+
3643static ObjString * allocate_string (char * chars , int length , u32 hash )
3744{
3845 ObjString * string = ALLOCATE_OBJ (ObjString , OBJ_STRING );
@@ -106,6 +113,11 @@ void print_object(Value value)
106113 print_function (AS_FUNCTION (value ));
107114 break ;
108115 }
116+ case OBJ_NATIVE :
117+ {
118+ printf ("<native fn>" );
119+ break ;
120+ }
109121 case OBJ_STRING :
110122 {
111123
Original file line number Diff line number Diff line change 1010#define IS_FUNCTION (value ) is_obj_type(value, OBJ_FUNCTION);
1111#define AS_FUNCTION (value ) (((ObjFunction*)AS_OBJ(value)))
1212
13+ #define IS_NATIVE (value ) is_obj_type(value, OBJ_NATIVE);
14+ #define AS_NATIVE (value ) (((ObjNative*)AS_OBJ(value))->function)
15+
1316#define IS_STRING (value ) is_obj_type(value, OBJ_STRING)
1417#define AS_STRING (value ) ((ObjString*)AS_OBJ(value))
1518#define AS_CSTRING (value ) (((ObjString*)AS_OBJ(value))->chars)
1619
1720typedef enum
1821{
19- OBJ_STRING ,
2022 OBJ_FUNCTION ,
23+ OBJ_NATIVE ,
24+ OBJ_STRING ,
2125} ObjType ;
2226
2327struct Obj
@@ -34,6 +38,15 @@ typedef struct
3438 ObjString * name ;
3539} ObjFunction ;
3640
41+ typedef Value (* NativeFn )(int arg_count , Value * args );
42+
43+ typedef struct
44+ {
45+ Obj obj ;
46+ NativeFn function ;
47+
48+ } ObjNative ;
49+
3750struct ObjString
3851{
3952 Obj obj ;
@@ -43,6 +56,7 @@ struct ObjString
4356};
4457
4558ObjFunction * new_function ();
59+ ObjNative * new_native (NativeFn function );
4660ObjString * take_string (char * chars , int length );
4761ObjString * copy_string (const char * chars , int length );
4862void print_object (Value value );
Original file line number Diff line number Diff line change 11#ifndef clox_value_h
22#define clox_value_h
33
4+ #include <stdbool.h>
5+
46typedef struct Obj Obj ;
57typedef struct ObjString ObjString ;
68
Original file line number Diff line number Diff line change 88#include "compiler.h"
99#include "debug.h"
1010#include "memory.h"
11+ #include "native_fn.h"
1112#include "object.h"
1213#include "table.h"
1314#include "value.h"
@@ -45,12 +46,23 @@ static void runtime_error(const char* format, ...)
4546 }
4647}
4748
49+ static void define_native (const char * name , NativeFn function )
50+ {
51+ push (OBJ_VAL (copy_string (name , (int )strlen (name ))));
52+ push (OBJ_VAL (new_native (function )));
53+ table_set (& vm .globals , AS_STRING (vm .stack [0 ]), vm .stack [1 ]);
54+ pop ();
55+ pop ();
56+ }
57+
4858void init_VM ()
4959{
5060 reset_stack ();
5161 vm .objects = NULL ;
5262 init_table (& vm .globals );
5363 init_table (& vm .strings );
64+
65+ define_native ("clock" , clock_native );
5466}
5567
5668void free_VM ()
@@ -108,6 +120,14 @@ static bool call_value(Value callee, int arg_count)
108120 {
109121 return call (AS_FUNCTION (callee ), arg_count );
110122 }
123+ case OBJ_NATIVE :
124+ {
125+ NativeFn native = AS_NATIVE (callee );
126+ Value result = native (arg_count , vm .stack_top - arg_count );
127+ vm .stack_top -= arg_count + 1 ;
128+ push (result );
129+ return true;
130+ }
111131 default :
112132 // No callable shit
113133 break ;
You can’t perform that action at this time.
0 commit comments