Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
variable.c@0:1a89e28dea91, 2012-05-30 (annotated)
- Committer:
- yusufx
- Date:
- Wed May 30 21:13:01 2012 +0000
- Revision:
- 0:1a89e28dea91
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| yusufx | 0:1a89e28dea91 | 1 | #include <string.h> |
| yusufx | 0:1a89e28dea91 | 2 | /*#include <stdio.h> |
| yusufx | 0:1a89e28dea91 | 3 | #include <signal.h> |
| yusufx | 0:1a89e28dea91 | 4 | #include <stdarg.h> |
| yusufx | 0:1a89e28dea91 | 5 | #include <time.h> |
| yusufx | 0:1a89e28dea91 | 6 | #include "util.h" |
| yusufx | 0:1a89e28dea91 | 7 | #include "sys.h" |
| yusufx | 0:1a89e28dea91 | 8 | */ |
| yusufx | 0:1a89e28dea91 | 9 | #include "vm.h" |
| yusufx | 0:1a89e28dea91 | 10 | #include "struct.h" |
| yusufx | 0:1a89e28dea91 | 11 | #include "serial.h" |
| yusufx | 0:1a89e28dea91 | 12 | #include "variable.h" |
| yusufx | 0:1a89e28dea91 | 13 | #include "util.h" |
| yusufx | 0:1a89e28dea91 | 14 | |
| yusufx | 0:1a89e28dea91 | 15 | #define ERROR_VAR_TYPE "type error" |
| yusufx | 0:1a89e28dea91 | 16 | #define VAR_MAX 100 |
| yusufx | 0:1a89e28dea91 | 17 | |
| yusufx | 0:1a89e28dea91 | 18 | const struct number_string var_types[] = { |
| yusufx | 0:1a89e28dea91 | 19 | {VAR_NIL, "nil"}, |
| yusufx | 0:1a89e28dea91 | 20 | {VAR_INT, "integer"}, |
| yusufx | 0:1a89e28dea91 | 21 | {VAR_BOOL, "boolean"}, |
| yusufx | 0:1a89e28dea91 | 22 | {VAR_FLT, "float"}, |
| yusufx | 0:1a89e28dea91 | 23 | {VAR_STR, "string"}, |
| yusufx | 0:1a89e28dea91 | 24 | {VAR_LST, "list"}, |
| yusufx | 0:1a89e28dea91 | 25 | {VAR_FNC, "function"}, |
| yusufx | 0:1a89e28dea91 | 26 | {VAR_MAP, "map"}, |
| yusufx | 0:1a89e28dea91 | 27 | {VAR_ERR, "error"}, |
| yusufx | 0:1a89e28dea91 | 28 | {VAR_C, "c-function"}, |
| yusufx | 0:1a89e28dea91 | 29 | }; |
| yusufx | 0:1a89e28dea91 | 30 | |
| yusufx | 0:1a89e28dea91 | 31 | const char *var_type_str(enum VarType vt) |
| yusufx | 0:1a89e28dea91 | 32 | { |
| yusufx | 0:1a89e28dea91 | 33 | return NUM_TO_STRING(var_types, vt); |
| yusufx | 0:1a89e28dea91 | 34 | } |
| yusufx | 0:1a89e28dea91 | 35 | |
| yusufx | 0:1a89e28dea91 | 36 | struct variable* variable_new(struct Context *context, enum VarType type) |
| yusufx | 0:1a89e28dea91 | 37 | { |
| yusufx | 0:1a89e28dea91 | 38 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 39 | if (context->num_vars++ > VAR_MAX) |
| yusufx | 0:1a89e28dea91 | 40 | garbage_collect(context); |
| yusufx | 0:1a89e28dea91 | 41 | struct variable* v = (struct variable*)malloc(sizeof(struct variable)); |
| yusufx | 0:1a89e28dea91 | 42 | v->type = type; |
| yusufx | 0:1a89e28dea91 | 43 | v->map = NULL; |
| yusufx | 0:1a89e28dea91 | 44 | v->marked = false; |
| yusufx | 0:1a89e28dea91 | 45 | return v; |
| yusufx | 0:1a89e28dea91 | 46 | } |
| yusufx | 0:1a89e28dea91 | 47 | |
| yusufx | 0:1a89e28dea91 | 48 | struct variable* variable_new_err(struct Context *context, const char* message) |
| yusufx | 0:1a89e28dea91 | 49 | { |
| yusufx | 0:1a89e28dea91 | 50 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 51 | struct variable *v = variable_new(context, VAR_ERR); |
| yusufx | 0:1a89e28dea91 | 52 | v->str = byte_array_from_string(message); |
| yusufx | 0:1a89e28dea91 | 53 | return v; |
| yusufx | 0:1a89e28dea91 | 54 | } |
| yusufx | 0:1a89e28dea91 | 55 | |
| yusufx | 0:1a89e28dea91 | 56 | struct variable* variable_new_nil(struct Context *context) |
| yusufx | 0:1a89e28dea91 | 57 | { |
| yusufx | 0:1a89e28dea91 | 58 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 59 | return variable_new(context, VAR_NIL); |
| yusufx | 0:1a89e28dea91 | 60 | } |
| yusufx | 0:1a89e28dea91 | 61 | |
| yusufx | 0:1a89e28dea91 | 62 | struct variable* variable_new_int(struct Context *context, int32_t i) |
| yusufx | 0:1a89e28dea91 | 63 | { |
| yusufx | 0:1a89e28dea91 | 64 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 65 | struct variable *v = variable_new(context, VAR_INT); |
| yusufx | 0:1a89e28dea91 | 66 | v->integer = i; |
| yusufx | 0:1a89e28dea91 | 67 | return v; |
| yusufx | 0:1a89e28dea91 | 68 | } |
| yusufx | 0:1a89e28dea91 | 69 | |
| yusufx | 0:1a89e28dea91 | 70 | struct variable* variable_new_bool(struct Context *context, bool b) |
| yusufx | 0:1a89e28dea91 | 71 | { |
| yusufx | 0:1a89e28dea91 | 72 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 73 | struct variable *v = variable_new(context, VAR_BOOL); |
| yusufx | 0:1a89e28dea91 | 74 | v->boolean = b; |
| yusufx | 0:1a89e28dea91 | 75 | return v; |
| yusufx | 0:1a89e28dea91 | 76 | } |
| yusufx | 0:1a89e28dea91 | 77 | |
| yusufx | 0:1a89e28dea91 | 78 | void variable_del(struct Context *context, struct variable *v) |
| yusufx | 0:1a89e28dea91 | 79 | { |
| yusufx | 0:1a89e28dea91 | 80 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 81 | context->num_vars--; |
| yusufx | 0:1a89e28dea91 | 82 | switch (v->type) { |
| yusufx | 0:1a89e28dea91 | 83 | case VAR_INT: |
| yusufx | 0:1a89e28dea91 | 84 | case VAR_FLT: |
| yusufx | 0:1a89e28dea91 | 85 | case VAR_MAP: |
| yusufx | 0:1a89e28dea91 | 86 | break; |
| yusufx | 0:1a89e28dea91 | 87 | case VAR_STR: |
| yusufx | 0:1a89e28dea91 | 88 | case VAR_FNC: |
| yusufx | 0:1a89e28dea91 | 89 | byte_array_del(v->str); |
| yusufx | 0:1a89e28dea91 | 90 | break; |
| yusufx | 0:1a89e28dea91 | 91 | case VAR_LST: |
| yusufx | 0:1a89e28dea91 | 92 | for (int i=0; i<v->list->length; i++) |
| yusufx | 0:1a89e28dea91 | 93 | variable_del(context, (struct variable*)array_get(v->list, i)); |
| yusufx | 0:1a89e28dea91 | 94 | break; |
| yusufx | 0:1a89e28dea91 | 95 | default: |
| yusufx | 0:1a89e28dea91 | 96 | vm_exit_message(context, "bad var type"); |
| yusufx | 0:1a89e28dea91 | 97 | break; |
| yusufx | 0:1a89e28dea91 | 98 | } |
| yusufx | 0:1a89e28dea91 | 99 | if (v->map) { |
| yusufx | 0:1a89e28dea91 | 100 | struct array *keys = map_keys(v->map); |
| yusufx | 0:1a89e28dea91 | 101 | struct array *values = map_values(v->map); |
| yusufx | 0:1a89e28dea91 | 102 | for (int i=0; i<keys->length; i++) { |
| yusufx | 0:1a89e28dea91 | 103 | byte_array_del((struct byte_array*)array_get(keys, i)); |
| yusufx | 0:1a89e28dea91 | 104 | variable_del(context, (struct variable*)array_get(values, i)); |
| yusufx | 0:1a89e28dea91 | 105 | } |
| yusufx | 0:1a89e28dea91 | 106 | array_del(keys); |
| yusufx | 0:1a89e28dea91 | 107 | array_del(values); |
| yusufx | 0:1a89e28dea91 | 108 | map_del(v->map); |
| yusufx | 0:1a89e28dea91 | 109 | } |
| yusufx | 0:1a89e28dea91 | 110 | free(v); |
| yusufx | 0:1a89e28dea91 | 111 | } |
| yusufx | 0:1a89e28dea91 | 112 | |
| yusufx | 0:1a89e28dea91 | 113 | struct variable* variable_new_float(struct Context *context, float f) |
| yusufx | 0:1a89e28dea91 | 114 | { |
| yusufx | 0:1a89e28dea91 | 115 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 116 | //DEBUGPRINT("new float %f\n", f); |
| yusufx | 0:1a89e28dea91 | 117 | struct variable *v = variable_new(context, VAR_FLT); |
| yusufx | 0:1a89e28dea91 | 118 | v->floater = f; |
| yusufx | 0:1a89e28dea91 | 119 | return v; |
| yusufx | 0:1a89e28dea91 | 120 | } |
| yusufx | 0:1a89e28dea91 | 121 | |
| yusufx | 0:1a89e28dea91 | 122 | struct variable *variable_new_str(struct Context *context, struct byte_array *str) { |
| yusufx | 0:1a89e28dea91 | 123 | struct variable *v = variable_new(context, VAR_STR); |
| yusufx | 0:1a89e28dea91 | 124 | v->str = str; |
| yusufx | 0:1a89e28dea91 | 125 | return v; |
| yusufx | 0:1a89e28dea91 | 126 | } |
| yusufx | 0:1a89e28dea91 | 127 | |
| yusufx | 0:1a89e28dea91 | 128 | struct variable *variable_new_fnc(struct Context *context, struct byte_array *fnc) { |
| yusufx | 0:1a89e28dea91 | 129 | struct variable *v = variable_new(context, VAR_FNC); |
| yusufx | 0:1a89e28dea91 | 130 | v->str = fnc; |
| yusufx | 0:1a89e28dea91 | 131 | return v; |
| yusufx | 0:1a89e28dea91 | 132 | } |
| yusufx | 0:1a89e28dea91 | 133 | |
| yusufx | 0:1a89e28dea91 | 134 | struct variable *variable_new_list(struct Context *context, struct array *list) { |
| yusufx | 0:1a89e28dea91 | 135 | struct variable *v = variable_new(context, VAR_LST); |
| yusufx | 0:1a89e28dea91 | 136 | v->list = list ? list : array_new(); |
| yusufx | 0:1a89e28dea91 | 137 | return v; |
| yusufx | 0:1a89e28dea91 | 138 | } |
| yusufx | 0:1a89e28dea91 | 139 | |
| yusufx | 0:1a89e28dea91 | 140 | struct variable *variable_new_map(struct Context *context, struct map *map) { |
| yusufx | 0:1a89e28dea91 | 141 | struct variable *v = variable_new(context, VAR_MAP); |
| yusufx | 0:1a89e28dea91 | 142 | v->map = map; |
| yusufx | 0:1a89e28dea91 | 143 | return v; |
| yusufx | 0:1a89e28dea91 | 144 | } |
| yusufx | 0:1a89e28dea91 | 145 | |
| yusufx | 0:1a89e28dea91 | 146 | struct variable *variable_new_c(struct Context *context, bridge *cfnc) { |
| yusufx | 0:1a89e28dea91 | 147 | struct variable *v = variable_new(context, VAR_C); |
| yusufx | 0:1a89e28dea91 | 148 | v->cfnc = cfnc; |
| yusufx | 0:1a89e28dea91 | 149 | return v; |
| yusufx | 0:1a89e28dea91 | 150 | } |
| yusufx | 0:1a89e28dea91 | 151 | |
| yusufx | 0:1a89e28dea91 | 152 | const char *variable_value_str(struct Context *context, const struct variable* v) |
| yusufx | 0:1a89e28dea91 | 153 | { |
| yusufx | 0:1a89e28dea91 | 154 | null_check(v); |
| yusufx | 0:1a89e28dea91 | 155 | char* str = (char*)malloc(100); |
| yusufx | 0:1a89e28dea91 | 156 | struct array* list = v->list; |
| yusufx | 0:1a89e28dea91 | 157 | |
| yusufx | 0:1a89e28dea91 | 158 | enum VarType vt = (enum VarType)v->type; |
| yusufx | 0:1a89e28dea91 | 159 | switch (vt) { |
| yusufx | 0:1a89e28dea91 | 160 | case VAR_NIL: sprintf(str, "nil"); break; |
| yusufx | 0:1a89e28dea91 | 161 | case VAR_INT: sprintf(str, "%d", v->integer); break; |
| yusufx | 0:1a89e28dea91 | 162 | case VAR_BOOL: sprintf(str, "%s", v->boolean ? "true" : "false"); break; |
| yusufx | 0:1a89e28dea91 | 163 | case VAR_FLT: sprintf(str, "%f", v->floater); break; |
| yusufx | 0:1a89e28dea91 | 164 | case VAR_STR: sprintf(str, "%s", byte_array_to_string(v->str)); break; |
| yusufx | 0:1a89e28dea91 | 165 | case VAR_FNC: sprintf(str, "f(%dB)", v->str->length); break; |
| yusufx | 0:1a89e28dea91 | 166 | case VAR_C: sprintf(str, "c-function"); break; |
| yusufx | 0:1a89e28dea91 | 167 | case VAR_MAP: break; |
| yusufx | 0:1a89e28dea91 | 168 | case VAR_LST: { |
| yusufx | 0:1a89e28dea91 | 169 | strcpy(str, "["); |
| yusufx | 0:1a89e28dea91 | 170 | vm_null_check(context, list); |
| yusufx | 0:1a89e28dea91 | 171 | for (int i=0; i<list->length; i++) { |
| yusufx | 0:1a89e28dea91 | 172 | struct variable* element = (struct variable*)array_get(list, i); |
| yusufx | 0:1a89e28dea91 | 173 | vm_null_check(context, element); |
| yusufx | 0:1a89e28dea91 | 174 | const char *q = (element->type == VAR_STR || element->type == VAR_FNC) ? "'" : ""; |
| yusufx | 0:1a89e28dea91 | 175 | const char *c = i ? "," : ""; |
| yusufx | 0:1a89e28dea91 | 176 | const char *estr = variable_value_str(context, element); |
| yusufx | 0:1a89e28dea91 | 177 | sprintf(str, "%s%s%s%s%s", str, c, q, estr, q); |
| yusufx | 0:1a89e28dea91 | 178 | } |
| yusufx | 0:1a89e28dea91 | 179 | } break; |
| yusufx | 0:1a89e28dea91 | 180 | case VAR_ERR: |
| yusufx | 0:1a89e28dea91 | 181 | strcpy(str, byte_array_to_string(v->str)); |
| yusufx | 0:1a89e28dea91 | 182 | break; |
| yusufx | 0:1a89e28dea91 | 183 | default: |
| yusufx | 0:1a89e28dea91 | 184 | vm_exit_message(context, ERROR_VAR_TYPE); |
| yusufx | 0:1a89e28dea91 | 185 | break; |
| yusufx | 0:1a89e28dea91 | 186 | } |
| yusufx | 0:1a89e28dea91 | 187 | |
| yusufx | 0:1a89e28dea91 | 188 | if (v->map) { |
| yusufx | 0:1a89e28dea91 | 189 | const struct array *a = map_keys(v->map); |
| yusufx | 0:1a89e28dea91 | 190 | const struct array *b = map_values(v->map); |
| yusufx | 0:1a89e28dea91 | 191 | |
| yusufx | 0:1a89e28dea91 | 192 | if (vt != VAR_LST) |
| yusufx | 0:1a89e28dea91 | 193 | strcat(str, "["); |
| yusufx | 0:1a89e28dea91 | 194 | else if (v->list->length && a->length) |
| yusufx | 0:1a89e28dea91 | 195 | strcat(str, ","); |
| yusufx | 0:1a89e28dea91 | 196 | for (int i=0; i<a->length; i++) { |
| yusufx | 0:1a89e28dea91 | 197 | if (i) |
| yusufx | 0:1a89e28dea91 | 198 | strcat(str, ","); |
| yusufx | 0:1a89e28dea91 | 199 | strcat(str, "'"); |
| yusufx | 0:1a89e28dea91 | 200 | strcat(str, byte_array_to_string((struct byte_array*)array_get(a,i))); |
| yusufx | 0:1a89e28dea91 | 201 | strcat(str, "'"); |
| yusufx | 0:1a89e28dea91 | 202 | strcat(str, ":"); |
| yusufx | 0:1a89e28dea91 | 203 | const struct variable *biv = (const struct variable*)array_get(b,i); |
| yusufx | 0:1a89e28dea91 | 204 | const char *bistr = variable_value_str(context, biv); |
| yusufx | 0:1a89e28dea91 | 205 | strcat(str, bistr); |
| yusufx | 0:1a89e28dea91 | 206 | } |
| yusufx | 0:1a89e28dea91 | 207 | strcat(str, "]"); |
| yusufx | 0:1a89e28dea91 | 208 | } |
| yusufx | 0:1a89e28dea91 | 209 | else if (vt == VAR_LST) |
| yusufx | 0:1a89e28dea91 | 210 | strcat(str, "]"); |
| yusufx | 0:1a89e28dea91 | 211 | |
| yusufx | 0:1a89e28dea91 | 212 | return str; |
| yusufx | 0:1a89e28dea91 | 213 | } |
| yusufx | 0:1a89e28dea91 | 214 | |
| yusufx | 0:1a89e28dea91 | 215 | struct byte_array *variable_value(struct Context *c, const struct variable *v) { |
| yusufx | 0:1a89e28dea91 | 216 | const char *str = variable_value_str(c, v); |
| yusufx | 0:1a89e28dea91 | 217 | return byte_array_from_string(str); |
| yusufx | 0:1a89e28dea91 | 218 | } |
| yusufx | 0:1a89e28dea91 | 219 | |
| yusufx | 0:1a89e28dea91 | 220 | |
| yusufx | 0:1a89e28dea91 | 221 | |
| yusufx | 0:1a89e28dea91 | 222 | struct variable *variable_pop(struct Context *context) |
| yusufx | 0:1a89e28dea91 | 223 | { |
| yusufx | 0:1a89e28dea91 | 224 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 225 | struct variable *v = (struct variable*)stack_pop(context->operand_stack); |
| yusufx | 0:1a89e28dea91 | 226 | //DEBUGPRINT("\nvariable_pop\n");// %s\n", variable_value(v)); |
| yusufx | 0:1a89e28dea91 | 227 | // print_operand_stack(); |
| yusufx | 0:1a89e28dea91 | 228 | return v; |
| yusufx | 0:1a89e28dea91 | 229 | } |
| yusufx | 0:1a89e28dea91 | 230 | |
| yusufx | 0:1a89e28dea91 | 231 | void variable_push(struct Context *context, struct variable *v) |
| yusufx | 0:1a89e28dea91 | 232 | { |
| yusufx | 0:1a89e28dea91 | 233 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 234 | stack_push(context->operand_stack, v); |
| yusufx | 0:1a89e28dea91 | 235 | //DEBUGPRINT("\nvariable_push\n"); |
| yusufx | 0:1a89e28dea91 | 236 | //print_operand_stack(); |
| yusufx | 0:1a89e28dea91 | 237 | } |
| yusufx | 0:1a89e28dea91 | 238 | |
| yusufx | 0:1a89e28dea91 | 239 | struct byte_array *variable_serialize(struct Context *context, |
| yusufx | 0:1a89e28dea91 | 240 | struct byte_array *bits, |
| yusufx | 0:1a89e28dea91 | 241 | const struct variable *in) |
| yusufx | 0:1a89e28dea91 | 242 | { |
| yusufx | 0:1a89e28dea91 | 243 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 244 | //DEBUGPRINT("\tserialize:%s\n", variable_value(in)); |
| yusufx | 0:1a89e28dea91 | 245 | if (!bits) |
| yusufx | 0:1a89e28dea91 | 246 | bits = byte_array_new(); |
| yusufx | 0:1a89e28dea91 | 247 | serial_encode_int(bits, 0, in->type); |
| yusufx | 0:1a89e28dea91 | 248 | switch (in->type) { |
| yusufx | 0:1a89e28dea91 | 249 | case VAR_INT: serial_encode_int(bits, 0, in->integer); break; |
| yusufx | 0:1a89e28dea91 | 250 | case VAR_FLT: serial_encode_float(bits, 0, in->floater); break; |
| yusufx | 0:1a89e28dea91 | 251 | case VAR_STR: |
| yusufx | 0:1a89e28dea91 | 252 | case VAR_FNC: serial_encode_string(bits, 0, in->str); break; |
| yusufx | 0:1a89e28dea91 | 253 | case VAR_LST: { |
| yusufx | 0:1a89e28dea91 | 254 | serial_encode_int(bits, 0, in->list->length); |
| yusufx | 0:1a89e28dea91 | 255 | for (int i=0; i<in->list->length; i++) |
| yusufx | 0:1a89e28dea91 | 256 | variable_serialize(context, bits, (const struct variable*)array_get(in->list, i)); |
| yusufx | 0:1a89e28dea91 | 257 | if (in->map) { |
| yusufx | 0:1a89e28dea91 | 258 | const struct array *keys = map_keys(in->map); |
| yusufx | 0:1a89e28dea91 | 259 | const struct array *values = map_values(in->map); |
| yusufx | 0:1a89e28dea91 | 260 | serial_encode_int(bits, 0, keys->length); |
| yusufx | 0:1a89e28dea91 | 261 | for (int i=0; i<keys->length; i++) { |
| yusufx | 0:1a89e28dea91 | 262 | serial_encode_string(bits, 0, (const struct byte_array*)array_get(keys, i)); |
| yusufx | 0:1a89e28dea91 | 263 | variable_serialize(context, bits, (const struct variable*)array_get(values, i)); |
| yusufx | 0:1a89e28dea91 | 264 | } |
| yusufx | 0:1a89e28dea91 | 265 | } else |
| yusufx | 0:1a89e28dea91 | 266 | serial_encode_int(bits, 0, 0); |
| yusufx | 0:1a89e28dea91 | 267 | } break; |
| yusufx | 0:1a89e28dea91 | 268 | case VAR_MAP: break; |
| yusufx | 0:1a89e28dea91 | 269 | default: vm_exit_message(context, "bad var type"); break; |
| yusufx | 0:1a89e28dea91 | 270 | } |
| yusufx | 0:1a89e28dea91 | 271 | |
| yusufx | 0:1a89e28dea91 | 272 | //DEBUGPRINT("in: %s\n", variable_value(in)); |
| yusufx | 0:1a89e28dea91 | 273 | //byte_array_print("serialized: ", bits); |
| yusufx | 0:1a89e28dea91 | 274 | return bits; |
| yusufx | 0:1a89e28dea91 | 275 | } |
| yusufx | 0:1a89e28dea91 | 276 | |
| yusufx | 0:1a89e28dea91 | 277 | struct variable *variable_deserialize(struct Context *context, struct byte_array *bits) |
| yusufx | 0:1a89e28dea91 | 278 | { |
| yusufx | 0:1a89e28dea91 | 279 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 280 | enum VarType vt = (enum VarType)serial_decode_int(bits); |
| yusufx | 0:1a89e28dea91 | 281 | switch (vt) { |
| yusufx | 0:1a89e28dea91 | 282 | case VAR_NIL: return variable_new_nil(context); |
| yusufx | 0:1a89e28dea91 | 283 | case VAR_INT: return variable_new_int(context, serial_decode_int(bits)); |
| yusufx | 0:1a89e28dea91 | 284 | case VAR_FLT: return variable_new_float(context, serial_decode_float(bits)); |
| yusufx | 0:1a89e28dea91 | 285 | case VAR_FNC: return variable_new_fnc(context, serial_decode_string(bits)); |
| yusufx | 0:1a89e28dea91 | 286 | case VAR_STR: return variable_new_str(context, serial_decode_string(bits)); |
| yusufx | 0:1a89e28dea91 | 287 | case VAR_LST: { |
| yusufx | 0:1a89e28dea91 | 288 | uint32_t size = serial_decode_int(bits); |
| yusufx | 0:1a89e28dea91 | 289 | struct array *list = array_new_size(size); |
| yusufx | 0:1a89e28dea91 | 290 | while (size--) |
| yusufx | 0:1a89e28dea91 | 291 | array_add(list, variable_deserialize(context, bits)); |
| yusufx | 0:1a89e28dea91 | 292 | struct variable *out = variable_new_list(context, list); |
| yusufx | 0:1a89e28dea91 | 293 | |
| yusufx | 0:1a89e28dea91 | 294 | uint32_t map_length = serial_decode_int(bits); |
| yusufx | 0:1a89e28dea91 | 295 | if (map_length) { |
| yusufx | 0:1a89e28dea91 | 296 | out->map = map_new(); |
| yusufx | 0:1a89e28dea91 | 297 | for (int i=0; i<map_length; i++) { |
| yusufx | 0:1a89e28dea91 | 298 | struct byte_array *key = serial_decode_string(bits); |
| yusufx | 0:1a89e28dea91 | 299 | struct variable *value = variable_deserialize(context, bits); |
| yusufx | 0:1a89e28dea91 | 300 | map_insert(out->map, key, value); |
| yusufx | 0:1a89e28dea91 | 301 | } |
| yusufx | 0:1a89e28dea91 | 302 | } |
| yusufx | 0:1a89e28dea91 | 303 | return out; |
| yusufx | 0:1a89e28dea91 | 304 | } |
| yusufx | 0:1a89e28dea91 | 305 | default: |
| yusufx | 0:1a89e28dea91 | 306 | vm_exit_message(context, "bad var type"); |
| yusufx | 0:1a89e28dea91 | 307 | return NULL; |
| yusufx | 0:1a89e28dea91 | 308 | } |
| yusufx | 0:1a89e28dea91 | 309 | } |
| yusufx | 0:1a89e28dea91 | 310 | |
| yusufx | 0:1a89e28dea91 | 311 | int variable_save(struct Context *context, |
| yusufx | 0:1a89e28dea91 | 312 | const struct variable *v, |
| yusufx | 0:1a89e28dea91 | 313 | const struct variable *path) |
| yusufx | 0:1a89e28dea91 | 314 | { |
| yusufx | 0:1a89e28dea91 | 315 | vm_null_check(context, v); |
| yusufx | 0:1a89e28dea91 | 316 | vm_null_check(context, path); |
| yusufx | 0:1a89e28dea91 | 317 | |
| yusufx | 0:1a89e28dea91 | 318 | struct byte_array *bytes = byte_array_new(); |
| yusufx | 0:1a89e28dea91 | 319 | variable_serialize(context, bytes, v); |
| yusufx | 0:1a89e28dea91 | 320 | return write_file(path->str, bytes); |
| yusufx | 0:1a89e28dea91 | 321 | } |
| yusufx | 0:1a89e28dea91 | 322 | |
| yusufx | 0:1a89e28dea91 | 323 | struct variable *variable_load(struct Context *context, const struct variable *path) |
| yusufx | 0:1a89e28dea91 | 324 | { |
| yusufx | 0:1a89e28dea91 | 325 | null_check(context); |
| yusufx | 0:1a89e28dea91 | 326 | vm_null_check(context, path); |
| yusufx | 0:1a89e28dea91 | 327 | |
| yusufx | 0:1a89e28dea91 | 328 | struct byte_array *file_bytes = read_file(path->str); |
| yusufx | 0:1a89e28dea91 | 329 | if (!file_bytes) |
| yusufx | 0:1a89e28dea91 | 330 | return NULL; |
| yusufx | 0:1a89e28dea91 | 331 | struct variable *v = variable_deserialize(context, file_bytes); |
| yusufx | 0:1a89e28dea91 | 332 | return v; |
| yusufx | 0:1a89e28dea91 | 333 | } |
| yusufx | 0:1a89e28dea91 | 334 |