Skip to content

Commit 93df4f7

Browse files
committed
feat: introduce bytecode generation for AST with new opcodes and compiler infrastructure.
1 parent fb6ca5f commit 93df4f7

5 files changed

Lines changed: 189 additions & 6 deletions

File tree

benchmarks/macro/json_bench.prox

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class JsonParser {
3434
func skipWhitespace() {
3535
while (this.pos < this.len) {
3636
let c = this.peek();
37-
if (c == " " or c == "\n" or c == "\t") {
37+
if (c == " " || c == "\n" || c == "\t") {
3838
this.consume();
3939
} else {
4040
return;

include/bytecode.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ typedef enum {
6565
OP_INTERFACE,
6666
OP_IMPLEMENT,
6767
OP_MAKE_FOREIGN,
68+
OP_MODULO,
69+
OP_BIT_AND,
70+
OP_BIT_OR,
71+
OP_BIT_XOR,
72+
OP_LEFT_SHIFT,
73+
OP_RIGHT_SHIFT,
6874
OP_HALT = 0xFF
6975
} OpCode;
7076

src/compiler/bytecode_gen.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ static void genExpr(BytecodeGen* gen, Expr* expr) {
184184
writeChunk(gen->chunk, OP_LESS, expr->line);
185185
writeChunk(gen->chunk, OP_NOT, expr->line);
186186
}
187+
else if (strcmp(expr->as.binary.operator, "%") == 0) writeChunk(gen->chunk, OP_MODULO, expr->line);
188+
else if (strcmp(expr->as.binary.operator, "&") == 0) writeChunk(gen->chunk, OP_BIT_AND, expr->line);
189+
else if (strcmp(expr->as.binary.operator, "|") == 0) writeChunk(gen->chunk, OP_BIT_OR, expr->line);
190+
else if (strcmp(expr->as.binary.operator, "^") == 0) writeChunk(gen->chunk, OP_BIT_XOR, expr->line);
191+
else if (strcmp(expr->as.binary.operator, "<<") == 0) writeChunk(gen->chunk, OP_LEFT_SHIFT, expr->line);
192+
else if (strcmp(expr->as.binary.operator, ">>") == 0) writeChunk(gen->chunk, OP_RIGHT_SHIFT, expr->line);
187193
break;
188194
}
189195
case EXPR_GROUPING: {

src/compiler/parser/parser.c

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ static Expr *assignment(Parser *p);
3737
static Expr *ternary(Parser *p);
3838
static Expr *orExpr(Parser *p);
3939
static Expr *andExpr(Parser *p);
40+
static Expr *bitwiseOr(Parser *p);
41+
static Expr *bitwiseXor(Parser *p);
42+
static Expr *bitwiseAnd(Parser *p);
4043
static Expr *equality(Parser *p);
4144
static Expr *comparison(Parser *p);
45+
static Expr *bitwiseShift(Parser *p);
4246
static Expr *term(Parser *p);
4347
static Expr *factor(Parser *p);
4448
static Expr *unary(Parser *p);
@@ -681,19 +685,55 @@ static Expr *orExpr(Parser *p) {
681685
}
682686

683687
static Expr *andExpr(Parser *p) {
684-
Expr *expr = equality(p);
688+
Expr *expr = bitwiseOr(p);
685689

686690
while (match(p, 1, TOKEN_AMPERSAND_AMPERSAND)) {
687691
Token op = previous(p);
688692
char *opStr = tokenToString(op);
689-
Expr *right = equality(p);
693+
Expr *right = bitwiseOr(p);
690694
expr = createLogicalExpr(expr, opStr, right, op.line, 0);
691695
free(opStr);
692696
}
693697

694698
return expr;
695699
}
696700

701+
static Expr *bitwiseOr(Parser *p) {
702+
Expr *expr = bitwiseXor(p);
703+
while (match(p, 1, TOKEN_PIPE)) {
704+
Token op = previous(p);
705+
char *opStr = tokenToString(op);
706+
Expr *right = bitwiseXor(p);
707+
expr = createBinaryExpr(expr, opStr, right, op.line, 0);
708+
free(opStr);
709+
}
710+
return expr;
711+
}
712+
713+
static Expr *bitwiseXor(Parser *p) {
714+
Expr *expr = bitwiseAnd(p);
715+
while (match(p, 1, TOKEN_CARET)) {
716+
Token op = previous(p);
717+
char *opStr = tokenToString(op);
718+
Expr *right = bitwiseAnd(p);
719+
expr = createBinaryExpr(expr, opStr, right, op.line, 0);
720+
free(opStr);
721+
}
722+
return expr;
723+
}
724+
725+
static Expr *bitwiseAnd(Parser *p) {
726+
Expr *expr = equality(p);
727+
while (match(p, 1, TOKEN_AMPERSAND)) {
728+
Token op = previous(p);
729+
char *opStr = tokenToString(op);
730+
Expr *right = equality(p);
731+
expr = createBinaryExpr(expr, opStr, right, op.line, 0);
732+
free(opStr);
733+
}
734+
return expr;
735+
}
736+
697737
static Expr *equality(Parser *p) {
698738
Expr *expr = comparison(p);
699739

@@ -709,20 +749,32 @@ static Expr *equality(Parser *p) {
709749
}
710750

711751
static Expr *comparison(Parser *p) {
712-
Expr *expr = term(p);
752+
Expr *expr = bitwiseShift(p);
713753

714754
while (match(p, 4, TOKEN_GREATER, TOKEN_GREATER_EQUAL, TOKEN_LESS,
715755
TOKEN_LESS_EQUAL)) {
716756
Token op = previous(p);
717757
char *opStr = tokenToString(op);
718-
Expr *right = term(p);
758+
Expr *right = bitwiseShift(p);
719759
expr = createBinaryExpr(expr, opStr, right, op.line, 0);
720760
free(opStr);
721761
}
722762

723763
return expr;
724764
}
725765

766+
static Expr *bitwiseShift(Parser *p) {
767+
Expr *expr = term(p);
768+
while (match(p, 2, TOKEN_LESS_LESS, TOKEN_GREATER_GREATER)) {
769+
Token op = previous(p);
770+
char *opStr = tokenToString(op);
771+
Expr *right = term(p);
772+
expr = createBinaryExpr(expr, opStr, right, op.line, 0);
773+
free(opStr);
774+
}
775+
return expr;
776+
}
777+
726778
static Expr *term(Parser *p) {
727779
Expr *expr = factor(p);
728780

src/runtime/vm.c

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <time.h>
1010
#include <stdarg.h>
1111
#include <stdlib.h> // Required for exit()
12+
#include <math.h>
13+
1214

1315

1416
#include "../include/common.h"
@@ -187,7 +189,13 @@ static InterpretResult run(VM* vm) {
187189
[OP_TRY] = &&DO_OP_TRY,
188190
[OP_CATCH] = &&DO_OP_CATCH,
189191
[OP_END_TRY] = &&DO_OP_END_TRY,
190-
[OP_MAKE_FOREIGN] = &&DO_OP_MAKE_FOREIGN
192+
[OP_MAKE_FOREIGN] = &&DO_OP_MAKE_FOREIGN,
193+
[OP_MODULO] = &&DO_OP_MODULO,
194+
[OP_BIT_AND] = &&DO_OP_BIT_AND,
195+
[OP_BIT_OR] = &&DO_OP_BIT_OR,
196+
[OP_BIT_XOR] = &&DO_OP_BIT_XOR,
197+
[OP_LEFT_SHIFT] = &&DO_OP_LEFT_SHIFT,
198+
[OP_RIGHT_SHIFT] = &&DO_OP_RIGHT_SHIFT
191199
};
192200
#pragma GCC diagnostic pop
193201

@@ -491,6 +499,7 @@ static InterpretResult run(VM* vm) {
491499
DO_OP_PRINT: {
492500
printValue(pop(vm));
493501
printf("\n");
502+
fflush(stdout);
494503
DISPATCH();
495504
}
496505
DO_OP_JUMP: {
@@ -662,6 +671,80 @@ static InterpretResult run(VM* vm) {
662671
DISPATCH();
663672
}
664673

674+
DO_OP_MODULO: {
675+
double b = AS_NUMBER(pop(vm));
676+
double a = AS_NUMBER(pop(vm));
677+
push(vm, NUMBER_VAL(fmod(a, b)));
678+
DISPATCH();
679+
}
680+
DO_OP_BIT_AND: {
681+
int b = (int)AS_NUMBER(pop(vm));
682+
int a = (int)AS_NUMBER(pop(vm));
683+
push(vm, NUMBER_VAL((double)(a & b)));
684+
DISPATCH();
685+
}
686+
DO_OP_BIT_OR: {
687+
int b = (int)AS_NUMBER(pop(vm));
688+
int a = (int)AS_NUMBER(pop(vm));
689+
push(vm, NUMBER_VAL((double)(a | b)));
690+
DISPATCH();
691+
}
692+
DO_OP_BIT_XOR: {
693+
int b = (int)AS_NUMBER(pop(vm));
694+
int a = (int)AS_NUMBER(pop(vm));
695+
push(vm, NUMBER_VAL((double)(a ^ b)));
696+
DISPATCH();
697+
}
698+
DO_OP_LEFT_SHIFT: {
699+
int b = (int)AS_NUMBER(pop(vm));
700+
int a = (int)AS_NUMBER(pop(vm));
701+
push(vm, NUMBER_VAL((double)(a << b)));
702+
DISPATCH();
703+
}
704+
DO_OP_RIGHT_SHIFT: {
705+
int b = (int)AS_NUMBER(pop(vm));
706+
int a = (int)AS_NUMBER(pop(vm));
707+
push(vm, NUMBER_VAL((double)(a >> b)));
708+
DISPATCH();
709+
}
710+
711+
DO_OP_MODULO: {
712+
double b = AS_NUMBER(pop(vm));
713+
double a = AS_NUMBER(pop(vm));
714+
push(vm, NUMBER_VAL(fmod(a, b)));
715+
DISPATCH();
716+
}
717+
DO_OP_BIT_AND: {
718+
int b = (int)AS_NUMBER(pop(vm));
719+
int a = (int)AS_NUMBER(pop(vm));
720+
push(vm, NUMBER_VAL((double)(a & b)));
721+
DISPATCH();
722+
}
723+
DO_OP_BIT_OR: {
724+
int b = (int)AS_NUMBER(pop(vm));
725+
int a = (int)AS_NUMBER(pop(vm));
726+
push(vm, NUMBER_VAL((double)(a | b)));
727+
DISPATCH();
728+
}
729+
DO_OP_BIT_XOR: {
730+
int b = (int)AS_NUMBER(pop(vm));
731+
int a = (int)AS_NUMBER(pop(vm));
732+
push(vm, NUMBER_VAL((double)(a ^ b)));
733+
DISPATCH();
734+
}
735+
DO_OP_LEFT_SHIFT: {
736+
int b = (int)AS_NUMBER(pop(vm));
737+
int a = (int)AS_NUMBER(pop(vm));
738+
push(vm, NUMBER_VAL((double)(a << b)));
739+
DISPATCH();
740+
}
741+
DO_OP_RIGHT_SHIFT: {
742+
int b = (int)AS_NUMBER(pop(vm));
743+
int a = (int)AS_NUMBER(pop(vm));
744+
push(vm, NUMBER_VAL((double)(a >> b)));
745+
DISPATCH();
746+
}
747+
665748
DO_OP_UNKNOWN: {
666749
runtimeError(vm, "Unknown opcode %d.", frame->ip[-1]);
667750
return INTERPRET_RUNTIME_ERROR;
@@ -1109,6 +1192,42 @@ static InterpretResult run(VM* vm) {
11091192
push(vm, OBJ_VAL(foreign));
11101193
break;
11111194
}
1195+
case OP_MODULO: {
1196+
double b = AS_NUMBER(pop(vm));
1197+
double a = AS_NUMBER(pop(vm));
1198+
push(vm, NUMBER_VAL(fmod(a, b)));
1199+
break;
1200+
}
1201+
case OP_BIT_AND: {
1202+
int b = (int)AS_NUMBER(pop(vm));
1203+
int a = (int)AS_NUMBER(pop(vm));
1204+
push(vm, NUMBER_VAL((double)(a & b)));
1205+
break;
1206+
}
1207+
case OP_BIT_OR: {
1208+
int b = (int)AS_NUMBER(pop(vm));
1209+
int a = (int)AS_NUMBER(pop(vm));
1210+
push(vm, NUMBER_VAL((double)(a | b)));
1211+
break;
1212+
}
1213+
case OP_BIT_XOR: {
1214+
int b = (int)AS_NUMBER(pop(vm));
1215+
int a = (int)AS_NUMBER(pop(vm));
1216+
push(vm, NUMBER_VAL((double)(a ^ b)));
1217+
break;
1218+
}
1219+
case OP_LEFT_SHIFT: {
1220+
int b = (int)AS_NUMBER(pop(vm));
1221+
int a = (int)AS_NUMBER(pop(vm));
1222+
push(vm, NUMBER_VAL((double)(a << b)));
1223+
break;
1224+
}
1225+
case OP_RIGHT_SHIFT: {
1226+
int b = (int)AS_NUMBER(pop(vm));
1227+
int a = (int)AS_NUMBER(pop(vm));
1228+
push(vm, NUMBER_VAL((double)(a >> b)));
1229+
break;
1230+
}
11121231
case OP_RETURN: {
11131232
vm->frameCount--;
11141233
if (vm->frameCount == 0) {

0 commit comments

Comments
 (0)