Skip to content

Commit 1126750

Browse files
chaemonkyuridenamida
authored andcommitted
Support C# (kyuridenamida#153)
* Support C#
1 parent 302d80b commit 1126750

File tree

16 files changed

+913
-5
lines changed

16 files changed

+913
-5
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ before_install:
1111
- sudo apt-get update --allow-insecure-repositories
1212
- sudo apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring
1313
- sudo apt-get update
14-
- sudo apt-get install rustc g++-4.9 openjdk-8-jdk nim dmd-compiler
14+
- sudo apt-get install rustc g++-4.9 openjdk-8-jdk nim dmd-compiler mono-complete
1515
- sudo ln -f -s /usr/bin/g++-4.9 /usr/bin/g++
1616

1717
install:
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
from typing import Dict, Any, Optional
2+
3+
from atcodertools.codegen.code_style_config import CodeStyleConfig
4+
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
5+
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+
161+
162+
class NoPredictionResultGiven(Exception):
163+
pass
164+
165+
166+
def main(args: CodeGenArgs) -> str:
167+
code_parameters = CSharpCodeGenerator(
168+
args.format, args.config).generate_parameters()
169+
return render(
170+
args.template,
171+
mod=args.constants.mod,
172+
yes_str=args.constants.yes_str,
173+
no_str=args.constants.no_str,
174+
**code_parameters
175+
)

atcodertools/common/language.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import re
22
from typing import Pattern, Callable
33

4-
from atcodertools.codegen.code_generators import cpp, java, rust, python, nim, d
4+
from atcodertools.codegen.code_generators import cpp, java, rust, python, nim, d, cs
55
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
66
from atcodertools.tools.templates import get_default_template_path
77

@@ -103,5 +103,15 @@ def from_name(cls, name: str):
103103
default_code_style=CodeStyle(indent_width=2)
104104
)
105105

106-
ALL_LANGUAGES = [CPP, JAVA, RUST, PYTHON, NIM, DLANG]
106+
CSHARP = Language(
107+
name="cs",
108+
display_name="C#",
109+
extension="cs",
110+
submission_lang_pattern=re.compile(".*C# \\(Mono.*"),
111+
default_code_generator=cs.main,
112+
default_template_path=get_default_template_path('cs'),
113+
)
114+
115+
116+
ALL_LANGUAGES = [CPP, JAVA, RUST, PYTHON, NIM, DLANG, CSHARP]
107117
ALL_LANGUAGE_NAMES = [lang.display_name for lang in ALL_LANGUAGES]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using System.Text;
3+
using System.Linq;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
using static System.Console;
7+
using static System.Math;
8+
using System.Diagnostics;
9+
10+
public class Program{
11+
{% if mod %}
12+
const long MOD = {{ mod }};
13+
{% endif %}
14+
{% if yes_str %}
15+
const string YES = "{{ yes_str }}";
16+
{% endif %}
17+
{% if no_str %}
18+
const string NO = "{{ no_str }}";
19+
{% endif %}
20+
21+
public static void Main(string[] args){
22+
ConsoleInput cin = new ConsoleInput(Console.In, ' ');
23+
{% if prediction_success %}
24+
{{ input_part }}
25+
new Program().Solve({{ actual_arguments }});
26+
{% else %}
27+
// Failed to predict input format
28+
{% endif %}
29+
}
30+
31+
{% if prediction_success %}
32+
public void Solve({{ formal_arguments }}){
33+
34+
}
35+
{% endif %}
36+
}
37+
38+
public class ConsoleInput{
39+
private readonly System.IO.TextReader _stream;
40+
private char _separator = ' ';
41+
private Queue<string> inputStream;
42+
public ConsoleInput(System.IO.TextReader stream, char separator = ' '){
43+
this._separator = separator;
44+
this._stream = stream;
45+
inputStream = new Queue<string>();
46+
}
47+
public string Read{
48+
get{
49+
if (inputStream.Count != 0) return inputStream.Dequeue();
50+
string[] tmp = _stream.ReadLine().Split(_separator);
51+
for (int i = 0; i < tmp.Length; ++i)
52+
inputStream.Enqueue(tmp[i]);
53+
return inputStream.Dequeue();
54+
}
55+
}
56+
public string ReadLine { get { return _stream.ReadLine(); } }
57+
public int ReadInt { get { return int.Parse(Read); } }
58+
public long ReadLong { get { return long.Parse(Read); } }
59+
public double ReadDouble { get { return double.Parse(Read); } }
60+
public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret;}
61+
public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret;}
62+
public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret;}
63+
}

