Skip to content

Commit 103c3ad

Browse files
committed
universal_code_generatorに統一
1 parent c347612 commit 103c3ad

File tree

14 files changed

+452
-793
lines changed

14 files changed

+452
-793
lines changed

atcodertools/codegen/code_generators/cpp.py

Lines changed: 4 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,13 @@
1-
2-
from typing import Dict, Any, Optional
3-
4-
from atcodertools.codegen.code_style_config import CodeStyleConfig
51
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
62
from atcodertools.codegen.template_engine import render
7-
from atcodertools.fmtprediction.models.format import Pattern, SingularPattern, ParallelPattern, TwoDimensionalPattern, \
8-
Format
9-
from atcodertools.fmtprediction.models.type import Type
10-
from atcodertools.fmtprediction.models.variable import Variable
11-
12-
13-
def _loop_header(var: Variable, for_second_index: bool):
14-
if for_second_index:
15-
index = var.second_index
16-
loop_var = "j"
17-
else:
18-
index = var.first_index
19-
loop_var = "i"
20-
21-
return "for(int {loop_var} = 0 ; {loop_var} < {length} ; {loop_var}++){{".format(
22-
loop_var=loop_var,
23-
length=index.get_length()
24-
)
25-
26-
27-
class CppCodeGenerator:
28-
29-
def __init__(self,
30-
format_: Optional[Format[Variable]],
31-
config: CodeStyleConfig):
32-
self._format = format_
33-
self._config = config
34-
35-
def generate_parameters(self) -> Dict[str, Any]:
36-
if self._format is None:
37-
return dict(prediction_success=False)
38-
39-
return dict(formal_arguments=self._formal_arguments(),
40-
actual_arguments=self._actual_arguments(),
41-
input_part=self._input_part(),
42-
prediction_success=True)
43-
44-
def _input_part(self):
45-
lines = []
46-
for pattern in self._format.sequence:
47-
lines += self._render_pattern(pattern)
48-
return "\n{indent}".format(indent=self._indent(1)).join(lines)
49-
50-
def _convert_type(self, type_: Type) -> str:
51-
if type_ == Type.float:
52-
return "long double"
53-
elif type_ == Type.int:
54-
return "long long"
55-
elif type_ == Type.str:
56-
return "std::string"
57-
else:
58-
raise NotImplementedError
59-
60-
def _get_declaration_type(self, var: Variable):
61-
ctype = self._convert_type(var.type)
62-
for _ in range(var.dim_num()):
63-
ctype = 'std::vector<{}>'.format(ctype)
64-
return ctype
65-
66-
def _actual_arguments(self) -> str:
67-
"""
68-
:return the string form of actual arguments e.g. "N, K, a"
69-
"""
70-
return ", ".join([
71-
v.name if v.dim_num() == 0 else 'std::move({})'.format(v.name)
72-
for v in self._format.all_vars()])
73-
74-
def _formal_arguments(self):
75-
"""
76-
:return the string form of formal arguments e.g. "int N, int K, std::vector<int> a"
77-
"""
78-
return ", ".join([
79-
"{decl_type} {name}".format(
80-
decl_type=self._get_declaration_type(v),
81-
name=v.name)
82-
for v in self._format.all_vars()
83-
])
84-
85-
def _generate_declaration(self, var: Variable):
86-
"""
87-
:return: Create declaration part E.g. array[1..n] -> std::vector<int> array = std::vector<int>(n-1+1);
88-
"""
89-
if var.dim_num() == 0:
90-
dims = []
91-
elif var.dim_num() == 1:
92-
dims = [var.first_index.get_length()]
93-
elif var.dim_num() == 2:
94-
dims = [var.first_index.get_length(),
95-
var.second_index.get_length()]
96-
else:
97-
raise NotImplementedError
98-
99-
if len(dims) == 0:
100-
ctor = ''
101-
elif len(dims) == 1:
102-
ctor = '({})'.format(dims[0])
103-
else:
104-
ctor = '({})'.format(dims[-1])
105-
ctype = self._convert_type(var.type)
106-
for dim in dims[-2::-1]:
107-
ctype = 'std::vector<{}>'.format(ctype)
108-
ctor = '({}, {}{})'.format(dim, ctype, ctor)
109-
110-
line = "{decl_type} {name}{constructor};".format(
111-
name=var.name,
112-
decl_type=self._get_declaration_type(var),
113-
constructor=ctor
114-
)
115-
return line
116-
117-
def _input_code_for_var(self, var: Variable) -> str:
118-
name = self._get_var_name(var)
119-
if var.type == Type.float:
120-
return 'scanf("%Lf",&{name});'.format(name=name)
121-
elif var.type == Type.int:
122-
return 'scanf("%lld",&{name});'.format(name=name)
123-
elif var.type == Type.str:
124-
return 'std::cin >> {name};'.format(name=name)
125-
else:
126-
raise NotImplementedError
127-
128-
@staticmethod
129-
def _get_var_name(var: Variable):
130-
name = var.name
131-
if var.dim_num() >= 1:
132-
name += "[i]"
133-
if var.dim_num() >= 2:
134-
name += "[j]"
135-
return name
136-
137-
def _render_pattern(self, pattern: Pattern):
138-
lines = []
139-
for var in pattern.all_vars():
140-
lines.append(self._generate_declaration(var))
141-
142-
representative_var = pattern.all_vars()[0]
143-
if isinstance(pattern, SingularPattern):
144-
lines.append(self._input_code_for_var(representative_var))
145-
elif isinstance(pattern, ParallelPattern):
146-
lines.append(_loop_header(representative_var, False))
147-
for var in pattern.all_vars():
148-
lines.append("{indent}{line}".format(indent=self._indent(1),
149-
line=self._input_code_for_var(var)))
150-
lines.append("}")
151-
elif isinstance(pattern, TwoDimensionalPattern):
152-
lines.append(_loop_header(representative_var, False))
153-
lines.append(
154-
"{indent}{line}".format(indent=self._indent(1), line=_loop_header(representative_var, True)))
155-
for var in pattern.all_vars():
156-
lines.append("{indent}{line}".format(indent=self._indent(2),
157-
line=self._input_code_for_var(var)))
158-
lines.append("{indent}}}".format(indent=self._indent(1)))
159-
lines.append("}")
160-
else:
161-
raise NotImplementedError
162-
163-
return lines
164-
165-
def _indent(self, depth):
166-
return self._config.indent(depth)
167-
1683

