From 50c3604dd297ba96795754e6d91c5997dd2a47d3 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 9 Apr 2020 15:08:48 +0200 Subject: [PATCH] Fixed variadic error. Fixed incorrect token type on decimal numbers(!) --- missing.txt | 1 + resources/testfragments/helloworld.c3 | 2 +- resources/testfragments/super_simple.c3 | 8 +++++--- src/compiler/lexer.c | 4 ++-- src/compiler/parse_expr.c | 2 +- src/compiler/parser.c | 10 +++++----- src/compiler/sema_expr.c | 6 ++++++ 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/missing.txt b/missing.txt index 597e4dcfa..c02d8e45d 100644 --- a/missing.txt +++ b/missing.txt @@ -56,6 +56,7 @@ Things missing: - Varargs - C ABI - Safe varargs +- Named parameters * Pre-post conditions - Breakdown here diff --git a/resources/testfragments/helloworld.c3 b/resources/testfragments/helloworld.c3 index 4e1710d70..72003c07d 100644 --- a/resources/testfragments/helloworld.c3 +++ b/resources/testfragments/helloworld.c3 @@ -1,6 +1,6 @@ module helloworld; -extern func void printf(char *str); +extern func void printf(char *str, ...); func void main() { diff --git a/resources/testfragments/super_simple.c3 b/resources/testfragments/super_simple.c3 index a2037ca35..f858530ab 100644 --- a/resources/testfragments/super_simple.c3 +++ b/resources/testfragments/super_simple.c3 @@ -372,7 +372,7 @@ typedef func void() as FEok; typedef func void(int) as Foo; //typedef int as Foo; -extern func void printf(char *hello); +extern func void printf(char *hello, ...); macro hello() { @@ -497,7 +497,7 @@ func int xxxx(int x) return 1; } -func int testPointers(int x) +func int testPointers(int x, int j = 0, double foo = 3.2) { 1 ? 1 : 2; int y = 0; @@ -515,9 +515,11 @@ func int testPointers(int x) func int main(int x) { printf("Helo!\n"); + testPointers(2, 3, 2.3); int efd = 9; uint fefoek = 1; - long fefoek = -fefoek; + printf("Helo: %d\n", efd + cast(fefoek, int)); + //long fefoek = -fefoek; int okfe = 1; return 1; switch (int bobe = okfe > 0 ? 1 : 0) diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 746335d4f..638d2244f 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -345,7 +345,7 @@ static inline Token scan_hex(Lexer *lexer) while (is_hex(peek(lexer))) next(lexer); } if (prev(lexer) == '_') return error_token(lexer, "The number ended with '_', but that character needs to be between, not after, digits."); - return make_token(lexer, is_float ? TOKEN_FLOAT : TOKEN_INTEGER, lexer->lexing_start); + return make_token(lexer, is_float ? TOKEN_REAL : TOKEN_INTEGER, lexer->lexing_start); } static inline Token scan_dec(Lexer *lexer) @@ -372,7 +372,7 @@ static inline Token scan_dec(Lexer *lexer) while (is_digit(peek(lexer))) next(lexer); } if (prev(lexer) == '_') return error_token(lexer, "The number ended with '_', but that character needs to be between, not after, digits."); - return make_token(lexer, is_float ? TOKEN_FLOAT : TOKEN_INTEGER, lexer->lexing_start); + return make_token(lexer, is_float ? TOKEN_REAL : TOKEN_INTEGER, lexer->lexing_start); } diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index bb05e6890..c09622bca 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -766,7 +766,7 @@ ParseRule rules[TOKEN_EOF + 1] = { [TOKEN_AT] = { parse_macro_expr, NULL, PREC_UNARY }, [TOKEN_CONST_IDENT] = { parse_identifier, NULL, PREC_NONE }, [TOKEN_STRING] = { parse_string_literal, NULL, PREC_NONE }, - [TOKEN_FLOAT] = { parse_double, NULL, PREC_NONE }, + [TOKEN_REAL] = { parse_double, NULL, PREC_NONE }, [TOKEN_OR] = { NULL, parse_binary, PREC_LOGICAL }, [TOKEN_AND] = { NULL, parse_binary, PREC_LOGICAL }, [TOKEN_EQ] = { NULL, parse_binary, PREC_ASSIGNMENT }, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index d04af80a0..4ab8f352b 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -931,6 +931,11 @@ static inline bool parse_opt_parameter_type_list(Context *context, Visibility pa CONSUME_OR(TOKEN_LPAREN, false); while (!try_consume(context, TOKEN_RPAREN)) { + if (signature->variadic) + { + SEMA_TOKEN_ERROR(context->tok, "Variadic arguments should be the last in a parameter list."); + return false; + } if (try_consume(context, TOKEN_ELIPSIS)) { signature->variadic = true; @@ -943,11 +948,6 @@ static inline bool parse_opt_parameter_type_list(Context *context, Visibility pa { EXPECT_OR(TOKEN_RPAREN, false); } - if (signature->variadic) - { - SEMA_TOKEN_ERROR(context->tok, "Variadic arguments should be the last in a parameter list."); - return false; - } } return true; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 7b829b01b..650d311c4 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -235,9 +235,15 @@ static inline bool sema_expr_analyse_func_call(Context *context, Type *to, Expr unsigned num_args = vec_size(args); // unsigned num_params = vec_size(func_params); // TODO handle named parameters, handle default parameters, varargs etc + unsigned func_param_count = vec_size(func_params); for (unsigned i = 0; i < num_args; i++) { Expr *arg = args[i]; + if (func_param_count >= i) + { + if (!sema_analyse_expr_of_required_type(context, NULL, arg)) return false; + continue; + } if (!sema_analyse_expr_of_required_type(context, func_params[i]->type, arg)) return false; } expr->type = decl->func.function_signature.rtype->type;