-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvm.h
More file actions
123 lines (97 loc) · 3.05 KB
/
Copy pathvm.h
File metadata and controls
123 lines (97 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef BRD_VM_H
#define BRD_VM_H
/* stack is limited to 256 values */
#define STACK_SIZE 256
/* number of frames is limited to 64 */
/* so you can only do recursion 64 calls deep */
#define FRAME_SIZE 64
#define INITIAL_THRESHOLD 100
/* VM bytecode */
/* Stack based virtual machine */
typedef char brd_bytecode_t;
enum brd_bytecode {
BRD_VM_NUM, /* has arg: long double */
BRD_VM_STR, /* has arg: string */
BRD_VM_GET_VAR, /* has arg: string */
BRD_VM_TRUE,
BRD_VM_FALSE,
BRD_VM_UNIT,
/* arithmetic */
BRD_VM_PLUS,
BRD_VM_MINUS,
BRD_VM_MUL,
BRD_VM_DIV,
BRD_VM_IDIV,
BRD_VM_MOD,
BRD_VM_POW,
BRD_VM_NEGATE,
/* comp */
BRD_VM_LT,
BRD_VM_LEQ,
BRD_VM_GT,
BRD_VM_GEQ,
BRD_VM_EQ,
BRD_VM_CONCAT,
/* boolean */
BRD_VM_NOT,
BRD_VM_TEST, /* if peek() then pop(); pc++ */
BRD_VM_TESTN, /* if not peek() then pop(); pc++*/
BRD_VM_TESTP, /* if pop() then pc++ */
/* these three instructions are ALWAYS to be followed by a JMP instruction */
BRD_VM_SET_VAR, /* has arg: string */
BRD_VM_BUILTIN, /* has arg: size_t */
BRD_VM_CALL, /* has arg: size_t */
BRD_VM_CLOSURE, /* has args size_t, strings, bytecode, followed by a JMP */
BRD_VM_JMP, /* has arg: size_t */
BRD_VM_JMPB, /* has arg: size_t */
/* this will do more when we have functions and classes */
BRD_VM_RETURN,
BRD_VM_POP,
BRD_VM_GET_IDX,
BRD_VM_SET_IDX,
BRD_VM_GET_FIELD,
BRD_VM_SET_FIELD,
BRD_VM_SUBCLASS,
BRD_VM_SET_CLASS,
BRD_VM_ACC_OBJ,
BRD_VM_LIST, /* initializes an empty list */
/* this is poorly named, it's a list operation */
BRD_VM_PUSH, /* x = pop(), peek().push(x) */
BRD_VM_PUSH_DICT,
};
struct brd_stack {
struct brd_value values[STACK_SIZE];
struct brd_value *sp;
char _p[8];
};
struct brd_frame {
size_t pc;
struct brd_value_map globals, locals;
};
struct brd_string_constant_list {
struct brd_string_constant_list *next;
struct brd_value_string string;
};
struct brd_vm {
struct brd_stack stack;
struct brd_heap_entry *heap;
struct brd_string_constant_list *strings;
brd_bytecode_t *bytecode;
size_t bc_length, bc_capacity;
size_t fp;
struct brd_frame frame[FRAME_SIZE];
unsigned int threshold, heap_size;
char _p[8];
};
extern struct brd_vm vm;
void brd_stack_push(struct brd_stack *stack, struct brd_value *value);
struct brd_value *brd_stack_pop(struct brd_stack *stack);
struct brd_value *brd_stack_peek(struct brd_stack *stack);
void brd_node_compile(struct brd_node *node);
void brd_vm_destroy(void);
void brd_vm_init(void);
void brd_vm_allocate(struct brd_heap_entry *entry);
struct brd_string_constant_list *brd_vm_add_string_constant(char *string);
void brd_vm_run(void);
void brd_vm_gc(void);
#endif