tests/check_autopep8

Whitespace-only changes.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Text;
3+
using System.Linq;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
using static System.Console;
7+
using static System.Math;
8+
9+
public class Program{
10+
public static void Main(string[] args){
11+
ConsoleInput cin = new ConsoleInput(Console.In, ' ');
12+
${input_part}
13+
new Program().Solve(${actual_arguments});
14+
}
15+
16+
public void Solve(${formal_arguments}){
17+
18+
}
19+
}
20+
21+
public class ConsoleInput{
22+
private readonly System.IO.TextReader _stream;
23+
private char _separator = ' ';
24+
private Queue<string> inputStream;
25+
public ConsoleInput(System.IO.TextReader stream, char separator = ' '){
26+
this._separator = separator;
27+
this._stream = stream;
28+
inputStream = new Queue<string>();
29+
}
30+
public string Read{
31+
get{
32+
if (inputStream.Count != 0) return inputStream.Dequeue();
33+
string[] tmp = _stream.ReadLine().Split(_separator);
34+
for (int i = 0; i < tmp.Length; ++i)
35+
inputStream.Enqueue(tmp[i]);
36+
return inputStream.Dequeue();
37+
}
38+
}
39+
public string ReadLine { get { return _stream.ReadLine(); } }
40+
public int ReadInt { get { return int.Parse(Read); } }
41+
public long ReadLong { get { return long.Parse(Read); } }
42+
public double ReadDouble { get { return double.Parse(Read); } }
43+
public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret;}
44+
public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret;}
45+
public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret;}
46+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.Text;
3+
using System.Linq;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
using static System.Console;
7+
using static System.Math;
8+
9+
public class Program{
10+
{% if mod %}
11+
const long MOD = {{ mod }};
12+
{% endif %}
13+
{% if yes_str %}
14+
const string YES = "{{ yes_str }}";
15+
{% endif %}
16+
{% if no_str %}
17+
const string NO = "{{ no_str }}";
18+
{% endif %}
19+
20+
public static void Main(string[] args){
21+
ConsoleInput cin = new ConsoleInput(Console.In, ' ');
22+
{{ input_part }}
23+
new Program().Solve({{ actual_arguments }});
24+
}
25+
26+
public void Solve({{ formal_arguments }}){
27+
28+
}
29+
}
30+
31+
public class ConsoleInput{
32+
private readonly System.IO.TextReader _stream;
33+
private char _separator = ' ';
34+
private Queue<string> inputStream;
35+
public ConsoleInput(System.IO.TextReader stream, char separator = ' '){
36+
this._separator = separator;
37+
this._stream = stream;
38+
inputStream = new Queue<string>();
39+
}
40+
public string Read{
41+
get{
42+
if (inputStream.Count != 0) return inputStream.Dequeue();
43+
string[] tmp = _stream.ReadLine().Split(_separator);
44+
for (int i = 0; i < tmp.Length; ++i)
45+
inputStream.Enqueue(tmp[i]);
46+
return inputStream.Dequeue();
47+
}
48+
}
49+
public string ReadLine { get { return _stream.ReadLine(); } }
50+
public int ReadInt { get { return int.Parse(Read); } }
51+
public long ReadLong { get { return long.Parse(Read); } }
52+
public double ReadDouble { get { return double.Parse(Read); } }
53+
public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret;}
54+
public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret;}
55+
public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret;}
56+
}

0 commit comments

Comments
 (0)