7d7992d3502bc3b16d7a10903a4825c270ff5696
[supertux.git] / src / scripting / serialize.cpp
1 #include "serialize.hpp"
2
3 #include <memory>
4 #include <assert.h>
5 #include "lisp/lisp.hpp"
6 #include "lisp/list_iterator.hpp"
7 #include "lisp/parser.hpp"
8 #include "lisp/writer.hpp"
9 #include "squirrel_error.hpp"
10
11 namespace Scripting
12 {
13
14 void load_squirrel_table(HSQUIRRELVM vm, int table_idx, const lisp::Lisp* lisp)
15 {
16   using namespace lisp;
17
18   if(table_idx < 0)
19     table_idx -= 2; 
20  
21   lisp::ListIterator iter(lisp);
22   while(iter.next()) {
23     const std::string& token = iter.item();
24     sq_pushstring(vm, token.c_str(), token.size());
25
26     const lisp::Lisp* value = iter.value();
27     switch(value->get_type()) {
28       case Lisp::TYPE_CONS:
29         sq_newtable(vm);
30         load_squirrel_table(vm, sq_gettop(vm), iter.lisp());
31         break;
32       case Lisp::TYPE_INTEGER:
33         sq_pushinteger(vm, value->get_int());
34         break;
35       case Lisp::TYPE_REAL:
36         sq_pushfloat(vm, value->get_float());
37         break;
38       case Lisp::TYPE_STRING:
39         sq_pushstring(vm, value->get_string().c_str(), -1);
40         break;
41       case Lisp::TYPE_BOOLEAN:
42         sq_pushbool(vm, value->get_bool() ? SQTrue : SQFalse);
43         break;
44       case Lisp::TYPE_SYMBOL:
45         std::cerr << "Unexpected symbol in lisp file...";
46         sq_pushnull(vm);
47         break;
48       default:
49         assert(false);
50         break;
51     }
52
53     if(SQ_FAILED(sq_createslot(vm, table_idx)))
54       throw Scripting::SquirrelError(vm, "Couldn't create new index");
55   }
56 }
57
58 void save_squirrel_table(HSQUIRRELVM vm, int table_idx, lisp::Writer& writer)
59 {
60   // offset because of sq_pushnull
61   if(table_idx < 0)
62     table_idx -= 1;
63   
64   //iterator table
65   sq_pushnull(vm);
66   while(SQ_SUCCEEDED(sq_next(vm, table_idx))) {
67     if(sq_gettype(vm, -2) != OT_STRING) {
68       std::cerr << "Table contains non-string key\n";
69       continue;
70     }
71     const char* key;
72     sq_getstring(vm, -2, &key);
73
74     switch(sq_gettype(vm, -1)) {
75       case OT_INTEGER: {
76         int val;
77         sq_getinteger(vm, -1, &val);
78         writer.write_int(key, val);
79         break;
80       }
81       case OT_FLOAT: {
82         float val;
83         sq_getfloat(vm, -1, &val);
84         writer.write_float(key, val);
85         break;
86       }
87       case OT_BOOL: {
88         SQBool val;
89         sq_getbool(vm, -1, &val);
90         writer.write_bool(key, val);
91         break;
92       }
93       case OT_STRING: {
94         const char* str;
95         sq_getstring(vm, -1, &str);
96         writer.write_string(key, str);
97         break;
98       }
99       case OT_TABLE: {
100         writer.start_list(key, true);
101         save_squirrel_table(vm, -1, writer);
102         writer.end_list(key);
103         break;
104       }
105       case OT_CLOSURE:
106         break; // ignore
107       case OT_NATIVECLOSURE:
108         break;
109       default:
110         std::cerr << "Can't serialize key '" << key << "' in table.\n";
111         break;
112     }
113     sq_pop(vm, 2);
114   }
115   sq_pop(vm, 1);
116 }
117
118 }
119