Skip to content

Commit

Permalink
Merge pull request #18 from ademyrodev/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
ademyro authored Aug 19, 2024
2 parents 25e23f3 + e2b3258 commit 963ea37
Show file tree
Hide file tree
Showing 12 changed files with 430 additions and 108 deletions.
11 changes: 11 additions & 0 deletions include/chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,23 @@ typedef enum {
OP_TRUE,
OP_FALSE,
OP_NIL,
OP_ZERO,
OP_ONE,
OP_MINUS_ONE,
OP_NEG,
OP_NOT,
OP_IS_NIL,
OP_IS_ZERO,
OP_IS_MINUS_ONE,
OP_ADD,
OP_SUB,
OP_MUL,
OP_DIV,
OP_SHL,
OP_SHR,
OP_BIT_AND,
OP_BIT_XOR,
OP_BIT_OR,
OP_EQ,
OP_NEQ,
OP_GREATER,
Expand Down
11 changes: 10 additions & 1 deletion include/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ typedef enum {
NODE_BINOP
} NodeType;

typedef enum {
UNOP_NEG = 1 << 0,
UNOP_NOT = 1 << 1,
UNOP_IS_ZERO = 1 << 2,
UNOP_IS_NEG_ONE = 1 << 3,
UNOP_IS_NIL = 1 << 4
} UnOpType;

typedef struct Node Node;

typedef struct {
Expand All @@ -39,6 +47,7 @@ typedef struct {

typedef struct {
Tok op;
UnOpType opType;
Node *operand;
} UnOp;

Expand Down Expand Up @@ -67,7 +76,7 @@ Node *newInt(TypeTable *table, long value, Loc loc);
Node *newFloat(TypeTable *table, double value, Loc loc);
Node *newBool(TypeTable *table, bool value, Loc loc);
Node *newNil(TypeTable *table, Loc loc);
Node *newUnOp(TypeTable *table, Tok op, Node *operand);
Node *newUnOp(TypeTable *table, Tok op, UnOpType type, Node *operand);
Node *newBinOp(TypeTable *table, Node *left, Tok op, Node *right);

void freeNode(Node *node);
Expand Down
2 changes: 2 additions & 0 deletions include/tok.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ typedef enum {
TOK_NEQUAL, TOK_ASSIGN, TOK_EQUAL, TOK_GREATER,
TOK_GREATER_EQUAL, TOK_LESS, TOK_LESS_EQUAL,

TOK_SHL, TOK_SHR, TOK_BIT_AND, TOK_BIT_XOR,

TOK_EXCLAM, TOK_QUESTION,

TOK_AND, TOK_CLASS, TOK_ELSE, TOK_END,
Expand Down
128 changes: 113 additions & 15 deletions src/compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ static void binOpTypeErr(Ctx *ctx, Node *left, Tok op, Node *right) {
actionName = "divide";
break;

case TOK_SHL:
case TOK_SHR:
actionName = "shift";
break;

case TOK_BIT_AND:
case TOK_PIPE:
case TOK_BIT_XOR:
actionName = "perform bitwise operation on";
break;

default:
actionName = "compare";
break;
Expand Down Expand Up @@ -247,8 +258,12 @@ static void endCompiler(Ctx *ctx) {
}

static Node *expr(Ctx *ctx);
static Node *bitOr(Ctx *ctx);
static Node *bitXor(Ctx *ctx);
static Node *bitAnd(Ctx *ctx);
static Node *equality(Ctx *ctx);
static Node *comparison(Ctx *ctx);
static Node *bitShift(Ctx *ctx);
static Node *term(Ctx *ctx);
static Node *factor(Ctx *ctx);
static Node *unary(Ctx *ctx);
Expand All @@ -257,7 +272,72 @@ static Node *intLiteral(Ctx *ctx);
static Node *floatLiteral(Ctx *ctx);

static Node *expr(Ctx *ctx) {
return equality(ctx);
return bitOr(ctx);
}

static Node *bitOr(Ctx *ctx) {
Node *left = bitXor(ctx);

while (check(ctx, TOK_PIPE)) {
Tok op = consume(ctx);

Node *right = bitXor(ctx);

// in the future, allow enum flag values. still gotta determine a syntax
// for them. a good candidate could be:
// enum Flags for &
// ...
// end
// but that’s really unintuitive. we’ll see--i’d like not to have to
// introduce a specific ‘bitwise’ keyword. and `enum X for &` has its
// charm, too.
if (!checkType(left, TYPE_INT) || !checkType(right, TYPE_INT)) {
binOpTypeErr(ctx, left, op, right);
}

Node *binOp = newBinOp(ctx->types, left, op, right);
left = binOp;
}

return left;
}

static Node *bitXor(Ctx *ctx) {
Node *left = bitAnd(ctx);

while (check(ctx, TOK_BIT_XOR)) {
Tok op = consume(ctx);

Node *right = bitAnd(ctx);

if (!checkType(left, TYPE_INT) || !checkType(right, TYPE_INT)) {
binOpTypeErr(ctx, left, op, right);
}

Node *binOp = newBinOp(ctx->types, left, op, right);
left = binOp;
}

return left;
}

static Node *bitAnd(Ctx *ctx) {
Node *left = equality(ctx);

while (check(ctx, TOK_BIT_AND)) {
Tok op = consume(ctx);

Node *right = equality(ctx);

if (!checkType(left, TYPE_INT) || !checkType(right, TYPE_INT)) {
binOpTypeErr(ctx, left, op, right);
}

Node *binOp = newBinOp(ctx->types, left, op, right);
left = binOp;
}

return left;
}

static Node *equality(Ctx *ctx) {
Expand All @@ -268,6 +348,10 @@ static Node *equality(Ctx *ctx) {

Node *right = comparison(ctx);

if (!typesMatch(left->valType, right->valType)) {
binOpTypeErr(ctx, left, op, right);
}

Node *binOp = newBinOp(ctx->types, left, op, right);
left = binOp;
}
Expand All @@ -276,15 +360,15 @@ static Node *equality(Ctx *ctx) {
}

static Node *comparison(Ctx *ctx) {
Node *left = term(ctx);
Node *left = bitShift(ctx);

while (
checkEither(ctx, TOK_LESS, TOK_GREATER) ||
checkEither(ctx, TOK_LESS_EQUAL, TOK_GREATER_EQUAL)
) {
Tok op = consume(ctx);

Node *right = term(ctx);
Node *right = bitShift(ctx);

if (!isNum(left) || !isNum(right)) {
binOpTypeErr(ctx, left, op, right);
Expand All @@ -297,6 +381,25 @@ static Node *comparison(Ctx *ctx) {
return left;
}

static Node *bitShift(Ctx *ctx) {
Node *left = term(ctx);

while (checkEither(ctx, TOK_SHL, TOK_SHR)) {
Tok op = consume(ctx);

Node *right = comparison(ctx);

if (!checkType(left, TYPE_INT) || !checkType(right, TYPE_INT)) {
binOpTypeErr(ctx, left, op, right);
}

Node *binOp = newBinOp(ctx->types, left, op, right);
left = binOp;
}

return left;
}

static Node *term(Ctx *ctx) {
Node *left = factor(ctx);

Expand Down Expand Up @@ -353,17 +456,17 @@ static Node *unary(Ctx *ctx) {
unaryNegationErr(ctx, op, tok, operand);
}

return newUnOp(ctx->types, op, operand);
return newUnOp(ctx->types, op, UNOP_NEG, operand);
}

case TOK_NOT: {
if (!checkType(operand, TYPE_BOOL) && !checkType(operand, TYPE_NIL)) {
if (!checkType(operand, TYPE_BOOL)) {
Tok tok = ctx->parser.prev;

unaryNegationErr(ctx, op, tok, operand);
}

return newUnOp(ctx->types, op, operand);
return newUnOp(ctx->types, op, UNOP_NOT, operand);
}

default:
Expand Down Expand Up @@ -497,23 +600,18 @@ bool compile(const char *fname, const char *src, Chunk *ch) {

const bool hadErrs = newMod.errCount != 0;

#ifdef DEBUG_COMPILE
if (!hadErrs) {
#ifdef DEBUG_COMPILE
fprintf(stderr, "unoptimized:\n");
prettyPrint(ast);
}
#endif

optNode(ast);

optNode(ast);
#ifdef DEBUG_COMPILE
if (!hadErrs) {
fprintf(stderr, "optimized:\n");
prettyPrint(ast);
}
#endif

emitNode(&ctx, ast);
emitNode(&ctx, ast);
}

freeNode(ast);

Expand Down
Loading

0 comments on commit 963ea37

Please sign in to comment.