Skip to content

Commit

Permalink
add parentheses to fix explicit typing + remove explicit typing in fe…
Browse files Browse the repository at this point in the history
…edback
  • Loading branch information
tibvdm committed Oct 2, 2024
1 parent 7df8f0d commit ae51fae
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ venv-*/
.venv/
node_modules/
result/
.data/
12 changes: 9 additions & 3 deletions tested/languages/haskell/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
from pathlib import Path
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional

from tested.datatypes import AllTypes
from tested.dodona import AnnotateCode, Message
Expand Down Expand Up @@ -28,6 +28,10 @@


class Haskell(Language):
def __init__(self, config: Optional["GlobalConfig"]):
super().__init__(config)
self.clean_types_regex = re.compile(r"\(([^:\s]*)\s*::\s*([A-Z][a-zA-Z0-9]*)\)")

def initial_dependencies(self) -> list[str]:
return ["Values.hs", "EvaluationUtils.hs"]

Expand Down Expand Up @@ -111,7 +115,7 @@ def linter(self, remaining: float) -> tuple[list[Message], list[AnnotateCode]]:
return linter.run_hlint(self.config.dodona, remaining)

def cleanup_description(self, statement: str) -> str:
return cleanup_description(self, statement)
return cleanup_description(self, self.clean_types_regex.sub(r'\1', statement))

def cleanup_stacktrace(self, stacktrace: str) -> str:
filename = submission_file(self)
Expand Down Expand Up @@ -165,11 +169,13 @@ def cleanup_stacktrace(self, stacktrace: str) -> str:
def generate_statement(self, statement: Statement) -> str:
from tested.languages.haskell import generators

return generators.convert_statement(statement)
return self.clean_types_regex.sub(r'\1', generators.convert_statement(statement))

def generate_execution_unit(self, execution_unit: "PreparedExecutionUnit") -> str:
from tested.languages.haskell import generators

print(generators.convert_execution_unit(execution_unit))

return generators.convert_execution_unit(execution_unit)

def generate_selector(self, contexts: list[str]) -> str:
Expand Down
21 changes: 10 additions & 11 deletions tested/languages/haskell/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,45 +40,44 @@
def convert_arguments(arguments: list[Expression]) -> str:
return ", ".join(convert_statement(arg) for arg in arguments)


def convert_value(value: Value) -> str:
# Handle some advanced types.
if value.type == AdvancedSequenceTypes.TUPLE:
assert isinstance(value, SequenceType)
return f"({convert_arguments(value.data)})"
elif isinstance(value.type, AdvancedNumericTypes):
if not isinstance(value.data, SpecialNumbers):
return f"{value.data} :: {convert_declaration(value.type)}"
return f"({value.data} :: {convert_declaration(value.type)})"
elif value.data == SpecialNumbers.NOT_A_NUMBER:
return f"(0/0) :: {convert_declaration(value.type)}"
return f"((0/0) :: {convert_declaration(value.type)})"
elif value.data == SpecialNumbers.POS_INFINITY:
return f"(1/0) :: {convert_declaration(value.type)}"
return f"((1/0) :: {convert_declaration(value.type)})"
else:
assert value.data == SpecialNumbers.NEG_INFINITY
return f"(-1/0) :: {convert_declaration(value.type)}"
return f"((-1/0) :: {convert_declaration(value.type)})"
elif value.type == AdvancedStringTypes.CHAR:
assert isinstance(value, StringType)
return "'" + value.data.replace("'", "\\'") + "'"
# Handle basic types
value = as_basic_type(value)
if value.type == BasicNumericTypes.INTEGER:
return f"{value.data} :: Int"
return f"({value.data} :: Int)"
elif value.type == BasicNumericTypes.REAL:
if not isinstance(value.data, SpecialNumbers):
return f"{value.data} :: Double"
return f"({value.data} :: Double)"
elif value.data == SpecialNumbers.NOT_A_NUMBER:
return "(0/0) :: Double"
return "((0/0) :: Double)"
elif value.data == SpecialNumbers.POS_INFINITY:
return "(1/0) :: Double"
return "((1/0) :: Double)"
else:
assert SpecialNumbers.NEG_INFINITY
return "(-1/0) :: Double"
return "((-1/0) :: Double)"
elif value.type == BasicStringTypes.TEXT:
return json.dumps(value.data)
elif value.type == BasicBooleanTypes.BOOLEAN:
return str(value.data)
elif value.type == BasicNothingTypes.NOTHING:
return "Nothing :: Maybe Integer"
return "(Nothing :: Maybe Integer)"
elif value.type == BasicSequenceTypes.SEQUENCE:
assert isinstance(value, SequenceType)
return f"[{convert_arguments(value.data)}]"
Expand Down
4 changes: 2 additions & 2 deletions tested/manual.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ def read_config() -> DodonaConfig:
programming_language=SupportedLanguage("haskell"),
natural_language="nl",
resources=Path(exercise_dir, "evaluation"),
source=Path(exercise_dir, "solution/voorlaatste.hs"),
source=Path(exercise_dir, "solution/ndeElement.hs"),
judge=Path("."),
workdir=Path("workdir"),
test_suite="voorlaatste.yaml",
test_suite="ndeElement.yaml",
options=Options(
linter=False,
),
Expand Down
16 changes: 16 additions & 0 deletions tests/exercises/haskell/evaluation/ndeElement.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
tabs:
- tab: geefNde
testcases:
- expression: geefNde(0, [1, 2, 3, 4])
description:
description: geefNde 0 [1, 2, 3, 4]
format: haskell
return: 1
- expression: geefNde(0, [1.0, 2.0, 3.0, 4.0])
return: 1.0
- expression: geefNde(0, ['a', 'b', 'c', 'd'])
return: a
- expression: geefNde(1, [(1, 2), (3, 4), (5, 6), (7, 8)])
return: !tuple [3, 4]
- expression: geefNde(1, [(1.0, 2.0), (3.0, 4.0), (5.0, 6.0), (7.0, 8.0)])
return: !tuple [3.0, 4.0]
2 changes: 2 additions & 0 deletions tests/exercises/haskell/solution/ndeElement.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
geefNde :: Int -> [a] -> a
geefNde n l = l !! n

0 comments on commit ae51fae

Please sign in to comment.