Cleaned up the Makefile, added the framework for checking for runtime errrors in the Interpreter and fixed a bug where I didn't close out the 'va_list' in the Match function in the Parser.
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS=-Wall -DDEBUG
|
CFLAGS=-Wall -DDEBUG
|
||||||
SRC=src
|
SRCDIR=src
|
||||||
OBJ=obj
|
OBJDIR=obj
|
||||||
SRCS=$(wildcard $(SRC)/*.c)
|
SRCS=$(wildcard $(SRCDIR)/*.c)
|
||||||
# Substitute all .c with .o from SRCS
|
# Substitute all .c with .o from SRCS
|
||||||
OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
|
OBJS=$(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SRCS))
|
||||||
|
|
||||||
BINDIR=bin
|
BINDIR=bin
|
||||||
BIN=$(BINDIR)/clox
|
BIN=$(BINDIR)/clox
|
||||||
@@ -18,20 +18,20 @@ release: $(BIN)
|
|||||||
$(BIN): $(OBJS) $(BINDIR)
|
$(BIN): $(OBJS) $(BINDIR)
|
||||||
$(CC) $(CFLAGS) $(OBJS) -o $@
|
$(CC) $(CFLAGS) $(OBJS) -o $@
|
||||||
|
|
||||||
$(OBJ)/%.o: $(SRC)/%.c $(OBJ)
|
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(OBJDIR)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BINDIR):
|
$(BINDIR):
|
||||||
mkdir $@
|
mkdir $@
|
||||||
|
|
||||||
$(OBJ):
|
$(OBJDIR):
|
||||||
mkdir $@
|
mkdir $@
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r $(BINDIR)/* $(OBJ)/*
|
rm -r $(BINDIR)/* $(OBJDIR)/*
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(BIN) test.lox
|
$(BIN) test.lox
|
||||||
+18
-3
@@ -14,6 +14,7 @@ Object* VisitBinaryExpression(Expr*);
|
|||||||
int IsTruthy(Object*);
|
int IsTruthy(Object*);
|
||||||
int IsEqual(Object*, Object*);
|
int IsEqual(Object*, Object*);
|
||||||
int ConcatStringObject(Object*, const Object*);
|
int ConcatStringObject(Object*, const Object*);
|
||||||
|
void CheckNumberOperand(TokenType, int, ...);
|
||||||
void PrintObject(Object*);
|
void PrintObject(Object*);
|
||||||
|
|
||||||
void PrintObject(Object* o) {
|
void PrintObject(Object* o) {
|
||||||
@@ -53,7 +54,6 @@ void Interpret(Expr* exp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object* VisitLiteralExpression(Expr* expr) {
|
Object* VisitLiteralExpression(Expr* expr) {
|
||||||
printf("Literal: %p\n", (double *) expr->expression.Literal->literal);
|
|
||||||
return CreateObject(expr->expression.Literal->literal, expr->expression.Literal->type);
|
return CreateObject(expr->expression.Literal->literal, expr->expression.Literal->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,8 +66,6 @@ Object* VisitGroupingExpression(Expr* expression) {
|
|||||||
Object* VisitBinaryExpression(Expr* expression) {
|
Object* VisitBinaryExpression(Expr* expression) {
|
||||||
Object* left = Evaluate(expression->expression.Binary.left);
|
Object* left = Evaluate(expression->expression.Binary.left);
|
||||||
Object* right = Evaluate(expression->expression.Binary.right);
|
Object* right = Evaluate(expression->expression.Binary.right);
|
||||||
PrintObject(left);
|
|
||||||
PrintObject(right);
|
|
||||||
double computed_value;
|
double computed_value;
|
||||||
|
|
||||||
switch(expression->expression.Binary.op->type) {
|
switch(expression->expression.Binary.op->type) {
|
||||||
@@ -108,6 +106,7 @@ Object* VisitBinaryExpression(Expr* expression) {
|
|||||||
return CreateObject(&computed_value, TRUE);
|
return CreateObject(&computed_value, TRUE);
|
||||||
//return IsEqual(left, right);
|
//return IsEqual(left, right);
|
||||||
case Minus:
|
case Minus:
|
||||||
|
|
||||||
left->value.number -= right->value.number;
|
left->value.number -= right->value.number;
|
||||||
FreeObject(right);
|
FreeObject(right);
|
||||||
return left;
|
return left;
|
||||||
@@ -159,6 +158,7 @@ Object* VisitUnaryExpression(Expr* expression) {
|
|||||||
|
|
||||||
switch (expression->expression.Unary.op->type) {
|
switch (expression->expression.Unary.op->type) {
|
||||||
case Minus:
|
case Minus:
|
||||||
|
CheckNumberOperand(expression->expression.Unary.op->type, right);//This needs to "throw" if the function fails.
|
||||||
computed_value = -right->value.number;
|
computed_value = -right->value.number;
|
||||||
FreeObject(right);
|
FreeObject(right);
|
||||||
c = CreateObject(&computed_value, Number);
|
c = CreateObject(&computed_value, Number);
|
||||||
@@ -282,4 +282,19 @@ int IsEqual(Object* a, Object* b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckNumberOperand(TokenType operator, int operandCount, ...) {
|
||||||
|
va_list list;
|
||||||
|
va_start(list, operandCount);
|
||||||
|
|
||||||
|
for(int i = 0; i < operandCount; i++) {
|
||||||
|
Object* operand = va_arg(list, Object*);
|
||||||
|
if (operand->instance != INS_DOUBLE) {
|
||||||
|
va_end(list);
|
||||||
|
return; //TODO: "throw" runtime error "Operand must be a number."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(list);
|
||||||
}
|
}
|
||||||
@@ -157,11 +157,14 @@ int Match(int count, ...) {
|
|||||||
|
|
||||||
for(int i = 0; i < count; i++) {
|
for(int i = 0; i < count; i++) {
|
||||||
if(Check(va_arg(list, TokenType))) {
|
if(Check(va_arg(list, TokenType))) {
|
||||||
|
va_end(list);
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user