From bc4bf001809131fd7f3d706301b4cee2f1794de8 Mon Sep 17 00:00:00 2001 From: Elliot <35050275+apache-hb@users.noreply.github.com> Date: Wed, 7 Aug 2024 23:19:29 +0100 Subject: [PATCH] start fixing assignment to parameters --- data/examples/config/config.ct | 28 +++++++++++++++-- src/cthulhu/check/src/tree.c | 22 +++++++++++++- .../events/include/cthulhu/events/events.inc | 8 +++++ src/cthulhu/tree/include/cthulhu/tree/tree.h | 4 +-- .../tree/include/cthulhu/tree/tree.inc | 2 +- src/cthulhu/tree/src/tree.c | 2 +- src/language/ctu/src/ctu.y | 2 +- src/language/ctu/src/sema/expr.c | 30 +++++++++++++++++-- src/language/ctu/src/sema/sema.c | 1 + src/target/debug/src/ssa.c | 25 ++++++++++++++++ 10 files changed, 113 insertions(+), 11 deletions(-) diff --git a/data/examples/config/config.ct b/data/examples/config/config.ct index 161ac484..ec8759a8 100644 --- a/data/examples/config/config.ct +++ b/data/examples/config/config.ct @@ -50,6 +50,18 @@ struct Lexer { def isAlpha(letter: char): bool = (letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z'); def isSpace(letter: char): bool = letter == ' ' || letter == '\t' || letter == '\n' || letter == '\r'; +def readUntil(current: *char, terminator: char): StringView { + var front = current; + while *current != terminator && *current != '\0' { + current = current + 1; + } + + return .{ + front = front, + back = current + }; +} + export def openConfigFile(path: str): ConfigFile { var file = mapFileHandle(path); if file.fileView == null { @@ -63,8 +75,20 @@ export def openConfigFile(path: str): ConfigFile { while index < file.fileSize { const letter = file.fileView[index]; - while isSpace(letter) { - index += 1; + index = index + 1; + + if isSpace(letter) { + continue; + } + + if letter == '[' { + const name = readUntil(file.fileView + index, ']'); + + sections[file.sectionCount] = .{ + name = name, + firstEntry = file.entryCount, + lastEntry = file.entryCount + }; } if isAlpha(letter) { diff --git a/src/cthulhu/check/src/tree.c b/src/cthulhu/check/src/tree.c index c122209a..f4f8e278 100644 --- a/src/cthulhu/check/src/tree.c +++ b/src/cthulhu/check/src/tree.c @@ -467,6 +467,7 @@ static void check_single_expr(check_t *check, const tree_t *expr) case eTreeExprLoad: case eTreeDeclLocal: case eTreeDeclParam: + case eTreeDeclCase: case eTreeDeclFunction: break; @@ -502,6 +503,16 @@ static void check_assign(check_t *check, const tree_t *stmt) } } + printf("dst: %s\n", tree_to_string(stmt->dst)); + + if (tree_is(stmt->dst, eTreeDeclParam)) + { + msg_notify(check->reports, &kEvent_AssignToParam, tree_get_node(stmt), + "assignment to parameter `%s`", + tree_get_name(stmt->dst) + ); + } + check_single_expr(check, stmt->src); } @@ -511,6 +522,9 @@ static void check_func_body(check_t *check, const tree_t *return_type, const tre switch (stmt->kind) { + case eTreeStmtJump: + break; + case eTreeStmtBlock: for (size_t i = 0; i < vector_len(stmt->stmts); i++) { @@ -519,8 +533,14 @@ static void check_func_body(check_t *check, const tree_t *return_type, const tre break; case eTreeStmtLoop: - case eTreeStmtBranch: + case eTreeStmtBranch: { + check_func_body(check, return_type, stmt->then); + + if (stmt->other != NULL) + check_func_body(check, return_type, stmt->other); + break; + } case eTreeStmtAssign: check_assign(check, stmt); diff --git a/src/cthulhu/events/include/cthulhu/events/events.inc b/src/cthulhu/events/include/cthulhu/events/events.inc index 92d340e4..110f6c03 100644 --- a/src/cthulhu/events/include/cthulhu/events/events.inc +++ b/src/cthulhu/events/include/cthulhu/events/events.inc @@ -626,4 +626,12 @@ CTU_EVENT(NotAnAggregate, { "A type was not an aggregate type.", }) +CTU_EVENT(AssignToParam, { + .severity = eSeverityInternal, + .id = "M0085", + .brief = "Assign to param", + .description = + "A parameter was assigned to, if a frontend allows this it must create a local copy.", +}) + #undef CTU_EVENT diff --git a/src/cthulhu/tree/include/cthulhu/tree/tree.h b/src/cthulhu/tree/include/cthulhu/tree/tree.h index 146ba12f..8e34ddb5 100644 --- a/src/cthulhu/tree/include/cthulhu/tree/tree.h +++ b/src/cthulhu/tree/include/cthulhu/tree/tree.h @@ -85,7 +85,7 @@ typedef struct tree_t { /* eTreeExprRef */ struct { - tree_t *expr; + const tree_t *expr; /* eTreeExprCast */ tree_cast_t cast; @@ -370,7 +370,7 @@ CT_TREE_API tree_t *tree_expr_string(const node_t *node, const tree_t *type, con * @param cast the kind of cast to perform * @return tree_t* the cast expression */ -CT_TREE_API tree_t *tree_expr_cast(const node_t *node, const tree_t *type, tree_t *expr, tree_cast_t cast); +CT_TREE_API tree_t *tree_expr_cast(const node_t *node, const tree_t *type, const tree_t *expr, tree_cast_t cast); /** * @brief load a value from a pointer or storage diff --git a/src/cthulhu/tree/include/cthulhu/tree/tree.inc b/src/cthulhu/tree/include/cthulhu/tree/tree.inc index db292126..fd90d2fb 100644 --- a/src/cthulhu/tree/include/cthulhu/tree/tree.inc +++ b/src/cthulhu/tree/include/cthulhu/tree/tree.inc @@ -164,7 +164,7 @@ TREE_KIND(eTreeDeclAttrib, "decl_attrib", eTagName) TREE_KIND(eTreeDeclGlobal, "decl_global", eTagName | eTagStorage | eTagEval | eTagHasType) TREE_KIND(eTreeDeclLocal, "decl_local", eTagName | eTagStorage | eTagEval | eTagHasType) TREE_KIND(eTreeDeclParam, "decl_param", eTagName | eTagHasType) -TREE_KIND(eTreeDeclCase, "decl_case", eTagName) +TREE_KIND(eTreeDeclCase, "decl_case", eTagName | eTagHasType) TREE_KIND(eTreeDeclField, "decl_field", eTagName | eTagHasType) TREE_KIND(eTreeDeclFunction, "decl_function", eTagName | eTagEval | eTagHasType) TREE_KIND(eTreeDeclModule, "decl_module", eTagName) diff --git a/src/cthulhu/tree/src/tree.c b/src/cthulhu/tree/src/tree.c index 3af9e7f9..6b1040e4 100644 --- a/src/cthulhu/tree/src/tree.c +++ b/src/cthulhu/tree/src/tree.c @@ -248,7 +248,7 @@ tree_t *tree_expr_string(const node_t *node, const tree_t *type, const char *val /// must be either storage or a pointer #define TREE_EXPECT_ADDRESS(TYPE) CTASSERTF(tree_is(TYPE, eTreeTypePointer) || tree_is(TYPE, eTreeTypeReference) || tree_is(TYPE, eTreeTypeOpaque) || tree_is(TYPE, eTreeError), "expected reference or pointer, found %s", tree_to_string(TYPE)) -tree_t *tree_expr_cast(const node_t *node, const tree_t *type, tree_t *expr, tree_cast_t cast) +tree_t *tree_expr_cast(const node_t *node, const tree_t *type, const tree_t *expr, tree_cast_t cast) { CTASSERT(expr != NULL); diff --git a/src/language/ctu/src/ctu.y b/src/language/ctu/src/ctu.y index 52c213c1..8cccb020 100644 --- a/src/language/ctu/src/ctu.y +++ b/src/language/ctu/src/ctu.y @@ -533,7 +533,7 @@ eq_expr: compare_expr { $$ = $1; } ; and_expr: eq_expr { $$ = $1; } - | eq_expr AND xor_expr { $$ = ctu_expr_compare(x, @$, eCompareAnd, $1, $3); } + | and_expr AND eq_expr { $$ = ctu_expr_compare(x, @$, eCompareAnd, $1, $3); } ; or_expr: and_expr { $$ = $1; } diff --git a/src/language/ctu/src/sema/expr.c b/src/language/ctu/src/sema/expr.c index 4113d7e1..a408e5d9 100644 --- a/src/language/ctu/src/sema/expr.c +++ b/src/language/ctu/src/sema/expr.c @@ -62,7 +62,9 @@ static tree_t *sema_decl_name(tree_t *sema, const node_t *node, const vector_t * if (it != NULL) { *needs_load = false; - return it->case_value; + // TODO: we always treat this as const + // just need to slap const on everything in this file + return (tree_t*)it; } return tree_raise(node, sema->reports, &kEvent_SymbolNotFound, @@ -178,6 +180,27 @@ static tree_t *sema_string(tree_t *sema, const ctu_t *expr, const tree_t *implic return str; } +static tree_t *sema_char(tree_t *sema, const ctu_t *expr, const tree_t *implicit_type) +{ + const tree_t *type = implicit_type ? implicit_type : ctu_get_char_type(); + if (!tree_is(type, eTreeTypeDigit)) + { + return tree_raise(expr->node, sema->reports, &kEvent_InvalidLiteralType, "invalid type `%s` for char literal", + tree_to_string(type)); + } + + if (expr->length < 1) + { + return tree_raise(expr->node, sema->reports, &kEvent_InvalidLiteralType, "char literal must contain at least 1 code point"); + } + + mpz_t value; + mpz_init_set_ui(value, expr->text[0]); + tree_t *it = tree_expr_digit(expr->node, type, value); + + return verify_expr_type(sema, eTreeTypeDigit, type, "char literal", it); +} + static tree_t *sema_name(tree_t *sema, const ctu_t *expr) { bool needs_load = false; @@ -392,7 +415,7 @@ static bool can_index_type(const tree_t *ty) static tree_t *sema_index_rvalue(ctu_sema_t *sema, const ctu_t *expr) { tree_t *index = ctu_sema_rvalue(sema, expr->index, ctu_get_int_type(eDigitSize, eSignUnsigned)); - tree_t *object = ctu_sema_lvalue(sema, expr->expr); + tree_t *object = ctu_sema_rvalue(sema, expr->expr, NULL); const tree_t *ty = get_ptr_type(tree_get_type(object)); if (!can_index_type(ty)) @@ -408,7 +431,7 @@ static tree_t *sema_index_rvalue(ctu_sema_t *sema, const ctu_t *expr) static tree_t *sema_index_lvalue(ctu_sema_t *sema, const ctu_t *expr) { tree_t *index = ctu_sema_rvalue(sema, expr->index, ctu_get_int_type(eDigitSize, eSignUnsigned)); - tree_t *object = ctu_sema_lvalue(sema, expr->expr); + tree_t *object = ctu_sema_rvalue(sema, expr->expr, NULL); const tree_t *ty = get_ptr_type(tree_get_type(object)); if (!can_index_type(ty)) @@ -653,6 +676,7 @@ tree_t *ctu_sema_rvalue(ctu_sema_t *sema, const ctu_t *expr, const tree_t *impli case eCtuExprBool: return sema_bool(sema->sema, expr, inner); case eCtuExprInt: return sema_int(sema->sema, expr, inner); case eCtuExprString: return sema_string(sema->sema, expr, inner); + case eCtuExprChar: return sema_char(sema->sema, expr, inner); case eCtuExprCast: return sema_cast(sema, expr); case eCtuExprInit: return sema_init(sema, expr, inner); diff --git a/src/language/ctu/src/sema/sema.c b/src/language/ctu/src/sema/sema.c index 2fa22bb0..3bf74ee2 100644 --- a/src/language/ctu/src/sema/sema.c +++ b/src/language/ctu/src/sema/sema.c @@ -191,6 +191,7 @@ static tree_t *make_opaque_type(const node_t *node, const char *name) { return (gOpaqueType = tree_type_opaque(node, name)); } + tree_t *ctu_get_int_type(digit_t digit, sign_t sign) { return DIGIT_TYPE(digit, sign); diff --git a/src/target/debug/src/ssa.c b/src/target/debug/src/ssa.c index 3a2d6348..556a5a23 100644 --- a/src/target/debug/src/ssa.c +++ b/src/target/debug/src/ssa.c @@ -265,6 +265,31 @@ static void emit_ssa_block(ssa_emit_t *emit, io_t *io, const ssa_block_t *bb) ); break; } + case eOpSizeOf: { + ssa_sizeof_t size_of = step->size_of; + io_printf(io, "\t%%%s = sizeof %s\n", + get_step_name(&emit->emit, step), + type_to_string(size_of.type, base->arena) + ); + break; + } + case eOpAlignOf: { + ssa_alignof_t align_of = step->align_of; + io_printf(io, "\t%%%s = alignof %s\n", + get_step_name(&emit->emit, step), + type_to_string(align_of.type, base->arena) + ); + break; + } + case eOpOffsetOf: { + ssa_offsetof_t offset_of = step->offset_of; + io_printf(io, "\t%%%s = offsetof %s %zu\n", + get_step_name(&emit->emit, step), + type_to_string(offset_of.type, base->arena), + offset_of.index + ); + break; + } default: CT_NEVER("unknown opcode %d", step->opcode); } }