Browse Source

Sol Part 35: Now With More Snakes!

Graham Northup 5 years ago
parent
commit
39ca473230
6 changed files with 209 additions and 40 deletions
  1. 1
    0
      .gitignore
  2. 30
    27
      builtins.c
  3. 1
    0
      interp.sol
  4. 17
    11
      object.c
  5. 158
    0
      sol-gdb.py
  6. 2
    2
      sol.h

+ 1
- 0
.gitignore View File

@@ -7,3 +7,4 @@ stdout
7 7
 gclog.txt
8 8
 gcstat.txt
9 9
 iss*
10
+*.sol

+ 30
- 27
builtins.c View File

@@ -389,24 +389,26 @@ sol_object_t *sol_f_parse(sol_state_t *state, sol_object_t *args) {
389 389
 
390 390
 sol_object_t *sol_f_ord(sol_state_t *state, sol_object_t *args) {
391 391
 	sol_object_t *arg = sol_list_get_index(state, args, 0), *str = sol_cast_string(state, arg);
392
-	sol_object_t *idx = sol_new_int(state, 0), *arg2, *iarg, *res;
392
+	sol_object_t *arg2, *iarg, *res;
393
+	long idx = 0;
393 394
 	size_t len = strlen(str->str);
394 395
 	sol_obj_free(arg);
395 396
 	if(sol_list_len(state, args) > 1) {
396 397
 		arg2 = sol_list_get_index(state, args, 1);
397 398
 		iarg = sol_cast_int(state, arg2);
398 399
 		sol_obj_free(arg2);
399
-		idx->ival = iarg->ival;
400
+		idx = iarg->ival;
400 401
 		sol_obj_free(iarg);
401 402
 	}
402
-	if(idx->ival < 0 || idx->ival >= len) {
403
+	if(idx < 0) {
404
+		idx += len;
405
+	}
406
+	if(idx < 0 || idx >= len) {
403 407
 		sol_obj_free(str);
404
-		sol_obj_free(idx);
405 408
 		return sol_set_error_string(state, "Compute ord of out-of-bounds index");
406 409
 	}
407
-	res = sol_new_int(state, str->str[idx->ival]);
410
+	res = sol_new_int(state, str->str[idx]);
408 411
 	sol_obj_free(str);
409
-	sol_obj_free(idx);
410 412
 	return res;
411 413
 }
412 414
 
@@ -905,6 +907,7 @@ sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
905 907
 sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
906 908
 	sol_object_t *str = sol_list_get_index(state, args, 0), *low = sol_list_get_index(state, args, 1), *high = sol_list_get_index(state, args, 2);
907 909
 	sol_object_t *ilow, *ihigh;
910
+	long l, h;
908 911
 	size_t len = strlen(str->str), i;
909 912
 	char *s;
910 913
 	if(sol_is_none(state, low)) {
@@ -919,37 +922,37 @@ sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
919 922
 	}
920 923
 	sol_obj_free(low);
921 924
 	sol_obj_free(high);
922
-	if(ilow->ival < 0) {
923
-		ilow->ival += len;
924
-		if(ilow->ival < 0) {
925
-			ilow->ival = 0;
925
+	l = ilow->ival;
926
+	h = ihigh->ival;
927
+	sol_obj_free(ihigh);
928
+	sol_obj_free(ilow);
929
+	if(l < 0) {
930
+		l += len;
931
+		if(l < 0) {
932
+			l = 0;
926 933
 		}
927 934
 	}
928
-	if(ilow->ival > len) {
929
-		ilow->ival = len;
935
+	if(l > len) {
936
+		l = len;
930 937
 	}
931
-	if(ihigh->ival < 0) {
932
-		ihigh->ival += len;
933
-		if(ihigh->ival < 0) {
934
-			ihigh->ival = 0;
938
+	if(h < 0) {
939
+		h += len;
940
+		if(h < 0) {
941
+			h = 0;
935 942
 		}
936 943
 	}
937
-	if(ihigh->ival > len) {
938
-		ihigh->ival = len;
944
+	if(h > len) {
945
+		h = len;
939 946
 	}
940
-	if(ilow->ival >= ihigh->ival) {
941
-		sol_obj_free(ilow);
942
-		sol_obj_free(ihigh);
947
+	if(l >= h) {
943 948
 		sol_obj_free(str);
944 949
 		return sol_new_string(state, "");
945 950
 	}
946
-	s = malloc(ihigh->ival - ilow->ival + 1);
947
-	for(i = ilow->ival; i < ihigh->ival; i++) {
948
-		s[i - ilow->ival] = str->str[i];
951
+	s = malloc(h - l + 1);
952
+	for(i = l; i < h; i++) {
953
+		s[i - l] = str->str[i];
949 954
 	}
950
-	s[ihigh->ival - ilow->ival] = '\0';
951
-	sol_obj_free(ihigh);
952
-	sol_obj_free(ilow);
955
+	s[h - l] = '\0';
953 956
 	sol_obj_free(str);
954 957
 	return sol_new_string(state, s);
955 958
 }

+ 1
- 0
interp.sol View File

@@ -26,6 +26,7 @@ while __interp.running do
26 26
 	__interp.line = io.stdin:read(io.LINE)
27 27
 	__interp.line = __interp.line:sub(0, -1)
28 28
 	--prepr(__interp.line)
29
+	--prepr(__interp)
29 30
 	if (__interp.line:sub(-4, None)=="then") then
30 31
 		__interp.buffer+=__interp.line+" "
31 32
 		__interp.stmt_stack+=1

+ 17
- 11
object.c View File

@@ -76,7 +76,12 @@ sol_object_t *sol_new_int(sol_state_t *state, long i) {
76 76
 	sol_object_t *res;
77 77
 #ifdef SOL_ICACHE
78 78
 	if(!state->icache_bypass && i >= SOL_ICACHE_MIN && i <= SOL_ICACHE_MAX) {
79
-		return sol_incref(state->icache[i - SOL_ICACHE_MIN]);
79
+		res = sol_incref(state->icache[i - SOL_ICACHE_MIN]);
80
+		if(res->ival != i) {
81
+			printf("WARNING: Integer at %ld mutated to %ld! Resetting...\n", i, res->ival);
82
+			res->ival = i;
83
+		}
84
+		return res;
80 85
 	}
81 86
 #endif
82 87
 	res = sol_alloc_object(state);
@@ -315,16 +320,17 @@ sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t
315 320
 	}
316 321
 	sol_list_insert(state, list, 0, key);
317 322
 	sol_list_insert(state, list, 1, state->None);
318
-	if(!dsl_seq_iter_is_invalid(iter)) do {
319
-			sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
320
-			cmp = CALL_METHOD(state, key, cmp, list);
321
-			icmp = sol_cast_int(state, cmp);
322
-			sol_obj_free(cmp);
323
-			if(icmp->ival == 0) {
324
-				res = AS_OBJ(dsl_seq_iter_at(iter));
325
-			}
326
-			sol_obj_free(icmp);
327
-		} while(dsl_seq_iter_next(iter));
323
+	while(!res && !dsl_seq_iter_is_invalid(iter)) {
324
+		sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
325
+		cmp = CALL_METHOD(state, key, cmp, list);
326
+		icmp = sol_cast_int(state, cmp);
327
+		sol_obj_free(cmp);
328
+		if(icmp->ival == 0) {
329
+			res = AS_OBJ(dsl_seq_iter_at(iter));
330
+		}
331
+		sol_obj_free(icmp);
332
+		dsl_seq_iter_next(iter);
333
+	} 
328 334
 	dsl_free_seq_iter(iter);
329 335
 	sol_obj_free(list);
330 336
 	if(res) {

+ 158
- 0
sol-gdb.py View File

@@ -0,0 +1,158 @@
1
+# GDB Sol extensions
2
+
3
+import gdb.printing
4
+import sys
5
+import traceback
6
+
7
+class _CatchExceptions(object):
8
+    def __init__(self):
9
+        self.excs = []
10
+    def print_eidx(self, idx):
11
+        traceback.print_exception(*self.excs[idx])
12
+    def __enter__(self):
13
+        pass
14
+    def __exit__(self, t, v, tb):
15
+        if t is not None:
16
+            self.excs.append((t, v, tb))
17
+guard = _CatchExceptions()
18
+
19
+class DslArray(gdb.Function):
20
+    '''Returns the (DSL_DATATYPE[]) array base of a dsl_array or dsl_seq (if it wraps an array), else NULL'''
21
+
22
+    def __init__(self):
23
+        super(DslArray, self).__init__('dsl_array')
24
+
25
+    def invoke(self, val):
26
+        with guard:
27
+            stype = str(val.type)
28
+            tp = gdb.lookup_type('sol_object_t').pointer()
29
+            if str(val.type).startswith('dsl_seq'):
30
+                if str(val['type']) != 'DSL_SEQ_ARRAY':
31
+                    return gdb.Value(0).cast(tp.pointer())
32
+                val = val['array']
33
+            if str(val.type).startswith('dsl_array'):
34
+                return val['data'].dereference().cast(tp.array(val['len']))
35
+            return gdb.Value(0).cast(tp.pointer())
36
+DslArray.instance = DslArray()
37
+
38
+class DslLen(gdb.Function):
39
+    '''Returns the length of a DSL sequence'''
40
+
41
+    def __init__(self):
42
+        super(DslLen, self).__init__('dsl_array')
43
+
44
+    def invoke(self, val):
45
+        with guard:
46
+            stype = str(val.type)
47
+            if stype.startswith('dsl_seq'):
48
+                return int(gdb.lookup_symbol('dsl_seq_len')[0].value()(val))
49
+            if stype.startswith('dsl_array'):
50
+                return int(gdb.lookup_symbol('dsl_array_len')[0].value()(val))
51
+            if stype.startswith('dsl_list'):
52
+                return int(gdb.lookup_symbol('dsl_list_len')[0].value()(val))
53
+            return -1
54
+DslLen.instance = DslLen()
55
+
56
+class SolObj(gdb.Function):
57
+    '''Casts the argument to a sol_object_t *'''
58
+
59
+    def __init__(self):
60
+        super(SolObj, self).__init__('sol_obj')
61
+
62
+    def invoke(self, val):
63
+        with guard:
64
+            return val.cast(gdb.lookup_type('sol_object_t').pointer())
65
+SolObj.instance = SolObj()
66
+
67
+class SolObjectPrettyPrinter(object):
68
+    STYPE_TO_DISPHINT = {
69
+            'SOL_SINGLET': 'string',
70
+            'SOL_INTEGER': 'number',
71
+            'SOL_FLOAT': 'number',
72
+            'SOL_STRING': 'string',
73
+            'SOL_LIST': 'array',
74
+            'SOL_MAP': 'map',
75
+            'SOL_MCELL': 'map',
76
+            'SOL_FUNCTION': 'function',
77
+            'SOL_CFUNCTION': 'function',
78
+            'SOL_STMT': 'syntax',
79
+            'SOL_EXPR': 'syntax',
80
+    }
81
+
82
+    def __init__(self, obj):
83
+        self.obj = obj
84
+
85
+    def display_hint(self):
86
+        return self.STYPE_TO_DISPHINT.get(str(self.obj['type']), 'string')
87
+
88
+    def to_string(self):
89
+        with guard:
90
+            return getattr(self, 'str_'+str(self.obj['type']), self.str_default)(self.obj)
91
+
92
+    def str_default(self, obj):
93
+        return '<Unknown object %r type %s>'%(obj, str(obj['type']))
94
+
95
+    def str_SOL_SINGLET(self, obj):
96
+        return obj['str']
97
+
98
+    def str_SOL_INTEGER(self, obj):
99
+        return str(obj['ival'])
100
+
101
+    def str_SOL_FLOAT(self, obj):
102
+        return str(obj['fval'])
103
+
104
+    def str_SOL_STRING(self, obj):
105
+        return obj['str']
106
+
107
+    def str_SOL_LIST(self, obj):
108
+        return '[List len=%d]'%(DslLen.instance.invoke(obj['seq']),)
109
+
110
+    def str_SOL_MAP(self, obj):
111
+        return '{Map len=%d}'%(DslLen.instance.invoke(obj['seq']),)
112
+
113
+    def str_SOL_MCELL(self, obj):
114
+        return '<{[%s] = %s}>'%(SolObjectPrettyPrinter(obj['key']).to_string(), SolObjectPrettyPrinter(obj['val']).to_string())
115
+
116
+    def str_SOL_FUNCTION(self, obj):
117
+        return '<Function %s>'%(obj['fname'],)
118
+
119
+    def str_SOL_CFUNCTION(self, obj):
120
+        return '<CFunction %r>'%(obj['cfunc'],)
121
+
122
+    def str_SOL_STMT(self, obj):
123
+        return str(obj['node'].cast(gdb.lookup_type('stmt_node').pointer())['type'])
124
+
125
+    def str_SOL_EXPR(self, obj):
126
+        return str(obj['node'].cast(gdb.lookup_type('expr_node').pointer())['type'])
127
+
128
+    def children(self):
129
+        with guard:
130
+            stype = str(self.obj['type'])
131
+            if stype in ('SOL_LIST', 'SOL_MAP'):
132
+                if str(self.obj['seq']['type']) == 'DSL_SEQ_ARRAY':
133
+                    tp = gdb.lookup_type('sol_object_t').pointer()
134
+                    lseq = DslLen.instance.invoke(self.obj['seq'])
135
+                    arr = self.obj['seq']['array']['data'].dereference().cast(tp.array(lseq))
136
+                    if stype == 'SOL_LIST':
137
+                        return  [(str(i), arr[i]) for i in range(lseq)]
138
+                    else:
139
+                        return sum([[(str(i)+'k', arr[i]['key']), (str(i)+'v', arr[i]['val'])] for i in range(lseq)], [])
140
+            if stype == 'SOL_FUNCTION':
141
+                return [('stmt', self.obj['func'].cast(gdb.lookup_type('stmt_node').pointer))]
142
+            return []
143
+
144
+    @classmethod
145
+    def check_printable(cls, obj):
146
+        with guard:
147
+            stype = str(obj.type)
148
+            if stype.startswith('sol_object_t') or stype.startswith('struct sol_tag_object_t'):
149
+                return cls(obj)
150
+            return None
151
+
152
+# pp = gdb.printing.RegexpCollectionPrettyPrinter('Sol')
153
+# pp.add_printer('sol_object_t', '^sol_object_t.*$', SolObjectPrettyPrinter)
154
+# pp.add_printer('sol_tag_object_t', '^struct sol_tag_object_t.*$', SolObjectPrettyPrinter)
155
+# gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
156
+gdb.current_objfile().pretty_printers.append(SolObjectPrettyPrinter.check_printable)
157
+
158
+print('Sol extensions loaded!')

+ 2
- 2
sol.h View File

@@ -9,8 +9,8 @@
9 9
 #include <stdarg.h>
10 10
 #include "dsl/dsl.h"
11 11
 
12
-#define VERSION "0.1a2"
13
-#define HEXVER 0x0001A02
12
+#define VERSION "0.1a3"
13
+#define HEXVER 0x0001A03
14 14
 
15 15
 #ifndef SOL_ICACHE_MIN
16 16
 #define SOL_ICACHE_MIN -128

Loading…
Cancel
Save