169-
class NoPredictionResultGiven(Exception):
170-
pass
4+
from atcodertools.codegen.code_generators.universal_code_generator import CodeGenerator
5+
from atcodertools.codegen.code_generators.universal_generator.cpp import CodeGeneratorInfo
1716

1727

1738
def main(args: CodeGenArgs) -> str:
174-
code_parameters = CppCodeGenerator(
175-
args.format, args.config).generate_parameters()
9+
code_parameters = CodeGenerator(
10+
args.format, args.config, CodeGeneratorInfo()).generate_parameters()
17611
return render(
17712
args.template,
17813
mod=args.constants.mod,

atcodertools/codegen/code_generators/cs.py

Lines changed: 4 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,171 +1,13 @@
1-
from typing import Dict, Any, Optional
2-
3-
from atcodertools.codegen.code_style_config import CodeStyleConfig
41
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
52
from atcodertools.codegen.template_engine import render
6-
from atcodertools.fmtprediction.models.format import Pattern, SingularPattern, ParallelPattern, TwoDimensionalPattern, \
7-
Format
8-
from atcodertools.fmtprediction.models.type import Type
9-
from atcodertools.fmtprediction.models.variable import Variable
10-
11-
12-
def _loop_header(var: Variable, for_second_index: bool):
13-
if for_second_index:
14-
index = var.second_index
15-
loop_var = "j"
16-
else:
17-
index = var.first_index
18-
loop_var = "i"
19-
20-
return "for(int {loop_var} = 0;{loop_var} < {len};{loop_var}++)".format(
21-
loop_var=loop_var,
22-
len=index.get_length()
23-
) + "{"
24-
25-
26-
class CSharpCodeGenerator:
27-
28-
def __init__(self,
29-
format_: Optional[Format[Variable]],
30-
config: CodeStyleConfig):
31-
self._format = format_
32-
self._config = config
33-
34-
def generate_parameters(self) -> Dict[str, Any]:
35-
if self._format is None:
36-
return dict(prediction_success=False)
37-
38-
return dict(formal_arguments=self._formal_arguments(),
39-
actual_arguments=self._actual_arguments(),
40-
input_part=self._input_part(),
41-
prediction_success=True)
42-
43-
def _input_part(self):
44-
lines = []
45-
for pattern in self._format.sequence:
46-
lines += self._render_pattern(pattern)
47-
return "\n{indent}".format(indent=self._indent(2)).join(lines)
48-
49-
def _convert_type(self, type_: Type) -> str:
50-
if type_ == Type.float:
51-
return "double"
52-
elif type_ == Type.int:
53-
return "long"
54-
elif type_ == Type.str:
55-
return "string"
56-
else:
57-
raise NotImplementedError
58-
59-
def _get_declaration_type(self, var: Variable):
60-
ctype = self._convert_type(var.type)
61-
if var.dim_num() == 0:
62-
return ctype
63-
else:
64-
return "{}[{}]".format(ctype, "," * (var.dim_num() - 1))
65-
66-
def _actual_arguments(self) -> str:
67-
"""
68-
:return the string form of actual arguments e.g. "N, K, a"
69-
"""
70-
return ", ".join([
71-
v.name if v.dim_num() == 0 else '{}'.format(v.name)
72-
for v in self._format.all_vars()])
73-
74-
def _formal_arguments(self):
75-
"""
76-
:return the string form of formal arguments e.g. "int N, int K, std::vector<int> a"
77-
"""
78-
return ", ".join([
79-
"{decl_type} {name}".format(
80-
decl_type=self._get_declaration_type(v),
81-
name=v.name)
82-
for v in self._format.all_vars()
83-
])
84-
85-
def _generate_declaration(self, var: Variable):
86-
"""
87-
:return: Create declaration part E.g. array[1..n] -> std::vector<int> array = std::vector<int>(n-1+1);
88-
"""
89-
if var.dim_num() == 0:
90-
dims = []
91-
elif var.dim_num() == 1:
92-
dims = [var.first_index.get_length()]
93-
elif var.dim_num() == 2:
94-
dims = [var.first_index.get_length(),
95-
var.second_index.get_length()]
96-
else:
97-
raise NotImplementedError
98-
ret = "{decl_type} {name}".format(
99-
decl_type=self._get_declaration_type(var), name=var.name)
100-
if len(dims) > 0:
101-
t = self._convert_type(var.type)
102-
d = []
103-
for dim in dims:
104-
d.append(str(dim))
105-
ret += " = new {type}[{dims}]".format(type=t, dims=",".join(d))
106-
ret += ";"
107-
return ret
108-
109-
def _input_code_for_var(self, var: Variable) -> str:
110-
name = self._get_var_name(var)
111-
if var.type == Type.float:
112-
return '{name} = cin.ReadDouble;'.format(name=name)
113-
elif var.type == Type.int:
114-
return '{name} = cin.ReadLong;'.format(name=name)
115-
elif var.type == Type.str:
116-
return '{name} = cin.Read;'.format(name=name)
117-
else:
118-
raise NotImplementedError
119-
120-
@staticmethod
121-
def _get_var_name(var: Variable):
122-
name = var.name
123-
if var.dim_num() >= 1:
124-
name += "[i"
125-
if var.dim_num() >= 2:
126-
name += ",j"
127-
name += "]"
128-
return name
129-
130-
def _render_pattern(self, pattern: Pattern):
131-
lines = []
132-
for var in pattern.all_vars():
133-
lines.append(self._generate_declaration(var))
134-
135-
representative_var = pattern.all_vars()[0]
136-
if isinstance(pattern, SingularPattern):
137-
lines.append(self._input_code_for_var(representative_var))
138-
elif isinstance(pattern, ParallelPattern):
139-
lines.append(_loop_header(representative_var, False))
140-
for var in pattern.all_vars():
141-
lines.append("{indent}{line}".format(indent=self._indent(1),
142-
line=self._input_code_for_var(var)))
143-
lines.append("}")
144-
elif isinstance(pattern, TwoDimensionalPattern):
145-
lines.append(_loop_header(representative_var, False))
146-
lines.append(
147-
"{indent}{line}".format(indent=self._indent(1), line=_loop_header(representative_var, True)))
148-
for var in pattern.all_vars():
149-
lines.append("{indent}{line}".format(indent=self._indent(2),
150-
line=self._input_code_for_var(var)))
151-
lines.append("{indent}}}".format(indent=self._indent(1)))
152-
lines.append("}")
153-
else:
154-
raise NotImplementedError
155-
156-
return lines
157-
158-
def _indent(self, depth):
159-
return self._config.indent(depth)
160-
1613

162-
class NoPredictionResultGiven(Exception):
163-
pass
4+
from atcodertools.codegen.code_generators.universal_code_generator import CodeGenerator
5+
from atcodertools.codegen.code_generators.universal_generator.cs import CodeGeneratorInfo
1646

1657

1668
def main(args: CodeGenArgs) -> str:
167-
code_parameters = CSharpCodeGenerator(
168-
args.format, args.config).generate_parameters()
9+
code_parameters = CodeGenerator(
10+
args.format, args.config, CodeGeneratorInfo()).generate_parameters()
16911
return render(
17012
args.template,
17113
mod=args.constants.mod,

0 commit comments

Comments
 (0)