Skip to content

Commit df75acb

Browse files
committed
add Java interface
1 parent 68a961c commit df75acb

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

src/lpg/interfaces/file.py

+2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66

77
from .lang.base import BaseLanguageInterface
88
from .lang.c import CLanguageInterface
9+
from .lang.java import JavaLanguageInterface
910
from .lang.javascript import JavaScriptLanguageInterface
1011
from .lang.python import PythonLanguageInterface
1112
from .lang.python3 import Python3LanguageInterface
1213
from .lang.typescript import TypeScriptLanguageInterface
1314

1415
LANGUAGE_INTERFACES: dict[str, BaseLanguageInterface] = {
1516
"c": CLanguageInterface(),
17+
"java": JavaLanguageInterface(),
1618
"javascript": JavaScriptLanguageInterface(),
1719
"typescript": TypeScriptLanguageInterface(),
1820
"python": PythonLanguageInterface(),

src/lpg/interfaces/lang/c.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@
2020
"""
2121

2222
FUNCTION_SIGNATURE_PATTERN = re.compile(
23-
r"""
24-
^(?P<returnType>(?:struct\s)?\w+(?:\[\]|\s?\*+)?)\s(?P<name>\w+)
25-
\((?P<params>(?:(?:struct\s)?\w+(?:\[\]|\s?\*+)?\s\w+(?:,\s)?)+)\)\s?{$
26-
""",
27-
flags=re.MULTILINE | re.VERBOSE,
23+
r"^(?P<returnType>(?:struct\s)?\w+(?:\[\]|\s?\*+)?) (?P<name>\w+)\((?P<params>[^)]+)\)\s?{$",
24+
flags=re.MULTILINE,
2825
)
2926

3027
SOLUTION_REPLACEMENT_PATTERN = re.compile(r"\n}")

src/lpg/interfaces/lang/java.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"""Project generator for the Java language."""
2+
3+
import re
4+
5+
from .base import BaseLanguageInterface
6+
7+
TEST_FILE_TEMPLATE = """\
8+
9+
public class Test {{
10+
public static void main(String[] args) {{
11+
{params_setup};
12+
{result_var_declaration}new Solution().{name}({params_call});
13+
System.out.printf("{OUTPUT_RESULT_PREFIX} %s\\n", {result_var});
14+
}}
15+
}}
16+
"""
17+
18+
FUNCTION_SIGNATURE_PATTERN = re.compile(
19+
r"public (?P<returnType>[^\s]+) (?P<name>\w+(?:\[\]|\s?\*+)?)\((?P<params>[^)]*)\)\s?{$",
20+
flags=re.MULTILINE,
21+
)
22+
23+
24+
SOLUTION_REPLACEMENT_PATTERN = re.compile(r"\n }")
25+
SOLUTION_REPLACEMENT_TEMPLATE = "return {return_value};\n }}"
26+
SUPPLEMENTAL_FILENAME_PATTERN = re.compile(r"public class (\w+) {")
27+
UTIL_IMPORT_TEMPLATE = "import java.util.*;\n\n"
28+
29+
30+
class JavaLanguageInterface(BaseLanguageInterface):
31+
"""Implementation of the Java language project template interface."""
32+
33+
function_signature_pattern = FUNCTION_SIGNATURE_PATTERN
34+
test_command = ["java", "Test"]
35+
36+
@property
37+
def compile_command(self):
38+
args = ["javac", "Solution.java", "Test.java"]
39+
40+
supplemental_filename = self.get_supplemental_filename()
41+
if supplemental_filename is not None:
42+
args.append(supplemental_filename)
43+
44+
return args
45+
46+
@property
47+
def default_output(self):
48+
return self.get_default_value(self.groups["returnType"])
49+
50+
def get_supplemental_filename(self):
51+
"""Obtains the name of the supplemental file."""
52+
code = self.groups["supplemental_code"]
53+
if not code:
54+
return None
55+
return f"{SUPPLEMENTAL_FILENAME_PATTERN.search(code).group(1)}.java"
56+
57+
def get_default_value(self, variable_type: str):
58+
"""Obtains the default value for a given variable type."""
59+
return {"boolean": "false", "int": "0", "void": "0"}.get(variable_type, "null")
60+
61+
def prepare_project_files(self, template: str):
62+
params = self.groups["params"].split(", ")
63+
self.groups["params_setup"] = ";\n ".join(
64+
f"{param} = {self.get_default_value(param.split()[0])}"
65+
for param in self.groups["params"].split(", ")
66+
)
67+
self.groups["params_call"] = ", ".join(param.split()[-1] for param in params)
68+
69+
if self.groups["returnType"] == "void":
70+
self.groups["result_var_declaration"] = ""
71+
self.groups["result_var"] = "0"
72+
formatted_template = template
73+
else:
74+
self.groups["result_var_declaration"] = (
75+
f"{self.groups['returnType']} result = "
76+
)
77+
self.groups["result_var"] = "result"
78+
formatted_template = re.sub(
79+
SOLUTION_REPLACEMENT_PATTERN,
80+
SOLUTION_REPLACEMENT_TEMPLATE.format(return_value=self.default_output),
81+
template,
82+
)
83+
84+
project_files = {
85+
"Solution.java": f"{UTIL_IMPORT_TEMPLATE}{formatted_template}\n",
86+
"Test.java": UTIL_IMPORT_TEMPLATE
87+
+ TEST_FILE_TEMPLATE.format(**self.groups),
88+
}
89+
if self.groups["supplemental_code"]:
90+
filename = self.get_supplemental_filename()
91+
project_files[filename] = self.groups["supplemental_code"]
92+
return project_files

0 commit comments

Comments
 (0)