From 00280d9a1ed62f801750ee1bacb5c8a30500f0b1 Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 19 Dec 2023 13:36:09 +0200 Subject: [PATCH 1/6] check main function args --- src/typecheck.c | 18 ++++++++++++++---- tests/should_succeed/main_funny_arg_names.jou | 6 ++++++ tests/wrong_type/main_1_arg.jou | 2 ++ tests/wrong_type/main_3_args.jou | 2 ++ tests/wrong_type/main_argc.jou | 2 ++ tests/wrong_type/main_argv.jou | 2 ++ 6 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 tests/should_succeed/main_funny_arg_names.jou create mode 100644 tests/wrong_type/main_1_arg.jou create mode 100644 tests/wrong_type/main_3_args.jou create mode 100644 tests/wrong_type/main_argc.jou create mode 100644 tests/wrong_type/main_argv.jou diff --git a/src/typecheck.c b/src/typecheck.c index a7d034e3..d6037c99 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -245,10 +245,20 @@ static Signature handle_signature(FileTypes *ft, const AstSignature *astsig, con else sig.returntype = type_from_ast(ft, &astsig->returntype); - // TODO: validate main() parameters - // TODO: test main() taking parameters - if (!self_type && !strcmp(sig.name, "main") && sig.returntype != intType) { - fail_with_error(astsig->returntype.location, "the main() function must return int"); + if (!self_type && !strcmp(sig.name, "main")) { + // special main() function checks + if (sig.returntype != intType) + fail(astsig->returntype.location, "the main() function must return int"); + if (sig.nargs != 0 && !( + sig.nargs == 2 + && sig.argtypes[0] == intType + && sig.argtypes[1] == get_pointer_type(get_pointer_type(byteType)))) + { + fail( + astsig->returntype.location, + "if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int" + ); + } } sig.returntype_location = astsig->returntype.location; diff --git a/tests/should_succeed/main_funny_arg_names.jou b/tests/should_succeed/main_funny_arg_names.jou new file mode 100644 index 00000000..5a9a8336 --- /dev/null +++ b/tests/should_succeed/main_funny_arg_names.jou @@ -0,0 +1,6 @@ +import "stdlib/io.jou" + +# Usually the args are named "argc" and "argv" but this is also acceptable +def main(lol: int, wat: byte**) -> int: + printf("lol = %d\n", lol) # Output: lol = 1 + return 0 diff --git a/tests/wrong_type/main_1_arg.jou b/tests/wrong_type/main_1_arg.jou new file mode 100644 index 00000000..f1b62b84 --- /dev/null +++ b/tests/wrong_type/main_1_arg.jou @@ -0,0 +1,2 @@ +def main(argc: int) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int + return 0 diff --git a/tests/wrong_type/main_3_args.jou b/tests/wrong_type/main_3_args.jou new file mode 100644 index 00000000..5567c383 --- /dev/null +++ b/tests/wrong_type/main_3_args.jou @@ -0,0 +1,2 @@ +def main(a: int, b: int, c: int) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int + return 0 diff --git a/tests/wrong_type/main_argc.jou b/tests/wrong_type/main_argc.jou new file mode 100644 index 00000000..bd8bb02c --- /dev/null +++ b/tests/wrong_type/main_argc.jou @@ -0,0 +1,2 @@ +def main(argc: long, argv: byte**) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int + return 0 diff --git a/tests/wrong_type/main_argv.jou b/tests/wrong_type/main_argv.jou new file mode 100644 index 00000000..8f2b68d1 --- /dev/null +++ b/tests/wrong_type/main_argv.jou @@ -0,0 +1,2 @@ +def main(argc: int, argv: byte*) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int + return 0 From d9f7d61438a4d9e4e55002cf3fbd1d619d10690d Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 19 Dec 2023 13:36:34 +0200 Subject: [PATCH 2/6] ignore self hosted for now --- self_hosted/runs_wrong.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/self_hosted/runs_wrong.txt b/self_hosted/runs_wrong.txt index 02c37c70..d6085915 100644 --- a/self_hosted/runs_wrong.txt +++ b/self_hosted/runs_wrong.txt @@ -14,3 +14,7 @@ tests/wrong_type/cannot_be_indexed.jou tests/wrong_type/index.jou tests/syntax_error/assign_to_None.jou tests/syntax_error/None_as_value.jou +tests/wrong_type/main_1_arg.jou +tests/wrong_type/main_3_args.jou +tests/wrong_type/main_argc.jou +tests/wrong_type/main_argv.jou From bb8b49fb1b89692896209d47905d10e2e582663c Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 19 Dec 2023 13:39:15 +0200 Subject: [PATCH 3/6] fixed self hosted --- self_hosted/runs_wrong.txt | 4 ---- self_hosted/typecheck.jou | 17 +++++++++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/self_hosted/runs_wrong.txt b/self_hosted/runs_wrong.txt index d6085915..02c37c70 100644 --- a/self_hosted/runs_wrong.txt +++ b/self_hosted/runs_wrong.txt @@ -14,7 +14,3 @@ tests/wrong_type/cannot_be_indexed.jou tests/wrong_type/index.jou tests/syntax_error/assign_to_None.jou tests/syntax_error/None_as_value.jou -tests/wrong_type/main_1_arg.jou -tests/wrong_type/main_3_args.jou -tests/wrong_type/main_argc.jou -tests/wrong_type/main_argv.jou diff --git a/self_hosted/typecheck.jou b/self_hosted/typecheck.jou index 2b9d18f5..80b285c3 100644 --- a/self_hosted/typecheck.jou +++ b/self_hosted/typecheck.jou @@ -389,10 +389,19 @@ def handle_signature(ft: FileTypes*, astsig: AstSignature*, self_type: Type*) -> else: sig.return_type = type_from_ast(ft, &astsig->return_type) - # TODO: validate main() parameters - # TODO: test main() taking parameters - if self_type == NULL and strcmp(sig.name, "main") == 0 and sig.return_type != int_type: - fail(astsig->return_type.location, "the main() function must return int") + if self_type == NULL and strcmp(sig.name, "main") == 0: + # special main() function checks + if sig.return_type != int_type: + fail(astsig->return_type.location, "the main() function must return int") + if sig.nargs != 0 and not ( + sig.nargs == 2 + and sig.argtypes[0] == int_type + and sig.argtypes[1] == byte_type->get_pointer_type()->get_pointer_type() + ): + fail( + astsig->return_type.location, + "if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int" + ) return sig From 7b8ffa6bec4859f44a8b9288e3030f6729a4a722 Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 19 Dec 2023 13:43:19 +0200 Subject: [PATCH 4/6] fix location? --- self_hosted/typecheck.jou | 2 +- src/typecheck.c | 2 +- tests/wrong_type/main_1_arg.jou | 4 +++- tests/wrong_type/main_3_args.jou | 4 +++- tests/wrong_type/main_argc.jou | 4 +++- tests/wrong_type/main_argv.jou | 4 +++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/self_hosted/typecheck.jou b/self_hosted/typecheck.jou index 80b285c3..70461ed2 100644 --- a/self_hosted/typecheck.jou +++ b/self_hosted/typecheck.jou @@ -399,7 +399,7 @@ def handle_signature(ft: FileTypes*, astsig: AstSignature*, self_type: Type*) -> and sig.argtypes[1] == byte_type->get_pointer_type()->get_pointer_type() ): fail( - astsig->return_type.location, + astsig->args[0].type.location, "if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int" ) diff --git a/src/typecheck.c b/src/typecheck.c index d6037c99..e601a076 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -255,7 +255,7 @@ static Signature handle_signature(FileTypes *ft, const AstSignature *astsig, con && sig.argtypes[1] == get_pointer_type(get_pointer_type(byteType)))) { fail( - astsig->returntype.location, + astsig->args.ptr[0].type.location, "if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int" ); } diff --git a/tests/wrong_type/main_1_arg.jou b/tests/wrong_type/main_1_arg.jou index f1b62b84..7250996a 100644 --- a/tests/wrong_type/main_1_arg.jou +++ b/tests/wrong_type/main_1_arg.jou @@ -1,2 +1,4 @@ -def main(argc: int) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +def main( + argc: int # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +) -> int: return 0 diff --git a/tests/wrong_type/main_3_args.jou b/tests/wrong_type/main_3_args.jou index 5567c383..f91891ba 100644 --- a/tests/wrong_type/main_3_args.jou +++ b/tests/wrong_type/main_3_args.jou @@ -1,2 +1,4 @@ -def main(a: int, b: int, c: int) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +def main( + a: int, b: int, c: int # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +) -> int: return 0 diff --git a/tests/wrong_type/main_argc.jou b/tests/wrong_type/main_argc.jou index bd8bb02c..ef11e7c0 100644 --- a/tests/wrong_type/main_argc.jou +++ b/tests/wrong_type/main_argc.jou @@ -1,2 +1,4 @@ -def main(argc: long, argv: byte**) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +def main( + argc: long, argv: byte** # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +) -> int: return 0 diff --git a/tests/wrong_type/main_argv.jou b/tests/wrong_type/main_argv.jou index 8f2b68d1..a896919a 100644 --- a/tests/wrong_type/main_argv.jou +++ b/tests/wrong_type/main_argv.jou @@ -1,2 +1,4 @@ -def main(argc: int, argv: byte*) -> int: # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +def main( + argc: int, argv: byte* # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int +) -> int: return 0 From 7d96ef3256ae3b61ef18d399b88f82718d9666d1 Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 19 Dec 2023 14:10:59 +0200 Subject: [PATCH 5/6] Update tests/wrong_type/main_3_args.jou --- tests/wrong_type/main_3_args.jou | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wrong_type/main_3_args.jou b/tests/wrong_type/main_3_args.jou index f91891ba..43bf2b22 100644 --- a/tests/wrong_type/main_3_args.jou +++ b/tests/wrong_type/main_3_args.jou @@ -1,4 +1,4 @@ def main( - a: int, b: int, c: int # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int + argc: int, argv: byte**, lol: int # Error: if the main() function takes parameters, it should be defined like this: def main(argc: int, argv: byte**) -> int ) -> int: return 0 From 4321f8a3f82de2f98554e56f62ff0523f18ba502 Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 19 Dec 2023 14:21:11 +0200 Subject: [PATCH 6/6] Update tests/should_succeed/main_funny_arg_names.jou --- tests/should_succeed/main_funny_arg_names.jou | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/should_succeed/main_funny_arg_names.jou b/tests/should_succeed/main_funny_arg_names.jou index 5a9a8336..7322f8ef 100644 --- a/tests/should_succeed/main_funny_arg_names.jou +++ b/tests/should_succeed/main_funny_arg_names.jou @@ -1,6 +1,6 @@ import "stdlib/io.jou" -# Usually the args are named "argc" and "argv" but this is also acceptable +# Usually the args are named "argc" and "argv", but you can name them whatever you want. def main(lol: int, wat: byte**) -> int: printf("lol = %d\n", lol) # Output: lol = 1 return 0