Browse Source

Sol Part 35: Now With More Snakes!

master
Graham Northup 6 years ago
parent
commit
39ca473230
  1. 1
      .gitignore
  2. 57
      builtins.c
  3. 1
      interp.sol
  4. 28
      object.c
  5. 158
      sol-gdb.py
  6. 4
      sol.h

1
.gitignore

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

57
builtins.c

@ -389,24 +389,26 @@ sol_object_t *sol_f_parse(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_ord(sol_state_t *state, sol_object_t *args) {
sol_object_t *arg = sol_list_get_index(state, args, 0), *str = sol_cast_string(state, arg);
sol_object_t *idx = sol_new_int(state, 0), *arg2, *iarg, *res;
sol_object_t *arg2, *iarg, *res;
long idx = 0;
size_t len = strlen(str->str);
sol_obj_free(arg);
if(sol_list_len(state, args) > 1) {
arg2 = sol_list_get_index(state, args, 1);
iarg = sol_cast_int(state, arg2);
sol_obj_free(arg2);
idx->ival = iarg->ival;
idx = iarg->ival;
sol_obj_free(iarg);
}
if(idx->ival < 0 || idx->ival >= len) {
if(idx < 0) {
idx += len;
}
if(idx < 0 || idx >= len) {
sol_obj_free(str);
sol_obj_free(idx);
return sol_set_error_string(state, "Compute ord of out-of-bounds index");
}
res = sol_new_int(state, str->str[idx->ival]);
res = sol_new_int(state, str->str[idx]);
sol_obj_free(str);
sol_obj_free(idx);
return res;
}
@ -905,6 +907,7 @@ sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
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);
sol_object_t *ilow, *ihigh;
long l, h;
size_t len = strlen(str->str), i;
char *s;
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) {
}
sol_obj_free(low);
sol_obj_free(high);
if(ilow->ival < 0) {
ilow->ival += len;
if(ilow->ival < 0) {
ilow->ival = 0;
l = ilow->ival;
h = ihigh->ival;
sol_obj_free(ihigh);
sol_obj_free(ilow);
if(l < 0) {
l += len;
if(l < 0) {
l = 0;
}
}
if(ilow->ival > len) {
ilow->ival = len;
if(l > len) {
l = len;
}
if(ihigh->ival < 0) {
ihigh->ival += len;
if(ihigh->ival < 0) {
ihigh->ival = 0;
if(h < 0) {
h += len;
if(h < 0) {
h = 0;
}
}
if(ihigh->ival > len) {
ihigh->ival = len;
if(h > len) {
h = len;
}
if(ilow->ival >= ihigh->ival) {
sol_obj_free(ilow);
sol_obj_free(ihigh);
if(l >= h) {
sol_obj_free(str);
return sol_new_string(state, "");
}
s = malloc(ihigh->ival - ilow->ival + 1);
for(i = ilow->ival; i < ihigh->ival; i++) {
s[i - ilow->ival] = str->str[i];
s = malloc(h - l + 1);
for(i = l; i < h; i++) {
s[i - l] = str->str[i];
}
s[ihigh->ival - ilow->ival] = '\0';
sol_obj_free(ihigh);
sol_obj_free(ilow);
s[h - l] = '\0';
sol_obj_free(str);
return sol_new_string(state, s);
}

1
interp.sol

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

28
object.c

@ -76,7 +76,12 @@ sol_object_t *sol_new_int(sol_state_t *state, long i) {
sol_object_t *res;
#ifdef SOL_ICACHE
if(!state->icache_bypass && i >= SOL_ICACHE_MIN && i <= SOL_ICACHE_MAX) {
return sol_incref(state->icache[i - SOL_ICACHE_MIN]);
res = sol_incref(state->icache[i - SOL_ICACHE_MIN]);
if(res->ival != i) {
printf("WARNING: Integer at %ld mutated to %ld! Resetting...\n", i, res->ival);
res->ival = i;
}
return res;
}
#endif
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
}
sol_list_insert(state, list, 0, key);
sol_list_insert(state, list, 1, state->None);
if(!dsl_seq_iter_is_invalid(iter)) do {
sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
cmp = CALL_METHOD(state, key, cmp, list);
icmp = sol_cast_int(state, cmp);
sol_obj_free(cmp);
if(icmp->ival == 0) {
res = AS_OBJ(dsl_seq_iter_at(iter));
}
sol_obj_free(icmp);
} while(dsl_seq_iter_next(iter));
while(!res && !dsl_seq_iter_is_invalid(iter)) {
sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
cmp = CALL_METHOD(state, key, cmp, list);
icmp = sol_cast_int(state, cmp);
sol_obj_free(cmp);
if(icmp->ival == 0) {
res = AS_OBJ(dsl_seq_iter_at(iter));
}
sol_obj_free(icmp);
dsl_seq_iter_next(iter);
}
dsl_free_seq_iter(iter);
sol_obj_free(list);
if(res) {

158
sol-gdb.py

@ -0,0 +1,158 @@
# GDB Sol extensions
import gdb.printing
import sys
import traceback
class _CatchExceptions(object):
def __init__(self):
self.excs = []
def print_eidx(self, idx):
traceback.print_exception(*self.excs[idx])
def __enter__(self):
pass
def __exit__(self, t, v, tb):
if t is not None:
self.excs.append((t, v, tb))
guard = _CatchExceptions()
class DslArray(gdb.Function):
'''Returns the (DSL_DATATYPE[]) array base of a dsl_array or dsl_seq (if it wraps an array), else NULL'''
def __init__(self):
super(DslArray, self).__init__('dsl_array')
def invoke(self, val):
with guard:
stype = str(val.type)
tp = gdb.lookup_type('sol_object_t').pointer()
if str(val.type).startswith('dsl_seq'):
if str(val['type']) != 'DSL_SEQ_ARRAY':
return gdb.Value(0).cast(tp.pointer())
val = val['array']
if str(val.type).startswith('dsl_array'):
return val['data'].dereference().cast(tp.array(val['len']))
return gdb.Value(0).cast(tp.pointer())
DslArray.instance = DslArray()
class DslLen(gdb.Function):
'''Returns the length of a DSL sequence'''
def __init__(self):
super(DslLen, self).__init__('dsl_array')
def invoke(self, val):
with guard:
stype = str(val.type)
if stype.startswith('dsl_seq'):
return int(gdb.lookup_symbol('dsl_seq_len')[0].value()(val))
if stype.startswith('dsl_array'):
return int(gdb.lookup_symbol('dsl_array_len')[0].value()(val))
if stype.startswith('dsl_list'):
return int(gdb.lookup_symbol('dsl_list_len')[0].value()(val))
return -1
DslLen.instance = DslLen()
class SolObj(gdb.Function):
'''Casts the argument to a sol_object_t *'''
def __init__(self):
super(SolObj, self).__init__('sol_obj')
def invoke(self, val):
with guard:
return val.cast(gdb.lookup_type('sol_object_t').pointer())
SolObj.instance = SolObj()
class SolObjectPrettyPrinter(object):
STYPE_TO_DISPHINT = {
'SOL_SINGLET': 'string',
'SOL_INTEGER': 'number',
'SOL_FLOAT': 'number',
'SOL_STRING': 'string',
'SOL_LIST': 'array',
'SOL_MAP': 'map',
'SOL_MCELL': 'map',
'SOL_FUNCTION': 'function',
'SOL_CFUNCTION': 'function',
'SOL_STMT': 'syntax',
'SOL_EXPR': 'syntax',
}
def __init__(self, obj):
self.obj = obj
def display_hint(self):
return self.STYPE_TO_DISPHINT.get(str(self.obj['type']), 'string')
def to_string(self):
with guard:
return getattr(self, 'str_'+str(self.obj['type']), self.str_default)(self.obj)
def str_default(self, obj):
return '<Unknown object %r type %s>'%(obj, str(obj['type']))
def str_SOL_SINGLET(self, obj):
return obj['str']
def str_SOL_INTEGER(self, obj):
return str(obj['ival'])
def str_SOL_FLOAT(self, obj):
return str(obj['fval'])
def str_SOL_STRING(self, obj):
return obj['str']
def str_SOL_LIST(self, obj):
return '[List len=%d]'%(DslLen.instance.invoke(obj['seq']),)
def str_SOL_MAP(self, obj):
return '{Map len=%d}'%(DslLen.instance.invoke(obj['seq']),)
def str_SOL_MCELL(self, obj):
return '<{[%s] = %s}>'%(SolObjectPrettyPrinter(obj['key']).to_string(), SolObjectPrettyPrinter(obj['val']).to_string())
def str_SOL_FUNCTION(self, obj):
return '<Function %s>'%(obj['fname'],)
def str_SOL_CFUNCTION(self, obj):
return '<CFunction %r>'%(obj['cfunc'],)
def str_SOL_STMT(self, obj):
return str(obj['node'].cast(gdb.lookup_type('stmt_node').pointer())['type'])
def str_SOL_EXPR(self, obj):
return str(obj['node'].cast(gdb.lookup_type('expr_node').pointer())['type'])
def children(self):
with guard:
stype = str(self.obj['type'])
if stype in ('SOL_LIST', 'SOL_MAP'):
if str(self.obj['seq']['type']) == 'DSL_SEQ_ARRAY':
tp = gdb.lookup_type('sol_object_t').pointer()
lseq = DslLen.instance.invoke(self.obj['seq'])
arr = self.obj['seq']['array']['data'].dereference().cast(tp.array(lseq))
if stype == 'SOL_LIST':
return [(str(i), arr[i]) for i in range(lseq)]
else:
return sum([[(str(i)+'k', arr[i]['key']), (str(i)+'v', arr[i]['val'])] for i in range(lseq)], [])
if stype == 'SOL_FUNCTION':
return [('stmt', self.obj['func'].cast(gdb.lookup_type('stmt_node').pointer))]
return []
@classmethod
def check_printable(cls, obj):
with guard:
stype = str(obj.type)
if stype.startswith('sol_object_t') or stype.startswith('struct sol_tag_object_t'):
return cls(obj)
return None
# pp = gdb.printing.RegexpCollectionPrettyPrinter('Sol')
# pp.add_printer('sol_object_t', '^sol_object_t.*$', SolObjectPrettyPrinter)
# pp.add_printer('sol_tag_object_t', '^struct sol_tag_object_t.*$', SolObjectPrettyPrinter)
# gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
gdb.current_objfile().pretty_printers.append(SolObjectPrettyPrinter.check_printable)
print('Sol extensions loaded!')

4
sol.h

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

Loading…
Cancel
Save