コード例 #1
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_or(me, pattern, peg, result, stream, failure, tail, peg_args):
        data = ""
        success = gensym("success")
        for pattern in pattern.patterns:
            # TODO: lazily create this
            out = gensym("or")
            my_result = newResult()
            fail = lambda : "goto %s;" % out
            if pattern == pattern.patterns[-1]:
                fail = failure
            data += """
{
Result %(new-result)s(%(result)s.getPosition());
%(code)s
%(result)s = %(new-result)s;
}
goto %(success)s;
%(out)s:
""" % {'new-result': my_result,
       'result': result,
       'code': pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip(),
       'success': success,
       'out': out}
        data += "%s:\n" % success
        return data
コード例 #2
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_or(me, pattern, peg, result, stream, failure, tail, peg_args):
        data = ""
        success = gensym("success")
        for pattern in pattern.patterns:
            # TODO: lazily create this
            out = gensym("or")
            my_result = newResult()
            fail = lambda: "goto %s;" % out
            if pattern == pattern.patterns[-1]:
                fail = failure
            data += """
{
Result %(new-result)s(%(result)s.getPosition());
%(code)s
%(result)s = %(new-result)s;
}
goto %(success)s;
%(out)s:
""" % {
                'new-result':
                my_result,
                'result':
                result,
                'code':
                pattern.generate_cpp(peg, my_result, stream, fail, tail,
                                     peg_args).strip(),
                'success':
                success,
                'out':
                out
            }
        data += "%s:\n" % success
        return data
コード例 #3
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_repeat_many(me, pattern, peg, result, stream, failure, tail,
                             peg_args):
        loop_done = gensym("loop")
        my_fail = lambda: "goto %s;" % loop_done
        my_result = newResult()
        data = """
%(result)s.reset();
do{
    Result %(new-result)s(%(result)s.getPosition());
    %(code)s
    %(result)s.addResult(%(new-result)s);
} while (true);
%(loop-done)s:
;
        """ % {
            'result':
            result,
            'new-result':
            my_result,
            'code':
            indent(
                pattern.next.generate_cpp(peg, my_result, stream, my_fail,
                                          tail, peg_args).strip()),
            'loop-done':
            loop_done
        }
        return data
コード例 #4
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_not(me, pattern, peg, result, stream, failure, tail,
                     peg_args):
        not_label = gensym("not")
        my_result = newResult()
        my_fail = lambda: "goto %s;" % not_label
        data = """
Result %(new-result)s(%(result)s);
%(code)s
%(fail)s
%(not)s:
%(result)s.setValue(Value((void*)0));
        """ % {
            'new-result':
            my_result,
            'result':
            result,
            'code':
            pattern.next.generate_cpp(peg, my_result, stream, my_fail, None,
                                      peg_args).strip(),
            'fail':
            failure(),
            'not':
            not_label,
            'result':
            result
        }

        return data
コード例 #5
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
            def newPattern(pattern, stream, result, success):
                # my_result = newResult()
                previous_position = gensym('position')
                out = [False]
                def label(n):
                    if n != False:
                        return "%s:" % n
                    return ""

                def fail():
                    if out[0] == False:
                        out[0] = newOut()
                    return "%s.setPosition(%s);\ngoto %s;" % (result, previous_position, out[0])
                # pattern_result = pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip()

                data = """
{
    int %(previous)s = %(result)s.getPosition();
    %(code)s
}
%(success)s
%(label)s
""" % {'previous': previous_position,
       'result': result,
       'code': indent(pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)),
       'success': success,
       'label': label(out[0])}
                return data
コード例 #6
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_bind(me, pattern, peg, result, stream, failure, tail,
                      peg_args):
        if pattern.pattern.isLineInfo():
            name = gensym("line_info")
            data = """
Stream::LineInfo %(name)s = %(stream)s.getLineInfo(%(result)s.getPosition());
%(variable)s = &%(name)s;
""" % {
                'name': name,
                'stream': stream,
                'result': result,
                'variable': pattern.variable
            }
        else:
            data = """
%(code)s
%(variable)s = %(result)s.getValues();
""" % {
                'code':
                pattern.pattern.generate_cpp(peg, result, stream, failure,
                                             tail, peg_args).strip(),
                'variable':
                pattern.variable,
                'result':
                result
            }
        return data
コード例 #7
0
    def generate_any(me, pattern, result, previous_result, stream, failure):
        temp = gensym()
        data = """
%s = %s.get(%s.getPosition())
if %s != chr(0):
    %s.setValue(%s)
    %s.nextPosition()
else:
    %s
""" % (temp, stream, result, temp, result, temp, result, indent(failure()))
        return data
コード例 #8
0
    def generate_any(me, pattern, result, previous_result, stream, failure):
        temp = gensym()
        data = """
%s = %s.get(%s.getPosition())
if %s != chr(0):
    %s.setValue(%s)
    %s.nextPosition()
else:
    %s
""" % (temp, stream, result, temp, result, temp, result, indent(failure()))
        return data
コード例 #9
0
    def generate_range(me, pattern, result, previous_result, stream, failure):
        letter = gensym("letter")
        data = """
%s = %s.get(%s.getPosition())
if '%s'.index(%s) != nil then
    %s.nextPosition()
    %s.setValue(%s)
else
    %s
end
""" % (letter, stream, result, pattern.range, letter, result, result, letter, indent(failure()))
        return data
コード例 #10
0
    def generate_range(me, pattern, result, previous_result, stream, failure):
        letter = gensym("letter")
        data = """
%s = %s.get(%s.getPosition())
if %s in '%s':
    %s.nextPosition()
    %s.setValue(%s)
else:
    %s
""" % (letter, stream, result, letter, pattern.range, result, result, letter, indent(failure()))

        return data
コード例 #11
0
    def generate_maybe(me, pattern, result, previous_result, stream, failure):
        save = gensym("save")
        fail = lambda : """raise PegError"""
        data = """
try:
    %s = %s.getPosition()
    %s
except PegError:
    %s = Result(%s)
    %s.setValue(None)
""" % (save, result, indent(pattern.pattern.generate_python(result, previous_result, stream, fail)), result, save, result)
        return data
コード例 #12
0
    def generate_maybe(me, pattern, result, previous_result, stream, failure):
        save = gensym("save")
        fail = lambda : """
%s = Result.new(%s)
%s.setValue(nil)
""" % (result, save, result)

        data = """
%s = %s.getPosition()
%s
""" % (save, result, pattern.pattern.generate_v1(me, result, previous_result, stream, fail))
        return data
コード例 #13
0
    def generate_range(me, pattern, result, previous_result, stream, failure):
        letter = gensym("letter")
        data = """
%s = %s.get(%s.getPosition())
if '%s'.index(%s) != nil then
    %s.nextPosition()
    %s.setValue(%s)
else
    %s
end
""" % (letter, stream, result, pattern.range, letter, result, result, letter,
        indent(failure()))
        return data
コード例 #14
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_maybe(me, pattern, peg, result, stream, failure, tail,
                       peg_args):
        save = gensym("save")
        fail = lambda: """
%s = Result(%s);
%s.setValue(Value((void*) 0));
""" % (result, save, result)
        data = """
int %s = %s.getPosition();
%s
""" % (save, result,
        pattern.pattern.generate_cpp(peg, result, stream, fail, tail, peg_args))
        return data
コード例 #15
0
    def generate_maybe(me, pattern, result, previous_result, stream, failure):
        save = gensym("save")
        fail = lambda: """
%s = Result(%s)
%s.setValue(None)
""" % (result, save, result)

        data = """
%s = %s.getPosition()
%s
""" % (save, result,
        pattern.pattern.generate_python(result, previous_result, stream, fail))
        return data
コード例 #16
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_any(me, pattern, peg, result, stream, failure, tail,
                     peg_args):
        temp = gensym()
        data = """
char %s = %s.get(%s.getPosition());
if (%s != '\\0'){
    %s.setValue(Value((void*) (long) %s));
    %s.nextPosition();
} else {
    %s
}
""" % (temp, stream, result, temp, result, temp, result, indent(failure()))
        return data
コード例 #17
0
    def generate_range(me, pattern, result, previous_result, stream, failure):
        letter = gensym("letter")
        data = """
%s = %s.get(%s.getPosition())
if %s in '%s':
    %s.nextPosition()
    %s.setValue(%s)
else:
    %s
""" % (letter, stream, result, letter, pattern.range, result, result, letter,
        indent(failure()))

        return data
コード例 #18
0
    def generate_or(me, pattern, result, previous_result, stream, failure):
        data = ""
        fail = failure
        save = gensym("save")
        for next_pattern in pattern.patterns[::-1]:
            data = """
%s = Result(%s)
%s
""" % (result, save, next_pattern.generate_python(result, previous_result, stream, fail).strip())
            fail = lambda : data
        return """
%s = %s.getPosition()
%s
""" % (save, result, data)
コード例 #19
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_or(me, pattern, peg, result, stream, failure, tail, peg_args):
        data = ""
        success = gensym("success")
        for pattern in pattern.patterns:
            # TODO: lazily create this
            out = gensym("or")
            my_result = newResult()
            fail = lambda: "goto %s;" % out
            if pattern == pattern.patterns[-1]:
                fail = failure
            data += """
{
Result %s(%s.getPosition());
%s
%s = %s;
}
goto %s;
%s:
""" % (my_result, result,
            pattern.generate_cpp(peg, my_result, stream, fail, tail,
                            peg_args).strip(), result, my_result, success, out)
        data += "%s:\n" % success
        return data
コード例 #20
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_any(me, pattern, peg, result, stream, failure, tail, peg_args):
        data = """
char %(temp)s = %(stream)s.get(%(result)s.getPosition());
if (%(temp)s != '\\0'){
    %(result)s.setValue(Value((void*) (long) %(temp)s));
    %(result)s.nextPosition();
} else {
    %(fail)s
}
""" % {'temp': gensym(),
       'stream': stream,
       'result': result,
       'fail': indent(failure())}
        return data
コード例 #21
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_range(me, pattern, peg, result, stream, failure, tail,
                       peg_args):
        letter = gensym("letter")
        data = """
char %s = %s.get(%s.getPosition());
if (%s != '\\0' && strchr("%s", %s) != NULL){
    %s.nextPosition();
    %s.setValue(Value((void*) (long) %s));
} else {
    %s
}
""" % (letter, stream, result, letter, pattern.range, letter, result, result,
        letter, indent(failure()))
        return data
コード例 #22
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_maybe(me, pattern, peg, result, stream, failure, tail, peg_args):
        save = gensym("save")
        fail = lambda: """
%(result)s = Result(%(save)s);
%(result)s.setValue(Value((void*) 0));
""" % {'result': result,
       'save': save}

        data = """
int %(save)s = %(result)s.getPosition();
%(code)s
""" % {'save': save,
       'result': result,
       'code': pattern.pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)}
        return data
コード例 #23
0
    def generate_maybe(me, pattern, result, previous_result, stream, failure):
        save = gensym("save")
        fail = lambda: """raise PegError"""
        data = """
try:
    %s = %s.getPosition()
    %s
except PegError:
    %s = Result(%s)
    %s.setValue(None)
""" % (save, result,
        indent(
           pattern.pattern.generate_python(result, previous_result, stream,
                                           fail)), result, save, result)
        return data
コード例 #24
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_range(me, pattern, peg, result, stream, failure, tail, peg_args):
        letter = gensym("letter")
        data = """
char %(letter)s = %(stream)s.get(%(result)s.getPosition());
if (%(letter)s != '\\0' && strchr("%(range)s", %(letter)s) != NULL){
    %(result)s.nextPosition();
    %(result)s.setValue(Value((void*) (long) %(letter)s));
} else {
    %(failure)s
}
""" % {'letter': letter,
       'stream': stream,
       'result': result,
       'range': pattern.range,
       'failure': indent(failure())}
        return data
コード例 #25
0
    def generate_or(me, pattern, result, previous_result, stream, failure):
        data = ""
        fail = failure
        save = gensym("save")
        for next_pattern in pattern.patterns[::-1]:
            data = """
%s = Result(%s)
%s
""" % (result, save,
            next_pattern.generate_python(result, previous_result, stream,
                                    fail).strip())
            fail = lambda: data
        return """
%s = %s.getPosition()
%s
""" % (save, result, data)
コード例 #26
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_bind(me, pattern, peg, result, stream, failure, tail,
                      peg_args):
        if pattern.pattern.isLineInfo():
            name = gensym("line_info")
            data = """
Stream::LineInfo %s = %s.getLineInfo(%s.getPosition());
%s = &%s;
""" % (name, stream, result, pattern.variable, name)
        else:
            data = """
%s
%s = %s.getValues();
""" % (pattern.pattern.generate_cpp(
                peg, result, stream, failure, tail,
                peg_args).strip(), pattern.variable, result)
        return data
コード例 #27
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_any(me, pattern, peg, result, stream, failure, tail,
                     peg_args):
        data = """
char %(temp)s = %(stream)s.get(%(result)s.getPosition());
if (%(temp)s != '\\0'){
    %(result)s.setValue(Value((void*) (intptr_t) %(temp)s));
    %(result)s.nextPosition();
} else {
    %(fail)s
}
""" % {
            'temp': gensym(),
            'stream': stream,
            'result': result,
            'fail': indent(failure())
        }
        return data
コード例 #28
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_not(me, pattern, peg, result, stream, failure, tail,
                     peg_args):
        not_label = gensym("not")
        my_result = newResult()
        my_fail = lambda: "goto %s;" % not_label
        data = """
Result %s(%s);
%s
%s
%s:
%s.setValue(Value((void*)0));
        """ % (my_result, result,
               pattern.next.generate_cpp(
                   peg, my_result, stream, my_fail, None,
                   peg_args).strip(), failure(), not_label, result)

        return data
コード例 #29
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_repeat_many(me, pattern, peg, result, stream, failure, tail, peg_args):
        loop_done = gensym("loop")
        my_fail = lambda: "goto %s;" % loop_done
        my_result = newResult()
        data = """
%(result)s.reset();
do{
    Result %(new-result)s(%(result)s.getPosition());
    %(code)s
    %(result)s.addResult(%(new-result)s);
} while (true);
%(loop-done)s:
;
        """ % {'result': result,
               'new-result': my_result,
               'code': indent(pattern.next.generate_cpp(peg, my_result, stream, my_fail, tail, peg_args).strip()),
               'loop-done': loop_done}
        return data
コード例 #30
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_not(me, pattern, peg, result, stream, failure, tail, peg_args):
        not_label = gensym("not")
        my_result = newResult()
        my_fail = lambda : "goto %s;" % not_label
        data = """
Result %(new-result)s(%(result)s);
%(code)s
%(fail)s
%(not)s:
%(result)s.setValue(Value((void*)0));
        """ % {'new-result': my_result,
               'result': result,
               'code': pattern.next.generate_cpp(peg, my_result, stream, my_fail, None, peg_args).strip(),
               'fail': failure(),
               'not': not_label,
               'result': result}

        return data
コード例 #31
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_bind(me, pattern, peg, result, stream, failure, tail, peg_args):
        if pattern.pattern.isLineInfo():
            name = gensym("line_info");
            data = """
Stream::LineInfo %(name)s = %(stream)s.getLineInfo(%(result)s.getPosition());
%(variable)s = &%(name)s;
""" % {'name': name,
       'stream': stream,
       'result': result,
       'variable': pattern.variable}
        else:
            data = """
%(code)s
%(variable)s = %(result)s.getValues();
""" % {'code': pattern.pattern.generate_cpp(peg, result, stream, failure, tail, peg_args).strip(),
       'variable': pattern.variable,
       'result': result}
        return data
コード例 #32
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_range(me, pattern, peg, result, stream, failure, tail,
                       peg_args):
        letter = gensym("letter")
        data = """
char %(letter)s = %(stream)s.get(%(result)s.getPosition());
if (%(letter)s != '\\0' && strchr("%(range)s", %(letter)s) != NULL){
    %(result)s.nextPosition();
    %(result)s.setValue(Value((void*) (intptr_t) %(letter)s));
} else {
    %(failure)s
}
""" % {
            'letter': letter,
            'stream': stream,
            'result': result,
            'range': pattern.range,
            'failure': indent(failure())
        }
        return data
コード例 #33
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
            def newPattern(pattern, stream, result, success):
                my_result = newResult()
                previous_position = gensym('position')
                out = [False]

                def label(n):
                    if n != False:
                        return "%s:" % n
                    return ""

                def fail():
                    if out[0] == False:
                        out[0] = newOut()
                    return "%s.setPosition(%s);\ngoto %s;" % (
                        result, previous_position, out[0])

                pattern_result = pattern.generate_cpp(peg, my_result, stream,
                                                      fail, tail,
                                                      peg_args).strip()

                old_data = """
{
Result %s(%s.getPosition());
%s
%s = %s;
}
%s
%s
                """ % (my_result, result, pattern_result, result, my_result,
                       success, label(out[0]))

                data = """
{
    int %s = %s.getPosition();
    %s
}
%s
%s
""" % (previous_position, result,
                indent(pattern.generate_cpp(peg, result, stream, fail, tail,
                                   peg_args)), success, label(out[0]))
                return data
コード例 #34
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_repeat_many(me, pattern, peg, result, stream, failure, tail,
                             peg_args):
        loop_done = gensym("loop")
        my_fail = lambda: "goto %s;" % loop_done
        my_result = newResult()
        data = """
%s.reset();
do{
    Result %s(%s.getPosition());
    %s
    %s.addResult(%s);
} while (true);
%s:
;
        """ % (result, my_result, result,
               indent(
                   pattern.next.generate_cpp(
                       peg, my_result, stream, my_fail, tail,
                       peg_args).strip()), result, my_result, loop_done)
        return data
コード例 #35
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
            def newPattern(pattern, stream, result, success):
                # my_result = newResult()
                previous_position = gensym('position')
                out = [False]

                def label(n):
                    if n != False:
                        return "%s:" % n
                    return ""

                def fail():
                    if out[0] == False:
                        out[0] = newOut()
                    return "%s.setPosition(%s);\ngoto %s;" % (
                        result, previous_position, out[0])

                # pattern_result = pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip()

                data = """
{
    int %(previous)s = %(result)s.getPosition();
    %(code)s
}
%(success)s
%(label)s
""" % {
                    'previous':
                    previous_position,
                    'result':
                    result,
                    'code':
                    indent(
                        pattern.generate_cpp(peg, result, stream, fail, tail,
                                             peg_args)),
                    'success':
                    success,
                    'label':
                    label(out[0])
                }
                return data
コード例 #36
0
ファイル: cpp_generator.py プロジェクト: gui-rocha/newmugen
    def generate_maybe(me, pattern, peg, result, stream, failure, tail,
                       peg_args):
        save = gensym("save")
        fail = lambda: """
%(result)s = Result(%(save)s);
%(result)s.setValue(Value((void*) 0));
""" % {
            'result': result,
            'save': save
        }

        data = """
int %(save)s = %(result)s.getPosition();
%(code)s
""" % {
            'save':
            save,
            'result':
            result,
            'code':
            pattern.pattern.generate_cpp(peg, result, stream, fail, tail,
                                         peg_args)
        }
        return data
コード例 #37
0
ファイル: cpp_generator.py プロジェクト: jyizheng/lvd-linux
    def generate_rule(me, pattern, peg, result, stream, failure, tail,
                      peg_args):
        rule = peg.getRule(pattern.rule)
        if rule != None and rule.isInline():
            # TODO: add rule parameters and regular parameters for inlined rules
            if tail != None:
                raise Exception(
                    "Do not combine inlined rules that use tail recursion")

            def newPattern(pattern, stream, result, success):
                my_result = newResult()
                previous_position = gensym('position')
                out = [False]

                def label(n):
                    if n != False:
                        return "%s:" % n
                    return ""

                def fail():
                    if out[0] == False:
                        out[0] = newOut()
                    return "%s.setPosition(%s);\ngoto %s;" % (
                        result, previous_position, out[0])

                pattern_result = pattern.generate_cpp(peg, my_result, stream,
                                                      fail, tail,
                                                      peg_args).strip()

                old_data = """
{
Result %s(%s.getPosition());
%s
%s = %s;
}
%s
%s
                """ % (my_result, result, pattern_result, result, my_result,
                       success, label(out[0]))

                data = """
{
    int %s = %s.getPosition();
    %s
}
%s
%s
""" % (previous_position, result,
                indent(pattern.generate_cpp(peg, result, stream, fail, tail,
                                   peg_args)), success, label(out[0]))
                return data

            success_out = gensym('success')
            data = """
%s
%s
%s:
;
""" % ('\n'.join([
                newPattern(pattern, stream, result,
                           "goto %s;" % success_out).strip()
                for pattern in rule.patterns
            ]), failure(), success_out)
            return data
        else:
            # TODO: add rule parameters here
            if tail != None:
                if len(tail) == 0:
                    return ""
                else:
                    if pattern.parameters == None or len(tail) != len(
                            pattern.parameters):
                        raise Exception(
                            "Expected parameters %s but got %s while calling rule '%s'"
                            % (tail, pattern.parameters, pattern.rule))
                    return '\n'.join([
                        "%s = %s;" % (q[0], me.fixup_cpp(q[1], peg_args))
                        for q in zip(tail, pattern.parameters)
                    ])
            else:

                def change(arg):
                    if arg.startswith('@'):
                        return arg[1:]
                    if peg.getRule(arg) == None:
                        raise Exception(
                            "Cannot find rule '%s' while trying to call rule '%s'"
                            % (arg, pattern.rule))
                    return '(void*) rule_%s' % arg

                rule_parameters = ""
                if pattern.rules != None:
                    rule_parameters = ", %s" % ", ".join(
                        [change(f) for f in pattern.rules])
                parameters = ""
                if pattern.parameters != None:
                    parameters = ", %s" % ", ".join([
                        me.fixup_cpp(p, peg_args) for p in pattern.parameters
                    ])
                    # parameters = ", %s" % fix_param(pattern.parameters)
                data = """
%s = rule_%s(%s, %s.getPosition()%s%s);
if (%s.error()){
    %s
}
""" % (result, pattern.rule, stream, result, rule_parameters, parameters,
                result, indent(failure()))

                return data
コード例 #38
0
ファイル: cpp_generator.py プロジェクト: marstau/shinsango
    def generate_rule(me, pattern, peg, result, stream, failure, tail, peg_args):
        rule = peg.getRule(pattern.rule)
        if rule != None and rule.isInline():
            # TODO: add rule parameters and regular parameters for inlined rules
            if tail != None:
                raise Exception("Do not combine inlined rules that use tail recursion")
            def newPattern(pattern, stream, result, success):
                # my_result = newResult()
                previous_position = gensym('position')
                out = [False]
                def label(n):
                    if n != False:
                        return "%s:" % n
                    return ""

                def fail():
                    if out[0] == False:
                        out[0] = newOut()
                    return "%s.setPosition(%s);\ngoto %s;" % (result, previous_position, out[0])
                # pattern_result = pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip()

                data = """
{
    int %(previous)s = %(result)s.getPosition();
    %(code)s
}
%(success)s
%(label)s
""" % {'previous': previous_position,
       'result': result,
       'code': indent(pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)),
       'success': success,
       'label': label(out[0])}
                return data

            success_out = gensym('success')
            data = """
%(code)s
%(fail)s
%(success)s:
;
""" % {'code': '\n'.join([newPattern(pattern, stream, result, "goto %s;" % success_out).strip() for pattern in rule.patterns]),
       'fail': failure(),
       'success': success_out}
            return data
        else:
            # TODO: add rule parameters here
            if tail != None:
                if len(tail) == 0:
                    return ""
                else:
                    if pattern.parameters == None or len(tail) != len(pattern.parameters):
                        raise Exception("Expected parameters %s but got %s while calling rule '%s'" % (tail, pattern.parameters, pattern.rule))
                    return '\n'.join(["%s = %s;" % (q[0], me.fixup_cpp(q[1], peg_args)) for q in zip(tail, pattern.parameters)])
            else:
                def change(arg):
                    if arg.startswith('@'):
                        return arg[1:]
                    if peg.getRule(arg) == None:
                        raise Exception("Cannot find rule '%s' while trying to call rule '%s'" % (arg, pattern.rule))
                    return '(void*) rule_%s' % arg
                rule_parameters = ""
                if pattern.rules != None:
                    rule_parameters = ", %s" % ", ".join([change(f) for f in pattern.rules])
                parameters = ""
                if pattern.parameters != None:
                    parameters = ", %s" % ", ".join([me.fixup_cpp(p, peg_args) for p in pattern.parameters])
                    # parameters = ", %s" % fix_param(pattern.parameters)
                data = """
%(result)s = rule_%(rule)s(%(stream)s, %(result)s.getPosition()%(rule-parameters)s%(parameters)s);
if (%(result)s.error()){
    %(fail)s
}
""" % {'result': result,
       'rule': pattern.rule,
       'stream': stream,
       'rule-parameters': rule_parameters,
       'parameters': parameters,
       'fail': indent(failure())}

                return data