-
Notifications
You must be signed in to change notification settings - Fork 7
Add C++ #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add C++ #532
Changes from all commits
Commits
Show all changes
75 commits
Select commit
Hold shift + click to select a range
5cec4da
Get first c++ judgements up and running
jorg-vr 201d060
Minimize code duplication
jorg-vr d73aad9
Add runtime error
jorg-vr d454083
Add support for objects
jorg-vr 5bd19b3
Support echo function
jorg-vr 895fbb7
Add test files
jorg-vr 52a9c8d
Implement test
jorg-vr d367fe5
Add file function test
jorg-vr 2ec43b9
Add file function test
jorg-vr 7eaad24
Fix isbn exercise
jorg-vr 9a8dde2
Solve isbn list
jorg-vr ef40fd8
Solve isbn list
jorg-vr ccf5a85
Solve lotto
jorg-vr c6a11bf
Solve objects
jorg-vr c97aacd
Solve objects
jorg-vr 2af1bbc
Solve remove
jorg-vr ef13853
Solve sum
jorg-vr 866c86f
Fix some tests
jorg-vr e5ff917
Improve linting
jorg-vr ac636db
Merge branch 'master' into feat/add-cpp
jorg-vr d133425
Fix multiple edge cases
jorg-vr c1841ae
Fix escaped strings testcase
jorg-vr ad4fba7
Fix specific argument tests
jorg-vr 4598da3
Remove forced string typing
jorg-vr 32010e9
Fix string type as text
jorg-vr a28267f
Fix types and formatting
jorg-vr f4b45c1
Don't inherit from C config
jorg-vr d25f8df
Don't inherrit from C generators.py
jorg-vr 095b812
Improve whitespace layout of result file
jorg-vr 71f063b
Simplify en merge types
jorg-vr 85b3804
Get rid of NULL
jorg-vr ffbe612
Remove unneeded newlines
jorg-vr d151e39
Convert vevaluation_result to actual cpp
jorg-vr 54db530
Standardize braces
jorg-vr 94094b8
Simplify write nothing
jorg-vr b8d41ab
Add cpp for more tests
jorg-vr 43ffd8c
Fix test_crashing_assignment_with_before
jorg-vr d765a58
Fix divission tests
jorg-vr 45a4c1c
Fix main definition
jorg-vr c898178
Fix test_assignment_and_use_in_expression
jorg-vr 9bd30de
Fix test_objects_chained
jorg-vr c480553
Fix test_counter_chained
jorg-vr 7bdca44
Fix test_property_assignment
jorg-vr 018ecf2
Fix linter
jorg-vr efe23ac
Fix main method signature
jorg-vr 8f09f15
Fix test_generic_exception_correct
jorg-vr 9e1f8c8
Fix test_generic_exception
jorg-vr 9341575
Fix test_specific_oracle_exception_syntax_error
jorg-vr d92c0aa
Fix test_specific_oracle_exception_runtime_exception
jorg-vr a511965
Fix test_specific_oracle_exception_wrong_exception
jorg-vr 44cdb39
test_io_function_display_no_multiline_exercise
jorg-vr 4501bc9
Fix basic types testcase
jorg-vr 664372b
Fix advanced types
jorg-vr 6f8c8d7
Fix special number types
jorg-vr 62ae29c
Fix linting
jorg-vr 39f1fc7
fix types
jorg-vr ff6ac60
Don't use 'using namespace std;'
jorg-vr 0db90b3
Don't use 'using namespace std;'
jorg-vr 9706fb6
Use variants instead of any where possible
jorg-vr 627519d
Test complex type conversion
jorg-vr 6606d7b
Fix test_advanced_types for haskell
jorg-vr daf3bda
Fix test_unknown_return_typ
jorg-vr e9ac84e
Compile on non streamable and move to c++20
jorg-vr 20defbb
Avoid use of pointers
jorg-vr 18eb21a
Avoid overzealous casting
jorg-vr c07ea57
Add support for static functions
jorg-vr 0b1a7ff
Replace c with modern cpp
jorg-vr a9e3df3
Cleanup stacktrace properly
jorg-vr f6d64ea
Fix parallel tests
jorg-vr 938eec7
Add jinja test
jorg-vr 03b7e3c
Fix linting
jorg-vr 1ac1037
Undo C changes
jorg-vr c96a386
Undo C changes
jorg-vr d3ac593
Clean up
jorg-vr bb33e5a
Fix csharp test
jorg-vr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -778,7 +778,8 @@ | |
| "kotlin", | ||
| "python", | ||
| "runhaskell", | ||
| "csharp" | ||
| "csharp", | ||
| "cpp" | ||
| ] | ||
| }, | ||
| "message" : { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -778,7 +778,8 @@ | |
| "kotlin", | ||
| "python", | ||
| "runhaskell", | ||
| "csharp" | ||
| "csharp", | ||
| "cpp" | ||
| ] | ||
| }, | ||
| "message" : { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,215 @@ | ||
| import re | ||
| from pathlib import Path | ||
|
|
||
| from tested.datatypes import AllTypes | ||
| from tested.dodona import AnnotateCode, Message | ||
| from tested.features import Construct, TypeSupport | ||
| from tested.languages.conventionalize import ( | ||
| Conventionable, | ||
| NamingConventions, | ||
| submission_file, | ||
| ) | ||
| from tested.languages.cpp.generators import CPPGenerator | ||
| from tested.languages.language import ( | ||
| CallbackResult, | ||
| Command, | ||
| Language, | ||
| TypeDeclarationMetadata, | ||
| ) | ||
| from tested.languages.preparation import PreparedExecutionUnit | ||
| from tested.languages.utils import executable_name | ||
| from tested.serialisation import Statement, Value | ||
|
|
||
|
|
||
| class CPP(Language): | ||
| def initial_dependencies(self) -> list[str]: | ||
| return [ | ||
| "values.h", | ||
| "values.cpp", | ||
| "values.tpp", | ||
| "evaluation_result.h", | ||
| "evaluation_result.cpp", | ||
| ] | ||
|
|
||
| def needs_selector(self): | ||
| return True | ||
|
|
||
| def file_extension(self) -> str: | ||
| return "cpp" | ||
|
|
||
| def comment(self, text: str) -> str: | ||
| return f"// {text}" | ||
|
|
||
| def naming_conventions(self) -> dict[Conventionable, NamingConventions]: | ||
| return { | ||
| "identifier": "camel_case", | ||
| "property": "camel_case", | ||
| "class": "pascal_case", | ||
| "global_identifier": "macro_case", | ||
| } | ||
|
|
||
| def supported_constructs(self) -> set[Construct]: | ||
| return { | ||
| Construct.FUNCTION_CALLS, | ||
| Construct.ASSIGNMENTS, | ||
| Construct.GLOBAL_VARIABLES, | ||
| Construct.OBJECTS, | ||
| Construct.HETEROGENEOUS_COLLECTIONS, | ||
| Construct.DEFAULT_PARAMETERS, | ||
| Construct.HETEROGENEOUS_ARGUMENTS, | ||
| Construct.EXCEPTIONS, | ||
| } | ||
|
|
||
| def datatype_support(self) -> dict[AllTypes, TypeSupport]: | ||
| return { # type: ignore | ||
| "integer": "supported", | ||
| "real": "supported", | ||
| "char": "supported", | ||
| "text": "supported", | ||
| "string": "supported", | ||
| "boolean": "supported", | ||
| "nothing": "supported", | ||
| "undefined": "reduced", | ||
| "null": "reduced", | ||
| "int8": "supported", | ||
| "uint8": "supported", | ||
| "int16": "supported", | ||
| "uint16": "supported", | ||
| "int32": "supported", | ||
| "uint32": "supported", | ||
| "int64": "supported", | ||
| "uint64": "supported", | ||
| "single_precision": "supported", | ||
| "double_precision": "supported", | ||
| "double_extended": "supported", | ||
| "sequence": "supported", | ||
| "set": "supported", | ||
| "map": "supported", | ||
| "dictionary": "supported", | ||
| "object": "reduced", | ||
| "array": "supported", | ||
| "list": "supported", | ||
| "tuple": "supported", | ||
| } | ||
|
|
||
| def compilation(self, files: list[str]) -> CallbackResult: | ||
| main_file = files[-1] | ||
| exec_file = Path(main_file).stem | ||
| result = executable_name(exec_file) | ||
| assert self.config | ||
| return ( | ||
| [ | ||
| "g++", | ||
| "-std=c++20", | ||
| "-Wall", | ||
| "-O3" if self.config.options.compiler_optimizations else "-O0", | ||
| "evaluation_result.cpp", | ||
| "values.cpp", | ||
| main_file, | ||
| "-o", | ||
| result, | ||
| ], | ||
| [result], | ||
| ) | ||
|
|
||
| def execution(self, cwd: Path, file: str, arguments: list[str]) -> Command: | ||
| local_file = cwd / executable_name(Path(file).stem) | ||
| return [str(local_file.absolute()), *arguments] | ||
|
|
||
| def modify_solution(self, solution: Path): | ||
| with open(solution, "r") as file: | ||
| contents = file.read() | ||
| # We use regex to find the main function. | ||
| # First, check if we have a no-arg main function. | ||
| # If so, replace it with a renamed main function that does have args. | ||
| no_args = re.compile(r"(int|void)(\s+)main(\s*)\((\s*)\)(\s*{)") | ||
| replacement = r"int\2solution_main\3(\4int argc, char* argv[])\5" | ||
| contents, nr = re.subn(no_args, replacement, contents, count=1) | ||
| if nr == 0: | ||
| # There was no main function without arguments. Now we try a main | ||
| # function with arguments. | ||
| with_args = re.compile(r"(int|void)(\s+)main(\s*)\((\s*)int") | ||
| replacement = r"int\2solution_main\3(\4int" | ||
| contents = re.sub(with_args, replacement, contents, count=1) | ||
| with open(solution, "w") as file: | ||
| header = "#pragma once\n\n" | ||
| file.write(header + contents) | ||
|
|
||
| def linter(self, remaining: float) -> tuple[list[Message], list[AnnotateCode]]: | ||
| # Import locally to prevent errors. | ||
| from tested.languages.c import linter | ||
|
|
||
| assert self.config | ||
| return linter.run_cppcheck(self.config.dodona, remaining, "c++") | ||
|
|
||
| def cleanup_stacktrace(self, stacktrace: str) -> str: | ||
| result = "" | ||
| in_student_file = False | ||
| for line in stacktrace.splitlines(keepends=True): | ||
| if submission_file(self) in line: | ||
| in_student_file = True | ||
| elif "|" not in line: | ||
| in_student_file = False | ||
|
|
||
| if in_student_file: | ||
| line = line.replace(submission_file(self), "<code>") | ||
| result += line | ||
| return result | ||
|
|
||
| def is_source_file(self, file: Path) -> bool: | ||
| return file.suffix in (".cpp", ".h", ".tpp") | ||
|
|
||
| def generator(self) -> CPPGenerator: | ||
| return CPPGenerator(self.file_extension()) | ||
|
|
||
| def generate_statement(self, statement: Statement) -> str: | ||
| return self.generator().convert_statement(statement) | ||
|
|
||
| def generate_execution_unit(self, execution_unit: "PreparedExecutionUnit") -> str: | ||
| return self.generator().convert_execution_unit(execution_unit) | ||
|
|
||
| def generate_selector(self, contexts: list[str]) -> str: | ||
| return self.generator().convert_selector(contexts) | ||
|
|
||
| def generate_encoder(self, values: list[Value]) -> str: | ||
| return self.generator().convert_encoder(values) | ||
|
|
||
| def get_declaration_metadata(self) -> TypeDeclarationMetadata: | ||
| return { | ||
| "names": { # type: ignore | ||
| "integer": "int", | ||
| "real": "double", | ||
| "char": "char", | ||
| "text": "std::string", | ||
| "string": "std::string", | ||
| "boolean": "bool", | ||
| "nothing": "void", | ||
| "undefined": "void", | ||
| "int8": "std::int8_t", | ||
| "uint8": "std::uint8_t", | ||
| "int16": "std::int16_t", | ||
| "uint16": "std::uint16_t", | ||
| "int32": "std::int32_t", | ||
| "uint32": "std::uint32_t", | ||
| "int64": "std::int64_t", | ||
| "uint64": "std::uint64_t", | ||
| "bigint": "std::intmax_t", | ||
| "single_precision": "float", | ||
| "double_precision": "double", | ||
| "any": "std::any", | ||
| "sequence": "std::vector", | ||
| "array": "std::vector", | ||
| "list": "std::list", | ||
| "tuple": "std::tuple", | ||
| "set": "std::set", | ||
| "map": "std::map", | ||
| }, | ||
| "nested": ("<", ">"), | ||
| "exception": "std::exception_ptr", | ||
| } | ||
|
|
||
| def is_void_method(self, name: str) -> bool: | ||
| assert self.config | ||
| regex = rf"void\s+{name}" | ||
| the_source = self.config.dodona.source.read_text() | ||
| return re.search(regex, the_source) is not None | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.