-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstrings.c
92 lines (84 loc) · 2.78 KB
/
strings.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <stdio.h>
#include <stddef.h>
#include "value.h"
#include "strings.h"
#include "memory.h"
#include "hashmap.h"
#include "vm.h"
#include <string.h>
#include <malloc.h>
char *type_to_string(Value value) {
switch (value.type) {
case TYPE_BOOL:
return "<builtin 'bool'>";
case TYPE_DECIMAL:
return "<builtin 'decimal'>";
case TYPE_INTEGER:
return "<builtin 'integer'>";
case TYPE_NIL:
return "<builtin 'nil'>";
case TYPE_OBJECT:
if (IS_STRING(value))
return "<class 'String'>";
else
return "<class 'Object'>";
default:
return "<unknown type>";
}
}
static char *long_to_string(int64_t value) {
char *buffer = ALLOCATE(char, 22);
snprintf(buffer, 22, "%ld", value);
return buffer;
}
static char *double_to_string(double value) {
char *buffer = ALLOCATE(char, 22);
snprintf(buffer, 22, "%.15g", value);
return buffer;
}
ObjString *value_to_string(Value value) {
char *value_as_string;
switch (value.type) {
case TYPE_INTEGER:
value_as_string = long_to_string(value.as.integer);
return make_objstring(value_as_string, (int) strlen(value_as_string));
case TYPE_DECIMAL:
value_as_string = double_to_string(value.as.decimal);
return make_objstring(value_as_string, (int) strlen(value_as_string));
case TYPE_BOOL:
if (value.as.integer == 0) {
return make_objstring("false", 6);
} else {
return make_objstring("true", 5);
}
case TYPE_OBJECT:
if (IS_STRING(value))
return ((ObjString *) value.as.object);
else
return make_objstring(type_to_string(value), (int) strlen(type_to_string(value)));
case TYPE_NIL:
default:
return make_objstring("nil", 4);
}
}
ObjString *make_objstring(const char *chars, int length) {
uint32_t hash = hash_string(chars, length);
ObjString *interned = get_string_entry(&vm.strings, chars, length, hash);
if (interned != NULL) return interned;
ObjString *string = malloc(sizeof(ObjString) + sizeof(char) * (length + 1));
string->type = OBJ_STRING;
string->length = length;
memcpy(string->chars, chars, length);
string->chars[length] = '\0';
string->hash = hash;
add_entry(&vm.strings, STRING_CAST(string), NIL);
return string;
}
ObjString *concatenate_strings(ObjString *a, ObjString *b) {
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';
return make_objstring(chars, length);
}