def s_core_hashmap_get(env, hashmap, *key_ret_val): """ if *key is more than 1, than first is key, second is the return value if not found """ k_len = len(key_ret_val) if k_len < 1: raise Exception( 'hashmap get needs key as second parameter, optional not found return value as third parameter' ) elif k_len == 1: key = key_ret_val[0] ret_value = types.SNilObject.instance() else: key = key_ret_val[0] ret_value = key_ret_val[1] if len(hashmap) < 2: raise Exception('The first parameter is not a hash map') values_count = len(hashmap[1]) for i in range(len(hashmap[0])): k = hashmap[0][i] if values_count <= i: return types.SResult(env, ret_value) if k.equal(key): return types.SResult(env, hashmap[1][i]) return types.SResult(env, ret_value)
def s_minus(env, *items): if len(items) == 0: return types.SResult(env, types.SNumber(0)) s = items[0].value for item in items[1:]: s -= item.value return types.SResult(env, types.SNumber(s))
def s_equal(env, *items): count = len(items) if count == 0 or count == 1: return types.SResult(env, types.SBoolean(True)) for i in range(count - 1): if not items[i].equal(items[i + 1]): return types.SResult(env, types.SBoolean(False)) return types.SResult(env, types.SBoolean(True))
def s_core_and(env, *items): res = types.SBoolean(True) for item in items: if not item.to_boolean(): return types.SResult(env, types.SBoolean(False)) else: res = item return types.SResult(env, res)
def s_core_less(env, *items): count = len(items) if count <= 1: return types.SResult(env, types.SBoolean(True)) else: for i in range(count - 1): if items[i].value >= items[i + 1].value: return types.SResult(env, types.SBoolean(False)) return types.SResult(env, types.SBoolean(True))
def s_core_do(env, *items): final_ret = types.SNilObject.instance() for item in items: result = item.realize(env) env = result.env final_ret = result.ret return types.SResult(env, final_ret)
def s_core_map(env, fn, items): l = types.SList() for item in items: result = types.SCallable.call_procedure(fn, env, [item]) env = result.env l.add(result.ret) return types.SResult(env, l)
def s_core_set_parent(env, name, value): if env.parent and env.parent.parent: env.parent.parent.bind(str(name), value) elif env.parent: env.parent.bind(str(name), value) else: env.bind(str(name), value) return types.SResult(env, value)
def s_core_define(env, name, value): """ bind to root env name: string value: SObject """ env.bind_to_root(str(name), value) return types.SResult(env, value)
def s_core_hashmap_from_list(env, key_list, value_list): """ scheme 的hashmap暂时用list(key_list, value_list)的形式表示。 将来打算再写一个SHashMap的类做这个功能 """ l = types.SList() l.add(key_list) l.add(value_list) return types.SResult(env, l)
def s_cons2(env, *items): seq = types.SList() import copy list = items[-1] items = items[:-1] seq.items = copy.copy(list.items) for i in range(len(items)): item = items[i] seq.items.insert(i, item) return types.SResult(env, seq)
def s_core_set(env, name, value): """ bind to the parent env of current env name: string value: SObject """ if env.parent is not None: env.parent.bind(str(name), value) else: env.bind(str(name), value) return types.SResult(env, value)
def s_core_if(env, pred, *items): if len(items) == 0 or len(items) > 2: raise Exception("if statement only accept 2 or 3 params") pred_result = pred.realize(env) env = pred_result.env if pred_result.ret.to_boolean(): body = items[0] return body.realize(env) else: if len(items) == 1: return types.SResult(env, types.SNilObject.instance()) else: body = items[1] return body.realize(env)
def s_cons(env, head, tail): seq = types.SList() seq.add(head) seq.add(tail) return types.SResult(env, seq)
def s_core_or(env, *items): for item in items: if item.to_boolean(): return types.SResult(env, item) return types.SResult(env, types.SBoolean(False))
def s_display(env, *values): for value in values: print value, return types.SResult(env, types.SNilObject.instance())
def s_core_type(env, value): return types.SResult(env, types.SString.value_of(value.typename))
def s_newline(env): print "\n", return types.SResult(env, types.SNilObject.instance())
def s_list_nth(env, seq, n): if len(seq) < n.value: raise Exception("%s has only %d items, index %d out of range" % (seq, len(seq), n.value)) item = seq[n.value] return types.SResult(env, item)
def s_core_up_env(env): env = env.up() return types.SResult(env, types.SNilObject.instance())
def s_core_macro(env, params, body): param_items = params if isinstance(params, types.SList): param_items = params.items macro = types.SMacro(param_items, body) return types.SResult(env, macro)
def s_core_lambda(env, params, body): param_items = params if isinstance(params, types.SList): param_items = params.items fn = types.SFunc(param_items, body) return types.SResult(env, fn)
def s_core_retrieve(env, sym): val = env.find(sym.to_str()) return types.SResult(env, val)
def s_print_env(env): print env.parent return types.SResult(env, types.SNilObject.instance())
def s_list(env, *items): seq = types.SList() for item in items: seq.add(item) return types.SResult(env, seq)
def s_core_print_locals(env): """ print the current name=>value map in env """ print env.parent.current return types.SResult(env, types.SNilObject.instance())
def s_list_len(env, seq): return types.SResult(env, types.SNumber(len(seq)))
def s_core_id(env, value): """ return value itself """ return types.SResult(env, value)
def s_core_down_env(env): env = env.down() return types.SResult(env, types.SNilObject.instance())
def s_core_str_sym(env, value): s = types.SString.value_of(value.str) return types.SResult(env, s)