def string_on_predicate1(compiler, cont, test): '''return current char and step if @test succeed, where @test: a python function with one argument, which tests on one char and return True or False @test must be registered with register_function''' test = test.interlang() text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) length = compiler.new_var(il.ConstLocalVar('length')) p = compiler.new_var(il.LocalVar('p')) if not isinstance(test, il.PyFunction): raise DaoCompileTypeError(test) return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.If(il.Ge(pos, length), il.failcont(il.FALSE), il.If(il.Call(test, il.GetItem(text, pos)), il.begin( il.Assign(p, il.add(pos, il.Integer(1))), il.While(il.And(il.Lt(p, length), il.Call(test, il.GetItem(text, p))), il.AddAssign(p, il.Integer(1))), il.SetParseState(il.Tuple(text, p)), il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), cont(il.GetItem(text, il.Slice2(pos, p)))), il.failcont(il.FALSE)))))
def or2_fun(compiler, cont, clause1, clause2): v = compiler.new_var(il.ConstLocalVar('v')) v1 = compiler.new_var(il.ConstLocalVar('v')) v2 = compiler.new_var(il.ConstLocalVar('v')) parse_state = compiler.new_var(il.ConstLocalVar('parse_state')) bindings = compiler.new_var(il.LocalVar('bindings')) fc = compiler.new_var(il.ConstLocalVar('old_failcont')) if has_cut_or(clause1) or has_cut_or(clause2): cut_or_cont = compiler.new_var(il.ConstLocalVar('cut_or_cont')) or_cont = il.clamda(v, il.SetCutOrCont(cut_or_cont), cont(v)) return il.begin( il.Assign(cut_or_cont, il.cut_or_cont), il.Assign(parse_state, il.parse_state), il.Assign(bindings, il.Copy(il.bindings)), il.Assign(fc, il.failcont), il.SetCutOrCont(il.clamda(v2, il.Assign(il.parse_state, parse_state), il.SetBindings(bindings), fc(il.FALSE))), il.SetFailCont(il.clamda(v1, il.SetFailCont(fc), clause2.cps(compiler, or_cont))), clause1.cps(compiler, or_cont)) else: return il.begin( il.Assign(fc, il.failcont), il.SetFailCont(il.clamda(v1, il.SetFailCont(fc), clause2.cps(compiler, cont))), clause1.cps(compiler, cont))
def integer(compiler, cont, arg): '''integer''' text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) p = compiler.new_var(il.LocalVar('p')) length = compiler.new_var(il.ConstLocalVar('length')) if isinstance(arg, Var): arg = arg.interlang() x = compiler.new_var(il.ConstLocalVar('x')) return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.If(il.Ge(pos, length), il.failcont(il.FALSE), il.If(il.Not(il.Cle(il.String('0'), il.GetItem(text, pos), il.String('9'))), il.failcont(il.FALSE), il.Begin(( il.Assign(p, il.add(pos, il.Integer(1))), il.while_(il.And(il.Lt(p, length), il.Cle(il.String('0'),il.GetItem(text, p),il.String('9'))), il.AddAssign(p, il.Integer(1))), il.Assign(x, il.Deref(arg)), il.If(il.IsLogicVar(x), il.begin(il.SetParseState(il.Tuple(text, p)), il.SetBinding(x, il.GetItem(text, il.Slice2(pos, p))), il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos)), il.DelBinding(x)), cont(il.GetItem(text, pos))), il.If(il.Isinstance(x, il.String('str')), il.If(il.Eq(x, il.GetItem(text, il.Slice2(pos, p))), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(il.GetItem(text, pos))), il.failcont(il.NONE)), il.RaiseTypeError(x))))))))) elif isinstance(arg, il.String): return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.If(il.Ge(pos, length), il.failcont(il.FALSE), il.If(il.Not(il.Cle(il.String('0'), il.GetItem(text, pos), il.String('9'))), il.failcont(il.FALSE), il.Begin(( il.Assign(p, il.add(pos, il.Integer(1))), il.while_(il.And(il.Lt(p, length), il.Cle(il.String('0'),il.GetItem(text, p),il.String('9'))), il.AddAssign(p, il.Integer(1))), il.If(il.Eq(arg, il.GetItem(text, il.Slice2(pos, p))), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(arg)), il.failcont(il.NONE)))))))) else: raise CompileTypeError
def literal(compiler, cont, arg): '''any given instance string''' text = compiler.new_var(il.ConstLocalVar('text')) pos = compiler.new_var(il.ConstLocalVar('pos')) p = compiler.new_var(il.LocalVar('p')) i = compiler.new_var(il.LocalVar('i')) x = compiler.new_var(il.ConstLocalVar('x')) length = compiler.new_var(il.ConstLocalVar('length')) length2 = compiler.new_var(il.ConstLocalVar('length2')) if isinstance(arg, Var): return il.Begin(( il.Assign(x, il.Deref(arg)), il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.Assign(length, il.Len(x)), il.Assign(i, il.Integer(0)), il.Assign(p, pos), il.while_(il.and_(il.Lt(i, length2), il.Lt(p, length), il.Eq(il.GetItem(text, p), il.GetItem(x, i))), il.AddAssign(p, il.Integer(1))), il.If(il.Lt(i, length2), il.failcont(il.NONE), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(arg))))) elif isinstance(arg, String): arg = arg.interlang() return il.Begin(( il.AssignFromList(text, pos, il.parse_state), il.Assign(length, il.Len(text)), il.Assign(length2, il.Len(arg)), il.Assign(i, il.Integer(0)), il.Assign(p, pos), il.while_(il.and_(il.Lt(i, length2), il.Lt(p, length), il.Eq(il.GetItem(text, p), il.GetItem(arg, i))), il.AddAssign(p, il.Integer(1)), il.AddAssign(i, il.Integer(1)), ), il.If(il.Lt(i, length2), il.failcont(il.NONE), il.begin(il.append_failcont(compiler, il.SetParseState(il.Tuple(text, pos))), il.SetParseState(il.Tuple(text, p)), cont(arg))))) else: raise CompileTypeError
def catch(compiler, cont, tag, *form): v = compiler.new_var(il.ConstLocalVar('v')) v2 = compiler.new_var(il.ConstLocalVar('v')) k = compiler.new_var(il.LocalVar('cont')) return tag.cps( compiler, il.clamda(v, il.Assign(k, il.clamda(v2, cont(v2))), il.PushCatchCont(v, k), begin(*form).cps(compiler, cont)))
def quasiquote(self, compiler, cont): result = compiler.new_var(il.LocalVar('result')) vars = tuple(compiler.new_var(il.ConstLocalVar('a'+repr(i))) for i in range(len(self.args))) body = (il.Assign(result, il.empty_list),)+tuple( il.If(il.Isinstance(var, il.Klass('UnquoteSplice')), il.AddAssign(result, il.Call(il.Symbol('list'), il.Attr(var, il.Symbol('item')))), il.ListAppend(result, var), ) for var in vars)+( cont(il.Call(il.Klass(self.__class__.__name__), il.QuoteItem(self.function), il.MakeTuple(result))),) fun = il.begin(*body) for var, arg in reversed(zip(vars, self.args)): fun = arg.quasiquote(compiler, il.clamda(var, fun)) return fun
def wrap_cut(compiler, cont, exp): cut_cont = il.ConstLocalVar('cut_cont') v = il.ConstLocalVar('v') v1 = compiler.new_var(il.ConstLocalVar('v')) v2 = compiler.new_var(il.ConstLocalVar('v')) parse_state = compiler.new_var(il.ConstLocalVar('parse_state')) bindings = compiler.new_var(il.LocalVar('bindings')) fc = compiler.new_var(il.ConstLocalVar('old_failcont')) return il.begin( il.Assign(cut_cont, il.cut_cont), il.Assign(parse_state, il.parse_state), il.Assign(bindings, il.Copy(il.bindings)), il.Assign(fc, il.failcont), il.SetCutCont(il.clamda(v2, il.Assign(il.parse_state, parse_state), il.SetBindings(bindings), fc(il.FALSE))), il.SetFailCont(il.clamda(v1, il.SetFailCont(fc), il.Assign(il.cut_cont, cut_cont), fc(il.FALSE))), exp.cps(compiler, il.clamda(v, il.Assign(il.cut_cont, cut_cont), cont(v))))