Chapter 19.4
This commit is contained in:
parent
60e752c0c5
commit
d5f352e577
3 changed files with 42 additions and 2 deletions
|
@ -25,7 +25,9 @@ struct ObjString {
|
||||||
char *chars;
|
char *chars;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ObjString *takeString(char *chars, int length);
|
||||||
ObjString *copyString(const char *chars, int length);
|
ObjString *copyString(const char *chars, int length);
|
||||||
|
void printObject(Value value);
|
||||||
|
|
||||||
static inline bool isObjType(Value value, ObjType type) {
|
static inline bool isObjType(Value value, ObjType type) {
|
||||||
return IS_OBJ(value) && AS_OBJ(value)->type == type;
|
return IS_OBJ(value) && AS_OBJ(value)->type == type;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "object.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
|
|
||||||
void initValueArray(ValueArray *array) {
|
void initValueArray(ValueArray *array) {
|
||||||
|
@ -37,6 +39,9 @@ void printValue(Value value) {
|
||||||
case VAL_NUMBER:
|
case VAL_NUMBER:
|
||||||
printf("%g", AS_NUMBER(value));
|
printf("%g", AS_NUMBER(value));
|
||||||
break;
|
break;
|
||||||
|
case VAL_OBJ:
|
||||||
|
printObject(value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +55,12 @@ bool valuesEqual(Value a, Value b) {
|
||||||
return true;
|
return true;
|
||||||
case VAL_NUMBER:
|
case VAL_NUMBER:
|
||||||
return AS_NUMBER(a) == AS_NUMBER(b);
|
return AS_NUMBER(a) == AS_NUMBER(b);
|
||||||
|
case VAL_OBJ: {
|
||||||
|
ObjString *aString = AS_STRING(a);
|
||||||
|
ObjString *bString = AS_STRING(b);
|
||||||
|
return aString->length == bString->length &&
|
||||||
|
memcmp(aString->chars, bString->chars, aString->length) == 0;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false; /* Unreachable */
|
return false; /* Unreachable */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "object.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
VM vm;
|
VM vm;
|
||||||
|
@ -43,6 +46,20 @@ static bool isFalsey(Value value) {
|
||||||
return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
|
return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void concatenate() {
|
||||||
|
ObjString *b = AS_STRING(pop());
|
||||||
|
ObjString *a = AS_STRING(pop());
|
||||||
|
|
||||||
|
int length = a->length + b->length;
|
||||||
|
char *chars = ALLOCATE(char, length + 1);
|
||||||
|
memcpy(chars, a->chars, a->length);
|
||||||
|
memcpy(chars + a->length, b->chars, b->length);
|
||||||
|
chars[length] = '\0';
|
||||||
|
|
||||||
|
ObjString *result = takeString(chars, length);
|
||||||
|
push(OBJ_VAL(result));
|
||||||
|
}
|
||||||
|
|
||||||
static InterpretResult run() {
|
static InterpretResult run() {
|
||||||
#define READ_BYTE() (*vm.ip++)
|
#define READ_BYTE() (*vm.ip++)
|
||||||
#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
|
#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
|
||||||
|
@ -96,9 +113,19 @@ static InterpretResult run() {
|
||||||
case OP_LESS:
|
case OP_LESS:
|
||||||
BINARY_OP(BOOL_VAL, <);
|
BINARY_OP(BOOL_VAL, <);
|
||||||
break;
|
break;
|
||||||
case OP_ADD:
|
case OP_ADD: {
|
||||||
BINARY_OP(NUMBER_VAL, +);
|
if (IS_STRING(peek(0)) && IS_STRING(peek(1))) {
|
||||||
|
concatenate();
|
||||||
|
} else if (IS_NUMBER(peek(0)) && IS_NUMBER(peek(1))) {
|
||||||
|
double b = AS_NUMBER(pop());
|
||||||
|
double a = AS_NUMBER(pop());
|
||||||
|
push(NUMBER_VAL(a + b));
|
||||||
|
} else {
|
||||||
|
runtimeError("Operands must be two numbers or two strings.");
|
||||||
|
return INTERPRET_RUNTIME_ERROR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case OP_SUBTRACT:
|
case OP_SUBTRACT:
|
||||||
BINARY_OP(NUMBER_VAL, -);
|
BINARY_OP(NUMBER_VAL, -);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue