コード例 #1
0
def print_lines(
    name: str,
    type_: Type,
    input_data: Input,
    indent_lvl: int,
    style: FormatStyle = FormatStyle.DEFAULT,
) -> List[str]:
    """Print the content of a var that holds in one or more lines"""
    indent = INDENTATION * indent_lvl
    if type_.fits_in_one_line(input_data.structs, style):
        return [indent + print_line(name, type_, input_data, style)]
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        inner = "iT{}".format(indent_lvl)
        return (
            [indent + "for _, {} in ipairs({}) do".format(inner, name)]
            + print_lines(inner, type_.encapsulated, input_data, indent_lvl + 1)
            + [indent + "end"]
        )
    assert type_.main == TypeEnum.STRUCT
    lines = []
    for i in input_data.get_struct(type_.struct_name).fields:
        lines.extend(
            print_lines('{}["{}"]'.format(name, i.name), i.type, input_data, indent_lvl)
        )
    return lines
コード例 #2
0
def print_line(name: str, type_: Type, input_data: Input,
               style: FormatStyle) -> str:
    """Print a variable on one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    newline = " " if style == FormatStyle.NO_ENDLINE else r"\n"
    if type_.main == TypeEnum.INT:
        return f'Printf.printf "%d{newline}" {name}'
    if type_.main == TypeEnum.CHAR:
        return f'Printf.printf "%c{newline}" {name}'
    if type_.main == TypeEnum.STR:
        return f'Printf.printf "%s{newline}" {name}'
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        concat = ""
        if type_.encapsulated.main == TypeEnum.INT:
            concat = '" " (List.rev (List.rev_map string_of_int {}))'.format(
                name)
        else:
            assert type_.encapsulated.main == TypeEnum.CHAR
            concat = '"" (List.rev (List.rev_map (String.make 1) {}))'.format(
                name)
        return 'Printf.printf "%s\\n" (String.concat {})'.format(concat)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return 'Printf.printf "{}\\n" {}'.format(
        " ".join("%d" if f.type.main == TypeEnum.INT else "%c"
                 for f in struct.fields),
        " ".join("{}.{}".format(name, var_name(f.name))
                 for f in struct.fields),
    )
コード例 #3
0
def print_line(name: str, type_: Type, input_data: Input,
               style: FormatStyle) -> str:
    """Print a variable that fits in one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    write = (f'write({name}), write(" ")'
             if style == FormatStyle.NO_ENDLINE else f"writeln({name})")
    if type_.main == TypeEnum.INT:
        return f"integer({name}), {write}"
    if type_.main == TypeEnum.CHAR:
        return f"atom({name}), {write}"
    if type_.main == TypeEnum.STR:
        return f"string({name}), {write}"
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.INT:
            return ("is_list({0}), maplist(integer, {0}), atomic_list_concat("
                    "{0}, ' ', {0}_S), writeln({0}_S)").format(name)
        assert type_.encapsulated.main == TypeEnum.CHAR
        return ("is_list({0}), maplist(atom, {0}), string_chars({0}_S, {0}),"
                "writeln({0}_S)").format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    fields = []
    for i, field in enumerate(struct.fields):
        f_name = name + "_" + var_name(field.name)
        fields.append(
            'get_assoc("{0}", {1}, {2}), {3}({2}), write({2}), {4}'.format(
                field.name,
                name,
                name + "_" + f_name,
                "integer" if field.type.main == TypeEnum.INT else "atom",
                'write(" ")' if i < len(struct.fields) - 1 else "nl",
            ))
    return "is_assoc({}), {}".format(name, ", ".join(fields))
コード例 #4
0
def print_lines(
        name: str,
        type_: Type,
        input_data: Input,
        style: FormatStyle = FormatStyle.DEFAULT) -> Tuple[List[str], str]:
    """Print a variable that fits in several lines

    Return a list of declarations to be put before, and the actual code to
    print the variable"""
    if type_.fits_in_one_line(input_data.structs, style):
        return ([], print_line(name, type_, input_data, style))
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        arg = name + "_S"
        function = "print_" + name
        (decl, code) = print_lines(arg, type_.encapsulated, input_data)
        return (decl + ["{}({}) :- {}.".format(function, arg, code)
                        ]), "is_list({1}), maplist({0}, {1})".format(
                            function, name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    fields = []
    decls = []
    for field in struct.fields:
        f_name = name + "_" + var_name(field.name)
        decl, print_inner = print_lines(f_name, field.type, input_data)
        fields.append('get_assoc("{}", {}, {}), {}'.format(
            field.name, name, f_name, print_inner))
        decls.extend(decl)
    return decls, "is_assoc({}), {}".format(name, ", ".join(fields))
コード例 #5
0
def read_line(type_: Type, input_data: Input) -> str:
    """Generate the Ruby code to read a line of given type"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return 'STDIN.gets.chomp.split("")'
        assert type_.encapsulated.main == TypeEnum.INT
        return "STDIN.gets.split.map(&:to_i)"
    if type_.main == TypeEnum.STRUCT:
        struct = input_data.get_struct(type_.struct_name)
        keys = ", ".join('"{}"'.format(i.name) for i in struct.fields)
        if all(i.type.main == TypeEnum.INT for i in struct.fields):
            return "Hash[[{}].zip(STDIN.gets.split.map(&:to_i))]".format(keys)
        if all(i.type.main == TypeEnum.CHAR for i in struct.fields):
            return 'Hash[[{}].zip(STDIN.gets.chomp.split(" "))]'.format(keys)
        return "Hash[[{}].zip([{}], STDIN.gets.split).map{{ {} }}]".format(
            keys,
            ", ".join("1" if i.type.main == TypeEnum.INT else "0"
                      for i in struct.fields),
            "|x,y,z| [x, y == 1 ? z.to_i : z]",
        )
    return {
        TypeEnum.INT: "STDIN.gets.to_i",
        TypeEnum.CHAR: "STDIN.gets[0]",
        TypeEnum.STR: "STDIN.gets.chomp",
    }[type_.main]
コード例 #6
0
def read_line(type_: Type, input_data: Input) -> str:
    """Read an entire line into the correct type"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main == TypeEnum.INT:
        return "read_int ()"
    if type_.main == TypeEnum.CHAR:
        return "(read_line ()).[0]"
    if type_.main == TypeEnum.STR:
        return "read_line ()"
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.INT:
            # Note: here we have to use List.rev_map |> List.rev, because
            # List.map is not tail-recursive, and will trigger a stack overflow
            # if the list is big (size bigger than 1024).
            # We could check if the constraints specify a small list, and use
            # only List.map for those cases.
            return ('read_line () |> fun x -> if x = "" then [] else '
                    "String.split_on_char ' ' x |> "
                    "List.rev_map int_of_string |> List.rev")
        assert type_.encapsulated.main == TypeEnum.CHAR
        return "List.init {} (String.get (read_line ()))".format(
            var_name(type_.size))
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    args = [var_name(field.name) for field in struct.fields]
    return 'Scanf.sscanf (read_line ()) "{}" (fun {} -> {{{}}})'.format(
        " ".join("%d" if f.type.main == TypeEnum.INT else "%c"
                 for f in struct.fields),
        " ".join(args),
        "; ".join("{0}".format(i) for i in args),
    )
コード例 #7
0
ファイル: parser_javascript.py プロジェクト: prologin/iorgen
def call(input_data: Input, reprint: bool) -> List[str]:
    """Declare the function that takes all inputs in arguments"""
    out = (["/**"] + [
        " * @param {{{}}} {} {}".format(type_str(arg.type, input_data),
                                        var_name(arg.name), arg.comment)
        for arg in input_data.input
    ] + [" * @returns {void}", " */"])
    out.append("function {}({}) {{".format(
        var_name(input_data.name),
        ", ".join(var_name(i.name) for i in input_data.input),
    ))
    if reprint:
        for variables in input_data.get_all_vars():
            if len(variables) == 1:
                var = variables[0]
                out.extend(
                    print_lines(input_data, var_name(var.name), var.type, 1,
                                var.format_style))
            else:
                out.append(INDENTATION + "console.log(" +
                           ", ".join(var_name(i.name)
                                     for i in variables) + ");")
    else:
        out.extend([
            INDENTATION + i
            for i in textwrap.wrap("/* TODO " + input_data.output + " */", 75)
        ])
    out.append("}")
    return out
コード例 #8
0
def call(input_data: Input, reprint: bool) -> List[str]:
    """Declare and call the function take all inputs in arguments"""
    name = var_name(input_data.name)
    lines = [
        "# +{}+:: {}".format(var_name(arg.name), arg.comment)
        for arg in input_data.input
    ]
    lines.append("def {}({})".format(
        name, ", ".join(var_name(i.name) for i in input_data.input)))
    if reprint:
        lines.append(INDENTATION + '$\\ = "\\n"')
        for variables in input_data.get_all_vars():
            if len(variables) == 1:
                var = variables[0]
                lines.extend(
                    print_lines(var_name(var.name), var.type, input_data, 1,
                                var.format_style))
            else:
                lines.append(
                    INDENTATION + "puts " +
                    f'[{", ".join(var_name(i.name) for i in variables)}].join(" ")'
                )
    else:
        lines.extend(
            textwrap.wrap(
                input_data.output,
                79,
                initial_indent=INDENTATION + "# " + "TODO ",
                subsequent_indent=INDENTATION + "# ",
            ))
    return lines + ["end"]
コード例 #9
0
ファイル: parser_perl.py プロジェクト: prologin/iorgen
def read_line(name: str, decl: str, type_: Type, input_data: Input,
              words: WordsName) -> List[str]:
    """Generate the Ruby code to read a line of given type"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main == TypeEnum.INT:
        return [decl.format("int <>")]
    if type_.main == TypeEnum.CHAR:
        return [decl.format("substr <>, 0, 1")]
    if type_.main == TypeEnum.STR:
        read = "<>" if decl.startswith("my") else "scalar(<>)"
        return [decl.format(read), "chomp {};".format(name)]
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        decl2 = decl
        if not decl.startswith("my"):
            decl2 = format_keep_braces(decl, "\\@{{[{}]}}")
        if type_.encapsulated.main == TypeEnum.INT:
            return [decl2.format("map { int } split(/[ \\n]/, <>)")]
        assert type_.encapsulated.main == TypeEnum.CHAR
        return [decl2.format("split /\\n?/, <>")]
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    decl2 = decl
    if not decl.startswith("my"):
        decl2 = format_keep_braces(decl, "\\%{{{{{}}}}}")
    split = words.next_name()
    fields = ('"{}" => {}'.format(
        f.name,
        ("int(${}[{}])" if f.type.main == TypeEnum.INT else
         "substr(${}[{}], 0, 1)").format(split, i),
    ) for i, f in enumerate(struct.fields))
    return [
        "my @{} = split /[ \\n]/, <>;".format(split),
        decl2.format("({})".format(", ".join(fields))),
    ]
コード例 #10
0
ファイル: parser_python.py プロジェクト: prologin/iorgen
def read_line(type_: Type, input_data: Input) -> str:
    """Generate the Python code to read a line of given type"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return "list(input())"
        assert type_.encapsulated.main == TypeEnum.INT
        return "list(map(int, input().split()))"
    if type_.main == TypeEnum.STRUCT:
        struct = input_data.get_struct(type_.struct_name)
        if all(i.type.main == TypeEnum.INT for i in struct.fields):
            return f"{class_name(struct.name)}(*map(int, input().split()))"
        if all(i.type.main == TypeEnum.CHAR for i in struct.fields):
            return f"{class_name(struct.name)}(*input().split())"
        return "{}(*map({}, ({}), input().split()))".format(
            class_name(struct.name),
            "lambda x, y: int(y) if x else y",
            ", ".join(
                "1" if i.type.main == TypeEnum.INT else "0" for i in struct.fields
            ),
        )
    return {
        TypeEnum.INT: "int(input())",
        TypeEnum.CHAR: "input()[0]",
        TypeEnum.STR: "input()",
    }[type_.main]
コード例 #11
0
def read_vars(input_data: Input, iterator: IteratorName) -> List[str]:
    """Read all input variables"""
    all_lines = []
    for variables in input_data.get_all_vars():
        if len(variables) == 1:
            var = variables[0]
            lines = read_lines(
                Variable(var_name(var.name), "", var.type, var.format_style),
                var_name(var.type.size),
                input_data,
                iterator,
            )
            if lines[0].startswith("local"):  # struct
                lines[1] = "local " + lines[1]
            else:
                lines[0] = "local " + lines[0]
            all_lines.extend(lines)
        else:
            assert all(var.type.main == TypeEnum.INT for var in variables)
            all_lines.append(
                'local {} = string.match(io.read(), "{}")'.format(
                    ", ".join(var_name(i.name) for i in variables),
                    " ".join(["(-?%d+)"] * len(variables)),
                )
            )
    return all_lines
コード例 #12
0
def gen_ocaml(input_data: Input, reprint: bool = False) -> str:
    """Generate a OCaml code to parse input"""
    output = ""
    main = ""
    for record in input_data.structs:
        main += "\n".join(declare_record(record))
        main += "\n\n"
    main += "\n".join(method(input_data, reprint))
    main += "\n\nlet () =\n"
    for variables in input_data.get_all_vars():
        if len(variables) == 1:
            var = variables[0]
            main += (
                INDENTATION + f"let {var_name(var.name)} = " +
                f"{read_lines(var.type, input_data, var.format_style)} in\n")
        else:
            assert all(var.type.main == TypeEnum.INT for var in variables)
            main += (INDENTATION + 'let[@warning "-8"] [' +
                     "; ".join(var_name(i.name) for i in variables) +
                     "] = read_line () |> String.split_on_char ' '"
                     '|> List.map int_of_string [@warning "+8"] in \n')
    args = (var_name(i.name) for i in input_data.input)
    main += "{}{} {}\n".format(INDENTATION, var_name(input_data.name),
                               " ".join(args))
    output += main
    return output
コード例 #13
0
def error_parse_input(dic: Dict[str, Any]) -> str:
    """Explain why we an input fails to parse"""
    # pylint: disable=too-many-return-statements
    # pylint: disable=too-many-branches
    assert Input.from_dict(dic) is None
    if "function_name" not in dic:
        if "name" in dic:
            dic["function_name"] = dic["name"]
        else:
            return "missing function_name field"
    if not isinstance(dic["function_name"], str):
        return "function_name is not a string"
    if "structs" in dic:  # non mandatory
        if not isinstance(dic["structs"], list):
            return "'structs' is not a list"
        for node in dic["structs"]:
            if Struct.from_dict(node) is None:
                return "failed to parse struct: " + error_parse_struct(node)
    if "input" not in dic:
        return "missing input field"
    if not isinstance(dic["input"], list):
        return "output is not a list"
    for node in dic["input"]:
        if Variable.from_dict(node) is None:
            return "failed to parse variable: " + error_parse_variable(node)
    if "output" not in dic:
        return "missing output field"
    if not isinstance(dic["output"], str):
        return "output is not a string"
    return "unknown error"
コード例 #14
0
def read_line(
    name: str, type_: Type, input_data: Input, iterator: IteratorName
) -> List[str]:
    """Generate the Lua code to read a line of given type"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        inner = iterator.new_it()
        iterator.pop_it()
        if type_.encapsulated.main == TypeEnum.CHAR:
            return [
                "{} = {{}}".format(name),
                'io.read():gsub(".",function({0}) table.insert({1}, {0}) end)'.format(
                    inner, name
                ),
            ]
        assert type_.encapsulated.main == TypeEnum.INT
        return [
            "{} = {{}}".format(name),
            'for {} in string.gmatch(io.read(), "-?%d+") do'.format(inner),
            INDENTATION + "table.insert({}, tonumber({}))".format(name, inner),
            "end",
        ]
    if type_.main == TypeEnum.STRUCT:
        struct = input_data.get_struct(type_.struct_name)
        words = iterator.new_it()
        iterator.pop_it()
        pattern = " ".join(
            "(-?%d+)" if i.type.main == TypeEnum.INT else "(%S)" for i in struct.fields
        )
        keys = (
            '["{}"]'.format(i.name) if " " in i.name else i.name for i in struct.fields
        )
        values = (
            "tonumber({}[{}])".format(words, i + 1)
            if f.type.main == TypeEnum.INT
            else "{}[{}]".format(words, i + 1)
            for (i, f) in enumerate(struct.fields)
        )
        return [
            'local {} = {{string.match(io.read(), "{}")}}'.format(words, pattern),
            "{} = {{{}}}".format(
                name, ", ".join(i + " = " + j for (i, j) in zip(keys, values))
            ),
        ]
    return [
        name
        + " = "
        + {
            TypeEnum.INT: "tonumber(io.read())",
            TypeEnum.CHAR: "io.read()",
            TypeEnum.STR: "io.read()",
        }[type_.main]
    ]
コード例 #15
0
def read_lines(
    type_: Type,
    size: str,
    input_data: Input,
    iterator: IteratorName,
    style: FormatStyle = FormatStyle.DEFAULT,
) -> List[str]:
    """Generate the Ruby code to read the lines for a given type"""
    if type_.fits_in_one_line(input_data.structs, style):
        return [read_line(type_, input_data)]
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        lines = read_lines(type_.encapsulated,
                           var_name(type_.encapsulated.size), input_data,
                           iterator)
        if len(lines) == 1:
            candidate = "Array.new({}) {{ {} }}".format(size, lines[0])
            if len(candidate) <= 75:
                return [candidate]
        if lines[0][0] == "{":
            lines[0] = "Array.new({}) {{ {}".format(size, lines[0])
        else:
            lines = ["Array.new({}) {{".format(size)
                     ] + [INDENTATION + i for i in lines]
        if lines[-1][-1] == "}":
            lines[-1] += " }"
        else:
            lines.append("}")
        return lines
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    if struct.is_sized_struct():
        inner = iterator.new_it()
        lines = read_lines(struct.fields[1].type, inner, input_data, iterator)
        iterator.pop_it()
        lines[0] = '"{}" => {}'.format(struct.fields[1].name, lines[0])
        return ([
            "(lambda {{ |{}| {{".format(inner),
            INDENTATION + '"{}" => {},'.format(struct.fields[0].name, inner),
        ] + [INDENTATION + i for i in lines] + ["} }).call(STDIN.gets.to_i)"])
    fields = []
    for i, field in enumerate(struct.fields):
        lines = read_lines(field.type, var_name(field.type.size), input_data,
                           iterator)
        lines[0] = '{}"{}" => {}'.format(INDENTATION, field.name, lines[0])
        if i != len(struct.fields) - 1:
            lines[-1] += ","
        fields.append(lines[0])
        fields.extend([INDENTATION + i for i in lines[1:]])
    return ["{"] + fields + ["}"]
コード例 #16
0
ファイル: parser_javascript.py プロジェクト: prologin/iorgen
def print_line(name: str, type_: Type, input_data: Input) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        return "console.log({});".format(name)
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return 'console.log({}.join(""));'.format(name)
        assert type_.encapsulated.main == TypeEnum.INT
        return 'console.log({}.join(" "));'.format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return 'console.log([{}].join(" "));'.format(", ".join(
        "{}.{}".format(name, var_name(i.name)) for i in struct.fields))
コード例 #17
0
def print_line(name: str, type_: Type, input_data: Input) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs)
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        return "puts {}".format(name)
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return 'puts {}.join("")'.format(name)
        assert type_.encapsulated.main == TypeEnum.INT
        return 'puts {}.join(" ")'.format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return "print {}".format(', " ", '.join('{}["{}"]'.format(name, i.name)
                                            for i in struct.fields))
コード例 #18
0
ファイル: parser_python.py プロジェクト: prologin/iorgen
def print_line(name: str, type_: Type, input_data: Input, style: FormatStyle) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        end = ", end=' '" if style == FormatStyle.NO_ENDLINE else ""
        return f"print({name}{end})"
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return "print(''.join({}))".format(name)
        assert type_.encapsulated.main == TypeEnum.INT
        return "print(' '.join(map(str, {})))".format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return "print({})".format(
        ", ".join(f"{name}.{var_name(field.name)}" for field in struct.fields)
    )
コード例 #19
0
def print_line(name: str, type_: Type, input_data: Input,
               style: FormatStyle) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        endline = " " if style == FormatStyle.NO_ENDLINE else r"\n"
        return f'echo {name}, "{endline}";'
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return 'echo join("", {}), "\\n";'.format(name)
        assert type_.encapsulated.main == TypeEnum.INT
        return 'echo join(" ", {}), "\\n";'.format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return 'echo {}, "\\n";'.format(", ' ', ".join(
        '{}["{}"]'.format(name, i.name) for i in struct.fields))
コード例 #20
0
ファイル: parser_julia.py プロジェクト: prologin/iorgen
def print_line(name: str, type_: Type, input_data: Input,
               style: FormatStyle) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        return (f'print({name}, " ")'
                if style == FormatStyle.NO_ENDLINE else f"println({name})")
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return "println(join({}))".format(name)
        assert type_.encapsulated.main == TypeEnum.INT
        return "println(join({}, ' '))".format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return "println({})".format(", ' ', ".join(
        "{}.{}".format(name, var_name(i.name)) for i in struct.fields))
コード例 #21
0
ファイル: parser_javascript.py プロジェクト: prologin/iorgen
def type_str(type_: Type, input_data: Input) -> str:
    """Return the Javascript name for a type"""
    # http://usejsdoc.org/tags-type.html
    if type_.main == TypeEnum.INT:
        return "number"
    if type_.main == TypeEnum.CHAR:
        return "string"
    if type_.main == TypeEnum.STR:
        return "string"
    if type_.main == TypeEnum.STRUCT:
        struct = input_data.get_struct(type_.struct_name)
        return "{{{}}}".format(", ".join("{}: {}".format(
            v.name if " " not in v.name else "'{}'".format(v.name),
            type_str(v.type, input_data),
        ) for v in struct.fields))
    assert type_.main == TypeEnum.LIST
    assert type_.encapsulated
    return "Array.<{}>".format(type_str(type_.encapsulated, input_data))
コード例 #22
0
ファイル: parser_python.py プロジェクト: prologin/iorgen
def read_vars(input_data: Input) -> List[str]:
    """Read all input variables"""
    lines = []
    for variables in input_data.get_all_vars():
        if len(variables) == 1:
            var = variables[0]
            var_lines = read_lines(
                var.type, var_name(var.type.size), input_data, var.format_style
            )
            var_lines[0] = f"{var_name(var.name)} = {var_lines[0]}"
            lines.extend(var_lines)
        else:
            assert all(var.type.main == TypeEnum.INT for var in variables)
            lines.append(
                ", ".join(var_name(i.name) for i in variables)
                + " = map(int, input().split())"
            )
    return lines
コード例 #23
0
def type_str(type_: Type, input_data: Input) -> str:
    """Transform a type into a string description for documentation"""
    if type_.main == TypeEnum.INT:
        return "int"
    if type_.main == TypeEnum.CHAR:
        return "string"
    if type_.main == TypeEnum.STR:
        return "string"
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        return "{}[]".format(type_str(type_.encapsulated, input_data))
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    # the following is not PHPDoc, but it does not allow for anything more than
    # 'array'
    return "(array{{{}}})".format(", ".join(
        '"{}": {}'.format(v.name, type_str(v.type, input_data))
        for v in struct.fields))
コード例 #24
0
def read_lines(type_: Type,
               input_data: Input,
               style: FormatStyle = FormatStyle.DEFAULT) -> str:
    """Read one or several lines into the correct type"""
    if type_.fits_in_one_line(input_data.structs, style):
        return read_line(type_, input_data)
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        return "List.init {} (fun _ -> {})".format(
            var_name(type_.size), read_lines(type_.encapsulated, input_data))
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return "{} {{{}}}".format(
        " ".join("let {} = {} in".format(var_name(field.name),
                                         read_lines(field.type, input_data))
                 for field in struct.fields),
        "; ".join("{0}".format(var_name(f.name)) for f in struct.fields),
    )
コード例 #25
0
ファイル: parser_perl.py プロジェクト: prologin/iorgen
def print_line(varname: str, type_: Type, input_data: Input,
               style: FormatStyle) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    name = "$" + varname[1:]
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        endline = " " if style == FormatStyle.NO_ENDLINE else r"\n"
        return f'print "{name}{endline}";'
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return f'print join("", @{{{name}}}) . "\\n";'
        assert type_.encapsulated.main == TypeEnum.INT
        return 'print "{}\\n";'.format("@{" + name + "}")
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return 'print "{}\\n";'.format(" ".join(
        "{}->{{'{}'}}".format(name, i.name) for i in struct.fields))
コード例 #26
0
ファイル: parser_perl.py プロジェクト: prologin/iorgen
def read_lines(var: Variable, decl: str, size: str, input_data: Input,
               words: WordsName) -> List[str]:
    """Generate the Ruby code to read the lines for a given type"""
    if var.fits_in_one_line(input_data.structs):
        return read_line(var.name, decl, var.type, input_data, words)
    if var.type.main == TypeEnum.LIST:
        assert var.type.encapsulated is not None
        lines = [
            decl.format("()" if var.name[0] == "@" else "[]"),
            "for (1..{}) {{".format(size),
        ]
        words.push_scope()
        array_name = var.name.replace("{", "{{").replace("}", "}}")
        if array_name[0] != "@":
            array_name = "@{{" + array_name + "}}"
        lines.extend([
            INDENTATION + i for i in read_lines(
                Variable("$" + var.name[1:] +
                         "[-1]", "", var.type.encapsulated),
                "push({}, {{}});".format(array_name),
                size_name(var.type.encapsulated.size),
                input_data,
                words,
            )
        ])
        words.pop_scope()
        return lines + ["}"]
    assert var.type.main == TypeEnum.STRUCT
    struct = input_data.get_struct(var.type.struct_name)
    sizes = [size_name(field.type.size) for field in struct.fields]
    if struct.is_sized_struct():
        sizes = ["", f"{var.name}{{'{struct.fields[0].name}'}}"]
    lines = [decl.format("()" if var.name[0] == "%" else "{}")]
    for (field, f_size) in zip(struct.fields, sizes):
        f_name = f"${var.name[1:]}{{'{field.name}'}}"
        lines.extend(
            read_lines(
                Variable(f_name, "", field.type),
                f_name.replace("{", "{{").replace("}", "}}") + " = {};",
                f_size,
                input_data,
                words,
            ))
    return lines
コード例 #27
0
def max_size(
    type_: Type,
    constraints: Optional[Constraints],
    input_data: Input,
    style: FormatStyle = FormatStyle.DEFAULT,
) -> int:
    """Computes the maximum number of bytes the type can take on stdin"""
    if type_.main == TypeEnum.INT:
        assert constraints
        return max(
            len(str(constraints.min_possible())), len(str(constraints.max_possible()))
        )
    if type_.main == TypeEnum.CHAR:
        return 1
    if type_.main == TypeEnum.STRUCT:
        struct = input_data.get_struct(type_.struct_name)
        sizes = [max_size(i.type, i.constraints, input_data) for i in struct.fields]
        if type_.fits_in_one_line(input_data.structs, style):
            return sum(sizes) + len(struct.fields) - 1
        return max(sizes)
    size = -1
    size_vars = [x for x in input_data.input if x.name == type_.size]
    if not size_vars:
        size_vars = [
            x for s in input_data.structs for x in s.fields if x.name == type_.size
        ]
    if size_vars:
        varconstraints = size_vars[0].constraints
        assert varconstraints
        size = varconstraints.max_possible()
    else:
        size = int(type_.size)
    if type_.main == TypeEnum.STR:
        return size
    assert type_.main == TypeEnum.LIST
    assert type_.encapsulated
    value = max_size(type_.encapsulated, constraints, input_data)
    return (
        value * size + max(0, size - 1)
        if type_.fits_in_one_line(input_data.structs, style)
        else value
    )
コード例 #28
0
ファイル: parser_perl.py プロジェクト: prologin/iorgen
def read_vars(input_data: Input, words: WordsName) -> List[str]:
    """Read all input variables"""
    lines = []
    for variables in input_data.get_all_vars():
        if len(variables) == 1:
            var = variables[0]
            lines.extend(
                read_lines(
                    Variable(var_name(var), "", var.type, var.format_style),
                    "my {} = {{}};".format(var_name(var)),
                    size_name(var.type.size),
                    input_data,
                    words,
                ))
        else:
            split = words.next_name()
            lines.append(f"my @{split} = split / /, <>;")
            for i, var in enumerate(variables):
                lines.append(f"my {var_name(var)} = int(${split}[{i}]);")

    return lines
コード例 #29
0
def generate_random_input(input_data: Input,
                          specs: List[str],
                          perf_mode: bool = False) -> str:
    """Generate a randow raw input, as described by input_data"""
    specs_dict = {}
    for i in range(0, len(specs), 2):
        specs_dict[specs[i]] = int(specs[i + 1])
    generator = Generator(input_data, specs_dict, perf_mode)
    lines = []
    for variables in input_data.get_all_vars():
        if len(variables) == 1:
            lines.extend(generator.generate_lines(variables[0]))
        else:
            values = []
            for var in variables:
                assert var.type.main == TypeEnum.INT
                assert var.constraints is not None
                values.append(
                    generator.generate_integer(var.name, var.constraints))
            lines.append(" ".join(values))
    return "\n".join(lines) + "\n"
コード例 #30
0
def print_line(name: str, type_: Type, input_data: Input, style: FormatStyle) -> str:
    """Print the content of a var in one line"""
    assert type_.fits_in_one_line(input_data.structs, style)
    if type_.main in (TypeEnum.INT, TypeEnum.CHAR, TypeEnum.STR):
        return (
            f"io.write({name}, ' ')"
            if style == FormatStyle.NO_ENDLINE
            else f"print({name})"
        )
    if type_.main == TypeEnum.LIST:
        assert type_.encapsulated is not None
        if type_.encapsulated.main == TypeEnum.CHAR:
            return 'print(table.concat({}, ""))'.format(name)
        assert type_.encapsulated.main == TypeEnum.INT
        return 'print(table.concat({}, " "))'.format(name)
    assert type_.main == TypeEnum.STRUCT
    struct = input_data.get_struct(type_.struct_name)
    return 'print(string.format("{}", {}))'.format(
        " ".join("%s" for _ in struct.fields),
        ", ".join('{}["{}"]'.format(name, i.name) for i in struct.fields),
    )