Skip to content

Commit a6dc876

Browse files
committedMar 7, 2023
Add VM Stack, OP_NEGATE
1 parent eb68e1b commit a6dc876

File tree

11 files changed

+146
-8
lines changed

11 files changed

+146
-8
lines changed
 

‎Makefile

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
CC = gcc-12
1+
CC = clang
22

3-
CFLAGS = -g -Wall -Wextra
3+
CFLAGS = -g -Wall
44

55
TARGET = cpplox
66

@@ -10,5 +10,10 @@ $(TARGET):
1010
$(CC) $(CFLAGS) -o $(TARGET).out src/*.c
1111

1212
clean:
13-
$(RM) -f *.out .DS_Store
13+
$(RM) -f .DS_Store
1414
$(RM) -rf *.dSYM/
15+
veryclean:
16+
$(RM) -f *.out
17+
$(RM) -f .DS_Store
18+
$(RM) -rf *.dSYM/
19+

‎README.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
# cpplox
22
Lox Language implementation in C, code for the bytecode virtual machine
3+
4+
## (TODO)
5+
6+
*Mon 2023-03-06 23:29+0530*
7+
1. Implement a run-length encoding algorithm for line checking.

‎src/chunk.c

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include <stdlib.h>
22
#include "chunk.h"
33
#include "memory.h"
4+
/* #include "value.h" */
45
/* #include <stdio.h> */
6+
57
void initChunk(Chunk* chunk) {
68
//Initialise chunk
79
chunk->count = 0;

‎src/chunk.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
#ifndef clox_chunk_h
33
#define clox_chunk_h
44

5-
65
#include "common.h"
76
#include "value.h"
7+
88
//Define opcode -> operation code
99
//return the kind of opertion that the interpeter is dealing with -> add, subtract etc.
1010
typedef enum {
1111
OP_RETURN,
12+
OP_NEGATE,
1213
OP_CONSTANT
1314
} OpCode;
1415

‎src/common.h

+11
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,16 @@
44
#include <stdbool.h>
55
#include <stddef.h>
66
#include <stdint.h>
7+
8+
#ifdef DEBUG_TRACE_EXECUTION
9+
printf(" ");
10+
for (Val *slot = vm.stack; slot < vm.stack_top; slot++) {
11+
printf("{ ");
12+
print_val(*slot);
13+
printf(" }");
14+
}
15+
printf("\n");
16+
disassembleInstruction(vm.chunk, (int)(vm.ip - vm.chunk->code));
717
//Use bool, size_t, uint8_t
818
#endif
19+
#endif

‎src/debug.c

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ int disassembleInstruction(Chunk* chunk, int offset) {
4141
return simpleInstruction("OP_RETURN", offset);
4242
case OP_CONSTANT:
4343
return const_instruction("OP_CONSTANT", chunk, offset);
44+
case OP_NEGATE:
45+
return simpleInstruction("OP_NEGATE", offset);
4446
default:
4547
printf("Unknown opcode %d\n", instruction);
4648
return offset + 1;

‎src/debug.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
#include "chunk.h"
55

6-
void disassembleChunk(Chunk* chunk, const char* name);
7-
int disassembleInstruction(Chunk* chunk, int offset);
6+
7+
void disassembleChunk(Chunk *chunk, const char* name);
8+
int disassembleInstruction(Chunk *chunk, int offset);
89

910
#endif

‎src/main.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
#include "common.h"
22
#include "chunk.h"
33
#include "debug.h"
4-
int main (int argc, char *argv[]) {
4+
#include "vm.h"
5+
6+
7+
int main () {
8+
init_vm();
59
Chunk chunk;
610
initChunk(&chunk);
711
writeChunk(&chunk, OP_CONSTANT, 123);
12+
813
int constant = add_const(&chunk, 1.5);
14+
915
writeChunk(&chunk, constant, 123);
16+
writeChunk(&chunk, OP_NEGATE, 123);
1017
writeChunk(&chunk, OP_RETURN, 123);
18+
1119
//Dissasemble the chunk!
1220
disassembleChunk(&chunk, "test chunk");
21+
22+
interpret(&chunk);
23+
free_vm();
1324
freeChunk(&chunk);
1425
return 0;
1526
}

‎src/memory.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <stdlib.h>
22
#include "memory.h"
33

4-
void* reallocate(void* pointer, size_t oldSize, size_t newSize){
4+
void* reallocate(void* pointer, size_t oldSize, size_t newSize){
55
if(newSize == 0) {
66
free(pointer);
77
return NULL;

‎src/vm.c

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include <stdio.h>
2+
#include "common.h"
3+
#include "debug.h"
4+
#include "vm.h"
5+
6+
/* Global decl */
7+
VM vm;
8+
9+
static void reset_stack() {
10+
vm.stack_top = vm.stack; //set stack_top to the beginning of the array to indecate it is empty
11+
}
12+
13+
void push(Val value) {
14+
*vm.stack_top = value;
15+
vm.stack_top++;
16+
}
17+
18+
Val pop() {
19+
vm.stack_top--;
20+
return *vm.stack_top;
21+
}
22+
23+
/*
24+
*The Run function is the core of the VM, the heart that pumps blood to the body
25+
*/
26+
27+
void init_vm() {
28+
reset_stack();
29+
}
30+
31+
32+
void free_vm() {
33+
34+
}
35+
36+
37+
static interpreted_result run (void) {
38+
#define READ_BYTE() (*vm.ip++)
39+
#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
40+
41+
for (;;) {
42+
uint8_t instruction;
43+
switch(instruction = READ_BYTE()) {
44+
case OP_CONSTANT: {
45+
Val constant = READ_CONSTANT();
46+
print_val(constant);
47+
printf("\n");
48+
push(constant);
49+
break;
50+
}
51+
52+
case OP_NEGATE: push(-pop()); break;
53+
54+
case OP_RETURN: {
55+
print_val(pop());
56+
printf("\n");
57+
return INTERPRET_OK;
58+
}
59+
}
60+
}
61+
#undef READ_BYTE
62+
#undef READ_CONSTANT
63+
}
64+
65+
66+
interpreted_result interpret(Chunk *chunk) {
67+
vm.chunk = chunk;
68+
vm.ip = vm.chunk->code;
69+
return run();
70+
}
71+

‎src/vm.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef clox_vm_h
2+
#define clox_vm_h
3+
4+
#include "chunk.h"
5+
#include "value.h"
6+
7+
#define STACK_MAX 256 //Are 8 bytes enough?
8+
9+
typedef struct {
10+
Chunk *chunk;
11+
uint8_t *ip;
12+
Val stack[STACK_MAX]; //My stack based proglang!
13+
Val *stack_top;
14+
} VM;
15+
16+
typedef enum {
17+
INTERPRET_OK,
18+
INTERPRET_COMPILE_ERROR,
19+
INTERPRET_RUNTIME_ERROR
20+
} interpreted_result;
21+
22+
void init_vm();
23+
void free_vm();
24+
interpreted_result interpret(Chunk *chunk);
25+
26+
void push(Val value);
27+
Val pop();
28+
29+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.