Skip to content

Commit bb28bd7

Browse files
authored
support go (#235)
* support go * goのcompilerテストを追加 * タブインデントのロジックを変更
1 parent e12602b commit bb28bd7

File tree

28 files changed

+767
-13
lines changed

28 files changed

+767
-13
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
2+
from atcodertools.codegen.template_engine import render
3+
4+
from atcodertools.codegen.code_generators.universal_code_generator import UniversalCodeGenerator, get_builtin_code_generator_info_toml_path
5+
6+
7+
def main(args: CodeGenArgs) -> str:
8+
code_parameters = UniversalCodeGenerator(
9+
args.format, args.config, get_builtin_code_generator_info_toml_path("go")).generate_parameters()
10+
return render(
11+
args.template,
12+
mod=args.constants.mod,
13+
yes_str=args.constants.yes_str,
14+
no_str=args.constants.no_str,
15+
**code_parameters
16+
)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
base_indent = 1
2+
insert_space_around_operators = false
3+
4+
# global変数宣言時の接頭辞
5+
global_prefix = ""
6+
7+
# ループ
8+
[loop]
9+
header = "for {loop_var} := int64(0); {loop_var} < {length}; {loop_var}++ {{"
10+
footer = "}}"
11+
12+
# タイプ
13+
[type]
14+
int = "int64"
15+
float = "float64"
16+
str = "string"
17+
18+
# デフォルト値
19+
[default]
20+
int = "0"
21+
float = "0.0"
22+
str = '""'
23+
24+
# 引数
25+
[arg]
26+
int = "{name} int64"
27+
float = "{name} float64"
28+
str = "{name} string"
29+
seq = "{name} []{type}"
30+
2d_seq = "{name} [][]{type}"
31+
32+
# 配列アクセス
33+
[access]
34+
seq = "{name}[{index}]"
35+
2d_seq = "{name}[{index_i}][{index_j}]"
36+
37+
# 宣言
38+
[declare]
39+
int = "var {name} int64"
40+
float = "var {name} float64"
41+
str = "var {name} string"
42+
seq = "var {name} []{type}"
43+
2d_seq = "var {name} [][]{type}"
44+
45+
# 確保
46+
[allocate]
47+
seq = "{name} = make([]{type}, {length})"
48+
2d_seq = "{name} = make([][]{type}, {length_i})\nfor i := int64(0); i < {length_i}; i++ {{\n\t{name}[i] = make([]{type}, {length_j})\n}}"
49+
50+
# 宣言と確保
51+
[declare_and_allocate]
52+
seq = "{name} := make([]{type}, {length})"
53+
2d_seq = "{name} := make([][]{type}, {length_i})\nfor i := int64(0); i < {length_i}; i++ {{\n\t{name}[i] = make([]{type}, {length_j})\n}}"
54+
55+
# 入力
56+
[input]
57+
int = "scanner.Scan()\n{name}, _ = strconv.ParseInt(scanner.Text(), 10, 64)"
58+
float = "scanner.Scan()\n{name}, _ = strconv.ParseFloat(scanner.Text(), 64)"
59+
str = "scanner.Scan()\n{name} = scanner.Text()"

atcodertools/codegen/code_style_config.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class CodeStyleConfigInitError(Exception):
1919
class CodeStyleConfig:
2020

2121
def __init__(self,
22-
indent_type: str = INDENT_TYPE_SPACE,
22+
indent_type: str = None,
2323
indent_width: Optional[int] = None,
2424
code_generator_file: Optional[str] = None,
2525
template_file: Optional[str] = None,
@@ -37,7 +37,7 @@ def __init__(self,
3737
raise CodeStyleConfigInitError(
3838
"language must be one of {}".format(ALL_LANGUAGE_NAMES))
3939

40-
if indent_type not in [INDENT_TYPE_SPACE, INDENT_TYPE_TAB]:
40+
if indent_type is not None and indent_type not in [INDENT_TYPE_SPACE, INDENT_TYPE_TAB]:
4141
raise CodeStyleConfigInitError(
4242
"indent_type must be 'space' or 'tab'")
4343

@@ -54,15 +54,25 @@ def __init__(self,
5454
"The specified template file '{}' is not found".format(
5555
template_file)
5656
)
57-
58-
self.indent_type = indent_type
57+
if indent_type is not None:
58+
self.indent_type = indent_type
59+
elif lang.default_code_style is not None and lang.default_code_style.indent_type is not None:
60+
self.indent_type = lang.default_code_style.indent_type
61+
else:
62+
self.indent_type = INDENT_TYPE_SPACE
5963

6064
if indent_width is not None:
6165
self.indent_width = indent_width
6266
elif lang.default_code_style is not None and lang.default_code_style.indent_width is not None:
6367
self.indent_width = lang.default_code_style.indent_width
6468
else:
65-
self.indent_width = 4
69+
if self.indent_type == INDENT_TYPE_SPACE:
70+
self.indent_width = 4
71+
elif self.indent_type == INDENT_TYPE_TAB:
72+
self.indent_width = 1
73+
else:
74+
raise CodeStyleConfigInitError(
75+
"indent_type must be 'space' or 'tab'")
6676

6777
if code_generator_file is not None:
6878
try:
@@ -84,4 +94,8 @@ def __init__(self,
8494
def indent(self, depth):
8595
if self.indent_type == INDENT_TYPE_SPACE:
8696
return " " * self.indent_width * depth
87-
return "\t" * self.indent_width * depth
97+
elif self.indent_type == INDENT_TYPE_TAB:
98+
return "\t" * self.indent_width * depth
99+
else:
100+
raise CodeStyleConfigInitError(
101+
"indent_type must be 'space' or 'tab'")

atcodertools/common/language.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import re
22
from typing import Pattern, Callable
33

4-
from atcodertools.codegen.code_generators import cpp, java, rust, python, nim, d, cs, swift
4+
from atcodertools.codegen.code_generators import cpp, java, rust, python, nim, d, cs, swift, go
55
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
66
from atcodertools.tools.templates import get_default_template_path
7+
from atcodertools.codegen.code_style_config import INDENT_TYPE_TAB
78
import platform
89

910

@@ -13,9 +14,11 @@ class LanguageNotFoundError(Exception):
1314

1415
class CodeStyle:
1516
def __init__(self,
16-
indent_width=None
17+
indent_width=None,
18+
indent_type=None
1719
):
1820
self.indent_width = indent_width
21+
self.indent_type = indent_type
1922

2023

2124
class Language:
@@ -178,6 +181,19 @@ def from_name(cls, name: str):
178181
exec_filename="{filename}{exec_extension}"
179182
)
180183

184+
GO = Language(
185+
name="go",
186+
display_name="Go",
187+
extension="go",
188+
submission_lang_pattern=re.compile(".*Go \\(1.*"),
189+
default_code_generator=go.main,
190+
default_template_path=get_default_template_path('go'),
191+
default_code_style=CodeStyle(indent_type=INDENT_TYPE_TAB),
192+
compile_command="go build -o {filename} {filename}.go",
193+
test_command="{exec_filename}",
194+
exec_filename="{filename}{exec_extension}"
195+
)
196+
181197

182-
ALL_LANGUAGES = [CPP, JAVA, RUST, PYTHON, NIM, DLANG, CSHARP, SWIFT]
198+
ALL_LANGUAGES = [CPP, JAVA, RUST, PYTHON, NIM, DLANG, CSHARP, SWIFT, GO]
183199
ALL_LANGUAGE_NAMES = [lang.display_name for lang in ALL_LANGUAGES]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
{% if prediction_success %}
3+
4+
import (
5+
"bufio"
6+
"os"
7+
"strconv"
8+
)
9+
{% endif %}
10+
{% if mod or yes_str or no_str %}
11+
12+
{% endif %}
13+
{% if mod %}
14+
const MOD = {{mod}}
15+
{% endif %}
16+
{% if yes_str %}
17+
const YES = "{{ yes_str }}"
18+
{% endif %}
19+
{% if no_str %}
20+
const NO = "{{ no_str }}"
21+
{% endif %}
22+
{% if prediction_success %}
23+
24+
func solve({{ formal_arguments }}) {
25+
26+
}
27+
{% endif %}
28+
29+
func main() {
30+
{% if prediction_success %}
31+
scanner := bufio.NewScanner(os.Stdin)
32+
const initialBufSize = 4096
33+
const maxBufSize = 1000000
34+
scanner.Buffer(make([]byte, initialBufSize), maxBufSize)
35+
scanner.Split(bufio.ScanWords)
36+
{{ input_part }}
37+
solve({{ actual_arguments }})
38+
{% else %}
39+
// Failed to predict input format
40+
{% endif %}
41+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"os"
6+
"strconv"
7+
)
8+
9+
func solve(${formal_arguments}) {
10+
11+
}
12+
13+
func main() {
14+
scanner := bufio.NewScanner(os.Stdin)
15+
const initialBufSize = 4096
16+
const maxBufSize = 1000000
17+
scanner.Buffer(make([]byte, initialBufSize), maxBufSize)
18+
scanner.Split(bufio.ScanWords)
19+
${input_part}
20+
solve(${actual_arguments})
21+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
{% if prediction_success %}
3+
4+
import (
5+
"bufio"
6+
"os"
7+
"strconv"
8+
)
9+
{% endif %}
10+
{% if mod or yes_str or no_str %}
11+
12+
{% endif %}
13+
{% if mod %}
14+
const MOD = {{mod}}
15+
{% endif %}
16+
{% if yes_str %}
17+
const YES = "{{ yes_str }}"
18+
{% endif %}
19+
{% if no_str %}
20+
const NO = "{{ no_str }}"
21+
{% endif %}
22+
{% if prediction_success %}
23+
24+
func solve({{ formal_arguments }}) {
25+
26+
}
27+
{% endif %}
28+
29+
func main() {
30+
{% if prediction_success %}
31+
scanner := bufio.NewScanner(os.Stdin)
32+
const initialBufSize = 4096
33+
const maxBufSize = 1000000
34+
scanner.Buffer(make([]byte, initialBufSize), maxBufSize)
35+
scanner.Split(bufio.ScanWords)
36+
{{ input_part }}
37+
solve({{ actual_arguments }})
38+
{% else %}
39+
// Failed to predict input format
40+
{% endif %}
41+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package main
2+
{% if prediction_success %}
3+
4+
import (
5+
"bufio"
6+
"fmt"
7+
"log"
8+
"os"
9+
"strconv"
10+
)
11+
{% endif %}
12+
{% if mod or yes_str or no_str %}
13+
14+
{% endif %}
15+
{% if mod %}
16+
const MOD = {{mod}}
17+
{% endif %}
18+
{% if yes_str %}
19+
const YES = "{{ yes_str }}"
20+
{% endif %}
21+
{% if no_str %}
22+
const NO = "{{ no_str }}"
23+
{% endif %}
24+
{% if prediction_success %}
25+
26+
func solve({{ formal_arguments }}) {
27+
fmt.Printf("%d %d\n", N, M)
28+
if int64(len(H)) != N-1 {
29+
log.Fatal()
30+
}
31+
for i := int64(0); i < N-1; i++ {
32+
if int64(len(H[i])) != M-2 {
33+
log.Fatal()
34+
}
35+
for j := int64(0); j < M-2; j++ {
36+
if j > 0 {
37+
fmt.Printf(" %s", H[i][j])
38+
} else {
39+
fmt.Printf("%s", H[i][j])
40+
}
41+
}
42+
fmt.Println()
43+
}
44+
45+
if int64(len(A)) != N-1 {
46+
log.Fatal()
47+
}
48+
if int64(len(B)) != N-1 {
49+
log.Fatal()
50+
}
51+
for i := int64(0); i < N-1; i++ {
52+
fmt.Printf("%d %.1f\n", A[i], B[i])
53+
}
54+
55+
fmt.Println(Q)
56+
if int64(len(X)) != M+Q {
57+
log.Fatal()
58+
}
59+
for i := int64(0); i < M+Q; i++ {
60+
fmt.Println(X[i])
61+
}
62+
63+
fmt.Println(YES)
64+
fmt.Println(NO)
65+
fmt.Println(MOD)
66+
}
67+
{% endif %}
68+
69+
func main() {
70+
{% if prediction_success %}
71+
scanner := bufio.NewScanner(os.Stdin)
72+
const initialBufSize = 4096
73+
const maxBufSize = 1000000
74+
scanner.Buffer(make([]byte, initialBufSize), maxBufSize)
75+
scanner.Split(bufio.ScanWords)
76+
{{ input_part }}
77+
solve({{ actual_arguments }})
78+
{% else %}
79+
// Failed to predict input format
80+
{% endif %}
81+
}

0 commit comments

Comments
 (0)