Skip to content

Commit

Permalink
Add other values, if statements and equality checking
Browse files Browse the repository at this point in the history
  • Loading branch information
paked committed Oct 13, 2018
1 parent 48cb916 commit 26730b0
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 37 deletions.
5 changes: 4 additions & 1 deletion example.ls
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
a := 11;
y := 33;
x := y * 2;
x := a * 3;

z := true;

x;

if x == y;

/*
if x == 10 {
x;
Expand Down
101 changes: 77 additions & 24 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ enum ASTNodeType : uint32 {
AST_NODE_MULTIPLY,
AST_NODE_DIVIDE,

AST_NODE_TEST_EQUAL,

AST_NODE_IDENTIFIER,
AST_NODE_VALUE,
AST_NODE_NUMBER
};

Expand All @@ -107,6 +110,10 @@ struct ASTNode_Identifier {
Token token;
};

struct ASTNode_Value {
Value val;
};

struct ASTNode_Number {
int number;
};
Expand All @@ -122,11 +129,17 @@ struct ASTNode {
ASTNode_Binary assignmentDeclaration;
ASTNode_Binary assignment;

ASTNode_Binary binary;

ASTNode_Binary add;
ASTNode_Binary subtract;
ASTNode_Binary multiply;
ASTNode_Binary divide;

ASTNode_Binary equality;

ASTNode_Value value;

ASTNode_Identifier identifier;
ASTNode_Number number;
};
Expand Down Expand Up @@ -157,28 +170,31 @@ ASTNode ast_makeIdentifier(Token t) {
node.identifier.token = t;

return node;
};
}

ASTNode ast_makeValue(Value v, Token t) {
ASTNode node = {};
node.type = AST_NODE_VALUE;

node.line = t.line;

node.value.val = v;

return node;
}

ASTNode ast_makeOperator(ASTNodeType op, Token t) {
ASTNode node = {};
node.line = t.line;

switch (op) {
case AST_NODE_ADD:
{
node.type = AST_NODE_ADD;
} break;
case AST_NODE_SUBTRACT:
{
node.type = AST_NODE_SUBTRACT;
} break;
case AST_NODE_MULTIPLY:
{
node.type = AST_NODE_MULTIPLY;
} break;
case AST_NODE_DIVIDE:
case AST_NODE_TEST_EQUAL:
{
node.type = AST_NODE_DIVIDE;
node.type = op;
} break;
default:
{
Expand Down Expand Up @@ -251,6 +267,29 @@ ASTNode ast_makeAssignment(ASTNode left, ASTNode right, Token t) {
return node;
}

bool ast_checkType(ASTNode n, ValueType vt) {
switch (n.type) {
case AST_NODE_ADD:
case AST_NODE_SUBTRACT:
case AST_NODE_MULTIPLY:
case AST_NODE_DIVIDE:
{
return ast_checkType(*n.binary.left, vt) && ast_checkType(*n.binary.right, vt);
} break;
case AST_NODE_NUMBER:
{
return (vt == VALUE_NUMBER) ? true : false;
} break;

case AST_NODE_VALUE:
{
return (vt == n.value.val.type);
} break;
default:
return false;
}
}

#define IS_USED(op) ((op).add.left != 0 && (op).add.right != 0)
bool ast_nodeHasValue(ASTNode n) {
if (!(n.type == AST_NODE_NUMBER || n.type == AST_NODE_IDENTIFIER)) {
Expand Down Expand Up @@ -295,27 +334,20 @@ bool ast_writeBytecode(ASTNode* node, Hunk* hunk, Scope* scope) {
assert(left->type == AST_NODE_IDENTIFIER);

ASTNode* right = node->assignmentDeclaration.right;
assert(ast_nodeHasValue(*right));
// assert(ast_nodeHasValue(*right));

// write instructions to push right side onto stack
if (!ast_writeBytecode(right, hunk, scope)) {
return false;
}

if (!scope_exists(scope, left->identifier.token.start, left->identifier.token.len)) {
Variable var = {};
if (!scope_get(scope, left->identifier.token.start, left->identifier.token.len, &var)) {
printf("ERROR: variable doesn't exist!\n");

return false;
}

Variable var = {};
var.start = left->identifier.token.start;
var.len = left->identifier.token.len;

var.index = hunk_addLocal(hunk, value_make(VALUE_NUMBER));

scope_set(scope, var);

hunk_write(hunk, OP_SET_LOCAL, node->line);
hunk_write(hunk, var.index, node->line);
} break;
Expand All @@ -325,7 +357,7 @@ bool ast_writeBytecode(ASTNode* node, Hunk* hunk, Scope* scope) {
assert(left->type == AST_NODE_IDENTIFIER);

ASTNode* right = node->assignmentDeclaration.right;
assert(ast_nodeHasValue(*right));
// assert(ast_nodeHasValue(*right));

// write instructions to push right side onto stack
if (!ast_writeBytecode(right, hunk, scope)) {
Expand All @@ -342,18 +374,33 @@ bool ast_writeBytecode(ASTNode* node, Hunk* hunk, Scope* scope) {
var.start = left->identifier.token.start;
var.len = left->identifier.token.len;

// TODO(harrison): replace local, don't just make a new one
var.index = hunk_addLocal(hunk, value_make(VALUE_NUMBER));

scope_set(scope, var);

hunk_write(hunk, OP_SET_LOCAL, node->line);
hunk_write(hunk, var.index, node->line);
} break;
case AST_NODE_TEST_EQUAL:
{
ASTNode* left = node->equality.left;
ASTNode* right = node->equality.right;

// write instructions to push left side onto stack
if(!ast_writeBytecode(left, hunk, scope)) {
return false;
}

// write instructions to push right side onto stack
if(!ast_writeBytecode(right, hunk, scope)) {
return false;
}

hunk_write(hunk, OP_TEST_EQ, node->line);
} break;
case AST_NODE_ADD:
{
ASTNode* left = node->add.left;

ASTNode* right = node->add.right;

// write instructions to push left side onto stack
Expand Down Expand Up @@ -428,6 +475,12 @@ bool ast_writeBytecode(ASTNode* node, Hunk* hunk, Scope* scope) {
hunk_write(hunk, OP_CONSTANT, node->line);
hunk_write(hunk, constant, node->line);
} break;
case AST_NODE_VALUE:
{
int constant = hunk_addConstant(hunk, node->value.val);
hunk_write(hunk, OP_CONSTANT, node->line);
hunk_write(hunk, constant, node->line);
} break;
case AST_NODE_IDENTIFIER:
{
Variable var = {};
Expand Down
62 changes: 58 additions & 4 deletions src/bytecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ enum OPCode : Instruction {
OP_ADD,
OP_SUBTRACT,
OP_MULTIPLY,
OP_DIVIDE
OP_DIVIDE,

// OP tgt, tlt, teq
OP_TEST_EQ, // ==
OP_TEST_GT, // >
OP_TEST_LT, // <
OP_TEST_OR, // ||
OP_TEST_AND // &&
};

enum ValueType {
Expand All @@ -26,7 +33,6 @@ enum ValueType {
// VALUE_OBJ
};


#define VALUE_IS_NUMBER(v) ((v).type == VALUE_NUMBER)
#define VALUE_IS_BOOL(v) ((v).type == VALUE_BOOL)

Expand Down Expand Up @@ -68,6 +74,15 @@ Value value_make(float t) {
return v;
}

Value value_make(bool t) {
Value v = {};
v.type = VALUE_BOOL;

v.as.boolean = t;

return v;
}

void value_print(Value v) {
switch (v.type) {
case VALUE_NUMBER:
Expand All @@ -77,10 +92,12 @@ void value_print(Value v) {
case VALUE_BOOL:
{
printf(v.as.boolean ? "true" : "false");

break;
}
default:
{
printf("unknown");
printf("unknown: %d", v.type);
}
};
}
Expand All @@ -91,6 +108,31 @@ void value_println(Value v) {
printf("\n");
}

bool value_equals(Value left, Value right) {
if (left.type != right.type) {
// TODO(harrison): this should not be possible. We need a type system.

assert(!"Can't compare variables of different types");
}

switch (left.type) {
case VALUE_BOOL:
{
return left.as.boolean == right.as.boolean;
} break;
case VALUE_NUMBER:
{
return us_equals(left.as.number, right.as.number);
} break;
default:
{
assert(!"Unknown type");
}
}

return false;
}

// Constants keeps track of all the available constants in a program. Zero is initialisation.
// TODO(harrison): force constants count to fit within the maximum addressable space by opcodes (256)
#define CONSTANTS_CAPACITY_GROW(c) ( ((c) < 8) ? 8 : (c)*2 )
Expand Down Expand Up @@ -192,6 +234,8 @@ int hunk_disassembleInstruction(Hunk* hunk, int offset) {
SIMPLE_INSTRUCTION(OP_MULTIPLY);
SIMPLE_INSTRUCTION(OP_DIVIDE);

SIMPLE_INSTRUCTION(OP_TEST_EQ);

case OP_CONSTANT:
{
int idx = hunk->code[offset + 1];
Expand All @@ -216,7 +260,6 @@ int hunk_disassembleInstruction(Hunk* hunk, int offset) {

return offset + 2;
} break;

default:
{
printf("Unknown opcode: %d\n", in);
Expand Down Expand Up @@ -325,7 +368,18 @@ ProgramResult vm_run(VM* vm) {

vm_stack_push(vm, v);
} break;
case OP_TEST_EQ:
{
Value b = vm_stack_pop(vm);
Value a = vm_stack_pop(vm);

Value c = {};
c.type = VALUE_BOOL;

c.as.boolean = value_equals(a, b);

vm_stack_push(vm, c);
} break;
#define BINARY_OP(op) \
Value b = vm_stack_pop(vm); \
Value a = vm_stack_pop(vm); \
Expand Down
24 changes: 20 additions & 4 deletions src/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum TokenType : uint32 {

TOKEN_TRUE,
TOKEN_FALSE,
TOKEN_IF,

TOKEN_ASSIGNMENT,
TOKEN_ASSIGNMENT_DECLARATION,
Expand All @@ -21,6 +22,8 @@ enum TokenType : uint32 {
TOKEN_MULTIPLY,
TOKEN_DIVIDE,

TOKEN_EQUALS,

TOKEN_BRACKET_OPEN,
TOKEN_BRACKET_CLOSE,
};
Expand Down Expand Up @@ -117,6 +120,7 @@ Token scanner_readIdentifier(Scanner* scn) {

// true
// false
// if
if (t.len == 4) {
if (strncmp(t.start, "true", 4) == 0) {
t.type = TOKEN_TRUE;
Expand All @@ -125,6 +129,10 @@ Token scanner_readIdentifier(Scanner* scn) {
if (strncmp(t.start, "false", 5) == 0) {
t.type = TOKEN_FALSE;
}
} else if (t.len == 2) {
if (strncmp(t.start, "if", 2) == 0) {
t.type = TOKEN_IF;
}
}

return t;
Expand Down Expand Up @@ -200,11 +208,19 @@ Token scanner_getToken(Scanner* scn) {
switch (*scn->head) {
case '=':
{
t.type = TOKEN_ASSIGNMENT;
t.start = scn->head;
t.len = 1;
if (scanner_peek(scn) == '=') {
t.type = TOKEN_EQUALS;
t.start = scn->head;
t.len = 2;

scn->head += t.len;
scn->head += t.len;
} else {
t.type = TOKEN_ASSIGNMENT;
t.start = scn->head;
t.len = 1;

scn->head += t.len;
}
} break;
case ':':
{
Expand Down
Loading

0 comments on commit 26730b0

Please sign in to comment.