Yusuf X / filagree

Dependents:   filagree_test

Committer:
yusufx
Date:
Wed May 30 21:13:01 2012 +0000
Revision:
0:1a89e28dea91

        

Who changed what in which revision?

UserRevisionLine numberNew 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