diff --git a/resources/lib/std/builtin.c3 b/resources/lib/std/builtin.c3 index 6742dd41a..6af2c8a31 100644 --- a/resources/lib/std/builtin.c3 +++ b/resources/lib/std/builtin.c3 @@ -1,5 +1,5 @@ module std::builtin; -/+ +/* enum TypeKind { VOID, @@ -97,4 +97,4 @@ struct TypeErrorValue char* name; ulong value; } -+/ \ No newline at end of file +*/ \ No newline at end of file diff --git a/resources/lib/std/cinterop.c3 b/resources/lib/std/cinterop.c3 index a8aa8bf84..5a9b5bebe 100644 --- a/resources/lib/std/cinterop.c3 +++ b/resources/lib/std/cinterop.c3 @@ -1,3 +1,78 @@ -module std:cinterop; +module std::cinterop; +$assert (${C_SHORT_SIZE} < 32); +$assert (${C_LONG_TYPE) < 128); +$if (${C_INT_SIZE} == 64) +{ + define CInt = long; + define CUInt = ulong; +} +$elseif (${C_INT_SIZE} == 32) +{ + define CInt = int; + define CUInt = uint; +} +$elseif (${C_INT_SIZE} == 16) +{ + define CInt = short; + define CUInt = ushort; +} +$else +{ + $assert(false, "Invalid C int size"); +} + +$if (${C_LONG_SIZE} == 64) +{ + define CLong = long; + define CULong = ulong; +} +$elseif (${C_LONG_SIZE} == 32) +{ + define CLong = int; + define CULong = uint; +} +$elseif (${C_LONG_SIZE} == 16) +{ + define CLong = short; + define CULong = ushort; +} +$else +{ + $assert(false, "Invalid C long size"); +} + +$if (${C_SHORT_SIZE} == 32) +{ + define CShort = int; + define CUShort = uint; +} +$elseif (${C_SHORT_SIZE} == 16) +{ + define CShort = short; + define CUShort = ushort; +} +$elseif (${C_SHORT_SIZE} == 8) +{ + define CShort = ichar; + define CUShort = char; +} +$else +{ + $assert(false, "Invalid C short size"); +} + +/* +define CChar = ${C_CHAR_TYPE}; +define CSChar = ${C_SCHAR_TYPE}; +define CShort = ${C_SHORT_TYPE}; +define CInt = ${C_INT_TYPE}; +define CLong = $(C_LONG_TYPE); +define CLongLong = ${C_LONGLONG_TYPE}; +define CUChar = ${C_UCHAR_TYPE}; +define CUShort = ${C_USHORT_TYPE}; +define CUInt = ${C_UINT_TYPE}; +define CULong = $(C_ULONG_TYPE); +define CULongLong = ${C_ULONGLONG_TYPE}; +*/ diff --git a/resources/lib/std/io.c3 b/resources/lib/std/io.c3 index c693a96d7..3b2704852 100644 --- a/resources/lib/std/io.c3 +++ b/resources/lib/std/io.c3 @@ -105,7 +105,7 @@ func void File.error(File *file) @inline int err = ferror } */ -/+ +/* #define __SLBF 0x0001 /* line buffered */ #define __SNBF 0x0002 /* unbuffered */ @@ -420,4 +420,4 @@ __END_DECLS #endif #endif /* _STDIO_H_ */ -+/ \ No newline at end of file +*/ \ No newline at end of file diff --git a/resources/lib/std/list.c3 b/resources/lib/std/list.c3 index 5381425cf..2afe884c9 100644 --- a/resources/lib/std/list.c3 +++ b/resources/lib/std/list.c3 @@ -112,3 +112,44 @@ func void List.free(List *list) list.capacity = 0; list.size = 0; } + +/* + +operator for(List *list; index, Type type) +{ + $IndexType = typeof(index); + $IndexType last_index = ($IndexType)(list.size); + for ($IndexType i = 0; i < last_index; i++) + { + yield(i, list.entries[index]); + } +} + +operator for(List *list; index, Type *type) +{ + $IndexType = typeof(index); + $IndexType last_index = ($IndexType)(list.size); + for ($IndexType i = 0; i < last_index; i++) + { + yield(i, &list.entries[index]); + } +} + +operator for(List *list; Type *type) +{ + usize size = list.size; + for (usize i = 0; i < last_index; i++) + { + yield(i, &list.entries[index]); + } +} +*/ +/* +operator for(List *list; Type type) +{ + usize size = list.size; + for (usize i = 0; i < last_index; i++) + { + yield(i, list.entries[index]); + } +}*/ \ No newline at end of file diff --git a/resources/lib/std/math.c3 b/resources/lib/std/math.c3 index 5b918a112..05cf358fe 100644 --- a/resources/lib/std/math.c3 +++ b/resources/lib/std/math.c3 @@ -130,7 +130,7 @@ private func double sin_limited(double x, double y, bool iy) return x - ((z * (0.5 * y - v * r) - y) - v * S1); } } -/+ +/* public func double cos(double x) { double[2] y; @@ -145,7 +145,7 @@ public func double cos(double x) { if (ix < 0x3e46a09e) { - // |x| < 2**-27 * sqrt(2) */ + // |x| < 2**-27 * sqrt(2) /* raise inexact if x!=0 */ FORCE_EVAL(x + 0x1p120f); return 1.0; @@ -167,4 +167,4 @@ public func double cos(double x) return sin_limited(y[0], y[1], true); } } -+/ \ No newline at end of file +*/ \ No newline at end of file diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 9cfe7c0c4..16d9a1962 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -441,10 +441,6 @@ void fprint_type_recursive(Context *context, FILE *file, Type *type, int indent) DUMP("(subarray"); DUMPTYPE(type->array.base); DUMPEND(); - case TYPE_VARARRAY: - DUMP("(vararray"); - DUMPTYPE(type->array.base); - DUMPEND(); case TYPE_INFERRED_ARRAY: DUMP("(inferred-array"); DUMPTYPE(type->array.base); @@ -525,11 +521,6 @@ void fprint_type_info_recursive(Context *context, FILE *file, TypeInfo *type_inf } DUMPF("(unresolved %s)", TOKSTR(type_info->unresolved.name_loc)); break; - case TYPE_INFO_VARARRAY: - DUMP("(vararray"); - DUMPTI(type_info->array.base); - DUMPE(); - break; case TYPE_INFO_SUBARRAY: DUMP("(subarray"); DUMPTI(type_info->array.base); @@ -590,6 +581,9 @@ void fprint_expr_recursive(Context *context, FILE *file, Expr *expr, int indent) if (!expr) return; switch (expr->expr_kind) { + case EXPR_PLACEHOLDER: + DUMP("(placeholder)"); + return; case EXPR_DESIGNATOR: DUMP("(named param)"); return; diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 0b2001aea..ba2673b02 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -34,6 +34,7 @@ void compiler_init(const char *std_lib_dir) //DEBUG_LOG("Found std library: %s", compiler.lib_dir); stable_init(&global_context.modules, 64); stable_init(&global_context.scratch_table, 32); + stable_init(&global_context.compiler_defines, 512); global_context.module_list = NULL; global_context.generic_module_list = NULL; stable_init(&global_context.global_symbols, 0x1000); @@ -249,8 +250,29 @@ static void add_global_define_int(const char *name, uint64_t int_value) add_global_define(name, value); } +static void setup_int_define(const char *id, uint64_t i) +{ + TokenType token_type = TOKEN_CONST_IDENT; + id = symtab_add(id, strlen(id), fnv1a(id, strlen(id)), &token_type); + Expr *expr = expr_new(EXPR_CONST, INVALID_RANGE); + expr_const_set_int(&expr->const_expr, i, TYPE_IXX); + expr->original_type = expr->type = type_compint; + expr->span = INVALID_RANGE; + expr->resolve_status = RESOLVE_NOT_DONE; + void *previous = stable_set(&global_context.compiler_defines, id, expr); + if (previous) + { + error_exit("Redefined ident %s", id); + } +} + void compiler_compile(void) { + setup_int_define("C_SHORT_SIZE", platform_target.width_c_short); + setup_int_define("C_INT_SIZE", platform_target.width_c_int); + setup_int_define("C_LONG_SIZE", platform_target.width_c_long); + setup_int_define("C_LONG_LONG_SIZE", platform_target.width_c_long_long); + global_context_clear_errors(); if (global_context.lib_dir) diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index f14099dd1..1a1fde029 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -703,6 +703,12 @@ typedef struct Decl *decl; } ExprIdentifier; +typedef struct +{ + Path *path; + TokenId identifier; +} ExprPlaceholder; + typedef struct { TokenId identifier; @@ -815,6 +821,7 @@ struct Expr_ ExprAccess access_expr; ExprDesignator designator_expr; ExprIdentifier identifier_expr; + ExprPlaceholder placeholder_expr; ExprIdentifier macro_identifier_expr; ExprIdentifierRaw ct_ident_expr; ExprIdentifierRaw ct_macro_ident_expr; @@ -1201,6 +1208,8 @@ typedef struct DynamicScope_ typedef struct MacroScope_ { Decl *macro; + uint32_t inline_line; + uint32_t original_inline_line; Decl **locals_start; unsigned depth; Decl **yield_symbol_start; @@ -1324,6 +1333,7 @@ typedef struct char scratch_buffer[MAX_STRING_BUFFER]; size_t scratch_buffer_len; STable scratch_table; + STable compiler_defines; Module std_module; Path std_module_path; } GlobalContext; @@ -1458,6 +1468,10 @@ extern const char *kw___ceil; extern const char *kw___round; extern const char *kw___sqrt; extern const char *kw___trunc; +extern const char *kw_FILE; +extern const char *kw_FUNC; +extern const char *kw_LINE; +extern const char *kw_LINEREAL; #define AST_NEW_TOKEN(_kind, _token) new_ast(_kind, source_span_from_token_id((_token).id)) #define AST_NEW(_kind, _loc) new_ast(_kind, _loc) @@ -1720,7 +1734,7 @@ Decl *sema_resolve_parameterized_symbol(Context *context, TokenId symbol, Path * Decl *sema_resolve_normal_symbol(Context *context, TokenId symbol, Path *path, bool handle_error); bool sema_resolve_type_info(Context *context, TypeInfo *type_info); bool sema_resolve_type_info_maybe_inferred(Context *context, TypeInfo *type_info, bool allow_inferred_type); -bool sema_resolve_type_shallow(Context *context, TypeInfo *type_info, bool allow_inferred_type); +bool sema_resolve_type_shallow(Context *context, TypeInfo *type_info, bool allow_inferred_type, bool in_shallow); Type *sema_type_lower_by_size(Type *type, ByteSize element_size); void sema_error_at_prev_end(Token token, const char *message, ...); @@ -1794,7 +1808,7 @@ Type *type_get_indexed_type(Type *type); Type *type_get_ptr(Type *ptr_type); Type *type_get_subarray(Type *arr_type); Type *type_get_inferred_array(Type *arr_type); -Type *type_get_vararray(Type *arr_type); + Type *type_get_vector(Type *vector_type, unsigned len); Type *type_int_signed_by_bitsize(unsigned bytesize); Type *type_int_unsigned_by_bitsize(unsigned bytesize); @@ -1916,7 +1930,7 @@ static inline bool type_is_ct(Type *type) static inline bool type_is_pointer(Type *type) { type = type->canonical; - return type->type_kind == TYPE_POINTER || type->type_kind == TYPE_VARARRAY; + return type->type_kind == TYPE_POINTER; } static inline uint64_t aligned_offset(uint64_t offset, uint64_t alignment) @@ -2050,7 +2064,6 @@ static inline bool type_kind_is_derived(TypeKind kind) { case TYPE_ARRAY: case TYPE_POINTER: - case TYPE_VARARRAY: case TYPE_SUBARRAY: return true; default: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index d2668c740..aadd2cafa 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -74,6 +74,7 @@ Expr *copy_expr(Expr *source_expr) UNREACHABLE case EXPR_UNDEF: return expr; + case EXPR_PLACEHOLDER: case EXPR_CONST_IDENTIFIER: case EXPR_MACRO_IDENTIFIER: case EXPR_CT_IDENT: @@ -139,6 +140,10 @@ Expr *copy_expr(Expr *source_expr) MACRO_COPY_EXPR(expr->guard_expr.inner); return expr; case EXPR_CONST: + if (type_kind_is_any_integer(expr->const_expr.kind) && expr->const_expr.i.digit_count > 1) + { + bigint_init_bigint(&expr->const_expr.i, &source_expr->const_expr.i); + } return expr; case EXPR_BINARY: MACRO_COPY_EXPR(expr->binary_expr.left); @@ -418,7 +423,6 @@ TypeInfo *copy_type_info(TypeInfo *source) return copy; case TYPE_INFO_INC_ARRAY: case TYPE_INFO_INFERRED_ARRAY: - case TYPE_INFO_VARARRAY: case TYPE_INFO_SUBARRAY: assert(source->resolve_status == RESOLVE_NOT_DONE); copy->array.base = copy_type_info(source->array.base); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 97894bd96..cb5066506 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -91,11 +91,6 @@ typedef enum CAST_XIERR, CAST_PTRPTR, CAST_PTRXI, - CAST_PTRVAR, - CAST_VARPTR, - CAST_VARSA, - CAST_VARVAR, - CAST_VARBOOL, CAST_ARRPTR, CAST_STRPTR, CAST_PTRBOOL, @@ -178,44 +173,45 @@ typedef enum typedef enum { EXPR_POISONED, - EXPR_GUARD, - EXPR_TRY, - EXPR_CATCH, - EXPR_ELSE, - EXPR_CONST, + EXPR_ACCESS, EXPR_BINARY, - EXPR_TERNARY, - EXPR_UNARY, - EXPR_POST_UNARY, - EXPR_TYPEID, - EXPR_IDENTIFIER, - EXPR_MACRO_IDENTIFIER, - EXPR_CT_IDENT, - EXPR_HASH_IDENT, - EXPR_CONST_IDENTIFIER, - EXPR_MACRO_CT_IDENTIFIER, EXPR_CALL, + EXPR_CAST, + EXPR_CATCH, + EXPR_COMPOUND_LITERAL, + EXPR_CONST, + EXPR_CONST_IDENTIFIER, + EXPR_CT_IDENT, + EXPR_DECL_LIST, + EXPR_DESIGNATOR, + EXPR_ELSE, + EXPR_ENUM_CONSTANT, + EXPR_EXPR_BLOCK, + EXPR_EXPRESSION_LIST, + EXPR_FAILABLE, EXPR_GROUP, - EXPR_SUBSCRIPT, + EXPR_GUARD, + EXPR_HASH_IDENT, + EXPR_MACRO_BLOCK, + EXPR_MACRO_CT_IDENTIFIER, + EXPR_MACRO_IDENTIFIER, + EXPR_MEMBER_ACCESS, + EXPR_IDENTIFIER, + EXPR_INITIALIZER_LIST, + EXPR_LEN, + EXPR_PLACEHOLDER, + EXPR_POST_UNARY, + EXPR_SCOPED_EXPR, EXPR_SLICE, EXPR_SLICE_ASSIGN, - EXPR_ACCESS, - EXPR_INITIALIZER_LIST, - EXPR_EXPRESSION_LIST, - EXPR_CAST, + EXPR_SUBSCRIPT, + EXPR_TERNARY, + EXPR_TRY, + EXPR_TYPEID, EXPR_TYPEINFO, EXPR_TYPEOF, - EXPR_MEMBER_ACCESS, - EXPR_SCOPED_EXPR, - EXPR_EXPR_BLOCK, - EXPR_MACRO_BLOCK, - EXPR_COMPOUND_LITERAL, - EXPR_FAILABLE, - EXPR_DECL_LIST, - EXPR_LEN, + EXPR_UNARY, EXPR_UNDEF, - EXPR_ENUM_CONSTANT, - EXPR_DESIGNATOR, } ExprKind; typedef enum @@ -273,7 +269,6 @@ typedef enum TYPE_INFO_ARRAY, TYPE_INFO_INC_ARRAY, TYPE_INFO_INFERRED_ARRAY, - TYPE_INFO_VARARRAY, TYPE_INFO_SUBARRAY, TYPE_INFO_POINTER, } TypeInfoKind; @@ -332,6 +327,7 @@ typedef enum TOKEN_MULT_ASSIGN, // *= TOKEN_NOT_EQUAL, // != TOKEN_OR, // || + TOKEN_PLACEHOLDER, // ${ TOKEN_PLUS_ASSIGN, // += TOKEN_PLUSPLUS, // ++ TOKEN_RBRAPIPE, // |} @@ -502,7 +498,6 @@ typedef enum TYPE_STRLIT, TYPE_DISTINCT, TYPE_ARRAY, - TYPE_VARARRAY, TYPE_SUBARRAY, TYPE_INFERRED_ARRAY, TYPE_TYPEINFO, diff --git a/src/compiler/headers.c b/src/compiler/headers.c index 6ed6efb2d..c195c6865 100644 --- a/src/compiler/headers.c +++ b/src/compiler/headers.c @@ -114,8 +114,6 @@ static void header_print_type(FILE *file, Type *type) UNREACHABLE case TYPE_ARRAY: break; - case TYPE_VARARRAY: - break; case TYPE_VIRTUAL: case TYPE_VIRTUAL_ANY: break; diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index f3f5921e1..a53875a81 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -222,6 +222,14 @@ static inline bool parse_nested_comment(Lexer *lexer) continue; } break; + case ' ': + case '\t': + case '\r': + case '\f': + break; + case '\n': + lexer_store_line_end(lexer); + break; default: break; } @@ -229,7 +237,7 @@ static inline bool parse_nested_comment(Lexer *lexer) } if (nesting > 0) { - return add_error_token(lexer, "Missing '+/' to end the nested comment."); + return add_error_token(lexer, "Missing '#/' to end the nested comment."); } return add_token(lexer, TOKEN_COMMENT, lexer->lexing_start); } @@ -240,6 +248,7 @@ static inline bool parse_nested_comment(Lexer *lexer) static inline bool parse_multiline_comment(Lexer *lexer) { TokenType type = peek(lexer) == '*' && peek_next(lexer) != '/' ? TOKEN_DOC_COMMENT : TOKEN_COMMENT; + int nesting = 1; while (1) { switch (peek(lexer)) @@ -248,7 +257,17 @@ static inline bool parse_multiline_comment(Lexer *lexer) if (peek_next(lexer) == '/') { skip(lexer, 2); - return add_token(lexer, type, lexer->lexing_start); + nesting--; + if (nesting == 0) return add_token(lexer, type, lexer->lexing_start); + continue; + } + break; + case '/': + if (peek_next(lexer) == '*') + { + skip(lexer, 2); + nesting++; + continue; } break; case '\n': @@ -1007,6 +1026,7 @@ static bool lexer_scan_token_inner(Lexer *lexer, LexMode mode) case '#': return scan_ident(lexer, TOKEN_HASH_IDENT, TOKEN_HASH_CONST_IDENT, TOKEN_HASH_TYPE_IDENT, '$'); case '$': + if (match(lexer, '{')) return add_token(lexer, TOKEN_PLACEHOLDER, "${"); return scan_ident(lexer, TOKEN_CT_IDENT, TOKEN_CT_CONST_IDENT, TOKEN_CT_TYPE_IDENT, '$'); case ',': return add_token(lexer, TOKEN_COMMA, ","); diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 727390c93..3f76f548e 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -323,19 +323,6 @@ void llvm_emit_ptr_from_array(GenContext *c, BEValue *value) } case TYPE_STRLIT: TODO - case TYPE_VARARRAY: - { - llvm_value_rvalue(c, value); - LLVMTypeRef struct_type = value->type->backend_aux_type; - LLVMValueRef pointer_addr = LLVMBuildStructGEP2(c->builder, struct_type, value->value, 3, "vararrptr"); - LLVMTypeRef pointer_type = llvm_get_type(c, type_get_ptr(value->type->array.base)); - AlignSize alignment = type_abi_alignment(type_voidptr); - // We need to pick the worst alignment in case this is packed in an array. - if (value->alignment < alignment) alignment = value->alignment; - llvm_value_set_address_align(value, - llvm_emit_load_aligned(c, pointer_type, pointer_addr, 0, "vaptr"), value->type, alignment); - return; - } default: UNREACHABLE } diff --git a/src/compiler/llvm_codegen_c_abi_x64.c b/src/compiler/llvm_codegen_c_abi_x64.c index 5b84cbe9b..642c3fa31 100644 --- a/src/compiler/llvm_codegen_c_abi_x64.c +++ b/src/compiler/llvm_codegen_c_abi_x64.c @@ -439,7 +439,6 @@ static void x64_classify(Type *type, ByteSize offset_base, X64Class *lo_class, X *lo_class = CLASS_SSE; *hi_class = CLASS_SSEUP; break; - case TYPE_VARARRAY: case TYPE_POINTER: *current = CLASS_INTEGER; break; @@ -545,7 +544,6 @@ AbiType *x64_get_int_type_at_offset(Type *type, unsigned offset, Type *source_ty { case TYPE_U64: case TYPE_I64: - case TYPE_VARARRAY: case TYPE_POINTER: if (!offset) return abi_type_new_plain(type); break; diff --git a/src/compiler/llvm_codegen_c_abi_x86.c b/src/compiler/llvm_codegen_c_abi_x86.c index e29e455c3..1b1e1dd8d 100644 --- a/src/compiler/llvm_codegen_c_abi_x86.c +++ b/src/compiler/llvm_codegen_c_abi_x86.c @@ -124,7 +124,6 @@ static bool x86_should_return_type_in_reg(Type *type) case TYPE_BOOL: case TYPE_POINTER: case TYPE_TYPEID: - case TYPE_VARARRAY: case TYPE_ERR_UNION: case TYPE_SUBARRAY: case TYPE_ERRTYPE: @@ -604,7 +603,6 @@ static ABIArgInfo *x86_classify_argument(CallConvention call, Regs *regs, Type * case ALL_FLOATS: case ALL_INTS: case TYPE_BOOL: - case TYPE_VARARRAY: case TYPE_POINTER: return x86_classify_primitives(call, regs, type); case TYPE_VECTOR: diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index c46737f6d..95a9e4d5e 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -370,53 +370,6 @@ static LLVMMetadataRef llvm_debug_subarray_type(GenContext *c, Type *type) return llvm_get_debug_struct(c, type, type->name, elements, 2, NULL, NULL, LLVMDIFlagZero); } -static LLVMMetadataRef llvm_debug_vararray_type(GenContext *c, Type *type) -{ - LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, type->name, NULL, NULL, LLVMDIFlagZero); - type->backend_debug_type = forward; - Type *element = type->array.base; - - LLVMMetadataRef array = LLVMDIBuilderCreateArrayType( - c->debug.builder, - type_size(type), - type_abi_alignment(element), - llvm_get_debug_type(c, element), - NULL, 0); - - LLVMMetadataRef array_member = LLVMDIBuilderCreateMemberType( - c->debug.builder, - forward, - "array", strlen("array"), - NULL, - 0, 0, - type_abi_alignment(element) * 8, - type_size(type_usize) * 2 * 8, LLVMDIFlagZero, array); - - LLVMMetadataRef elements[3] = { - llvm_get_debug_member(c, type_get_ptr(type->array.base), "len", 0, NULL, forward, LLVMDIFlagZero), - llvm_get_debug_member(c, type_usize, "capacity", type_size(type_usize), NULL, forward, LLVMDIFlagZero), - array_member - }; - unsigned strukt_size = type_size(type_usize) * 2 * 8; - unsigned alignment = type_abi_alignment(type_usize) * 8; - LLVMMetadataRef strukt = LLVMDIBuilderCreateStructType(c->debug.builder, - NULL, - "", 0, NULL, 0, strukt_size, - alignment, - LLVMDIFlagZero, NULL, - elements, 3, - c->debug.runtime_version, - NULL, // VTable - "", 0); - LLVMMetadataRef real = LLVMDIBuilderCreatePointerType(c->debug.builder, - strukt, - strukt_size, - alignment, 0, - type->name, strlen(type->name)); - - LLVMMetadataReplaceAllUsesWith(forward, real); - return real; -} static LLVMMetadataRef llvm_debug_errunion_type(GenContext *c, Type *type) { @@ -579,8 +532,6 @@ static inline LLVMMetadataRef llvm_get_debug_type_internal(GenContext *c, Type * return type->backend_debug_type = llvm_debug_typedef_type(c, type); case TYPE_ARRAY: return type->backend_debug_type = llvm_debug_array_type(c, type); - case TYPE_VARARRAY: - return type->backend_debug_type = llvm_debug_vararray_type(c, type); case TYPE_SUBARRAY: return type->backend_debug_type = llvm_debug_subarray_type(c, type); case TYPE_ERR_UNION: diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index e1cb1c392..bf22d9d16 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -153,8 +153,6 @@ static inline LLVMValueRef llvm_emit_subscript_addr_with_base(GenContext *c, Typ llvm_get_type(c, type->array.base), parent_value, &index_value, 1, "sarridx"); } - case TYPE_VARARRAY: - TODO default: UNREACHABLE @@ -209,9 +207,6 @@ static inline LLVMValueRef llvm_emit_subscript_addr_with_base_new(GenContext *c, llvm_get_type(c, type->array.base), parent->value, &index->value, 1, "sarridx"); } - case TYPE_VARARRAY: - // TODO insert trap on overflow. - TODO case TYPE_STRLIT: // TODO insert trap on overflow. return LLVMBuildInBoundsGEP(c->builder, parent->value, &index->value, 1, "ptridx"); @@ -394,8 +389,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, BEValue *value, Type *to_ value->value = LLVMBuildExtractValue(c->builder, value->value, 0, ""); } break; - case CAST_VARPTR: - break; case CAST_ARRPTR: TODO case CAST_EREU: @@ -502,10 +495,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, BEValue *value, Type *to_ value->value = LLVMBuildBitCast(c->builder, value->value, llvm_get_ptr_type(c, to_type), ""); value->type = to_type; return; - case CAST_PTRVAR: - case CAST_VARSA: - case CAST_VARVAR: - case CAST_VARBOOL: case CAST_BOOLBOOL: case CAST_SABOOL: TODO @@ -1131,33 +1120,6 @@ void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_l case TYPE_STRLIT: TODO break; - case TYPE_VARARRAY: - { - llvm_value_rvalue(c, be_value); - LLVMValueRef check = LLVMBuildIsNull(c->builder, be_value->value, "checknull"); - BEValue bool_value; - llvm_value_set_bool(&bool_value, check); - LLVMBasicBlockRef null_block = llvm_basic_block_new(c, "lennull"); - LLVMBasicBlockRef non_null_block = llvm_basic_block_new(c, "lennormal"); - LLVMBasicBlockRef exit_block = llvm_basic_block_new(c, "lenend"); - llvm_emit_cond_br(c, &bool_value, null_block, non_null_block); - llvm_emit_block(c, null_block); - LLVMValueRef result_null = llvm_get_zero(c, type_usize); - llvm_emit_br(c, exit_block); - llvm_emit_block(c, non_null_block); - LLVMTypeRef struct_type = be_value->type->backend_aux_type; - LLVMValueRef len_addr = LLVMBuildStructGEP2(c->builder, struct_type, be_value->value, 0, ""); - llvm_value_set_address(be_value, len_addr, type_usize); - LLVMValueRef result = llvm_value_rvalue_store(c, be_value); - llvm_emit_br(c, exit_block); - llvm_emit_block(c, exit_block); - LLVMValueRef total = LLVMBuildPhi(c->builder, llvm_get_type(c, type_usize), ""); - LLVMValueRef logic_values[2] = { result_null, result }; - LLVMBasicBlockRef blocks[2] = { null_block, non_null_block }; - LLVMAddIncoming(total, logic_values, blocks, 2); - llvm_value_set(be_value, total, type_usize); - return; - } default: UNREACHABLE } @@ -1233,7 +1195,6 @@ llvm_emit_slice_values(GenContext *c, Expr *slice, Type **parent_type_ref, LLVMV case TYPE_ARRAY: parent_base = parent_addr; break; - case TYPE_VARARRAY: case TYPE_STRLIT: TODO default: @@ -1264,7 +1225,6 @@ llvm_emit_slice_values(GenContext *c, Expr *slice, Type **parent_type_ref, LLVMV case TYPE_ARRAY: len = llvm_const_int(c, type_usize, parent_type->array.len); break; - case TYPE_VARARRAY: case TYPE_STRLIT: TODO default: @@ -2315,7 +2275,6 @@ static void llvm_expand_type_to_args(GenContext *context, Type *param_type, LLVM case TYPE_POINTER: case TYPE_ENUM: case TYPE_ERRTYPE: - case TYPE_VARARRAY: vec_add(*values, LLVMBuildLoad2(context->builder, llvm_get_type(context, param_type), expand_ptr, "loadexpanded")); return; case TYPE_TYPEDEF: @@ -2566,8 +2525,6 @@ static void llvm_emit_unpacked_variadic_arg(GenContext *c, Expr *expr, BEValue * case TYPE_SUBARRAY: *subarray = value; return; - case TYPE_VARARRAY: - TODO default: UNREACHABLE } @@ -3156,6 +3113,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) case EXPR_MACRO_CT_IDENTIFIER: case EXPR_CT_IDENT: case EXPR_HASH_IDENT: + case EXPR_PLACEHOLDER: UNREACHABLE case EXPR_UNDEF: // Should never reach this. diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 44b0bee82..1a20596c2 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -83,7 +83,7 @@ static LLVMValueRef llvm_emit_decl(GenContext *c, Ast *ast) { Type *type = type_flatten(decl->type); // Normal case, zero init. - if (type_is_builtin(type->type_kind) || type->type_kind == TYPE_POINTER || type->type_kind == TYPE_VARARRAY) + if (type_is_builtin(type->type_kind) || type->type_kind == TYPE_POINTER) { llvm_emit_store(c, decl, LLVMConstNull(alloc_type)); } diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 50d1cfa4d..be8749efa 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -415,18 +415,6 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type) LLVMStructSetBody(virtual_type, types, 2, false); return any_type->backend_type = virtual_type; } - case TYPE_VARARRAY: - { - LLVMTypeRef size_type = llvm_get_type(c, type_usize); - LLVMTypeRef capacity_type = llvm_get_type(c, type_usize); - LLVMTypeRef func_type = llvm_get_type(c, type_voidptr); - LLVMTypeRef ptr_type = LLVMPointerType(llvm_get_type(c, any_type->array.base), 0); - LLVMTypeRef types[4] = { size_type, capacity_type, func_type, ptr_type }; - LLVMTypeRef array_type = LLVMStructCreateNamed(c->context, any_type->name); - LLVMStructSetBody(array_type, types, 4, false); - any_type->backend_aux_type = array_type; - return any_type->backend_type = LLVMPointerType(array_type, 0); - } case TYPE_VECTOR: return any_type->backend_type = LLVMVectorType(llvm_get_type(c, any_type->vector.base), any_type->vector.len); } diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 67cf70a15..2223c111e 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -676,6 +676,25 @@ static Expr *parse_else_expr(Context *context, Expr *left) return else_expr; } +static Expr *parse_placeholder(Context *context, Expr *left) +{ + assert(!left && "Had left hand side"); + advance_and_verify(context, TOKEN_PLACEHOLDER); + Expr *expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + CONSUME_OR(TOKEN_RBRACE, poisoned_expr); + + if (expr->expr_kind != EXPR_IDENTIFIER && TOKTYPE(expr->identifier_expr.identifier) != TOKEN_CONST_IDENT) + { + SEMA_ERROR(expr, "Expected an uppercase identifier that corresponds to a compile time argument."); + return poisoned_expr; + } + ExprPlaceholder placeholder = { .identifier = expr->identifier_expr.identifier, .path = expr->identifier_expr.path }; + expr->placeholder_expr = placeholder; + expr->expr_kind = EXPR_PLACEHOLDER; + expr->resolve_status = RESOLVE_NOT_DONE; + return expr; +} + static Expr *parse_integer(Context *context, Expr *left) { assert(!left && "Had left hand side"); @@ -1076,6 +1095,7 @@ ParseRule rules[TOKEN_EOF + 1] = { [TOKEN_FALSE] = { parse_bool, NULL, PREC_NONE }, [TOKEN_NULL] = { parse_null, NULL, PREC_NONE }, [TOKEN_INTEGER] = { parse_integer, NULL, PREC_NONE }, + [TOKEN_PLACEHOLDER] = { parse_placeholder, NULL, PREC_NONE }, [TOKEN_CHAR_LITERAL] = { parse_char_lit, NULL, PREC_NONE }, [TOKEN_AT] = { parse_macro_ident, NULL, PREC_NONE }, [TOKEN_STRING] = { parse_string_literal, NULL, PREC_NONE }, diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 2857fc7aa..2af23c9ac 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -668,7 +668,7 @@ static inline TypeInfo *parse_array_type_index(Context *context, TypeInfo *type) RANGE_EXTEND_PREV(incr_array); return incr_array; } - if (try_consume(context, TOKEN_QUESTION)) + if (try_consume(context, TOKEN_STAR)) { CONSUME_OR(TOKEN_RBRACKET, poisoned_type_info); TypeInfo *inferred_array = type_info_new(TYPE_INFO_INFERRED_ARRAY, type->span); @@ -676,15 +676,6 @@ static inline TypeInfo *parse_array_type_index(Context *context, TypeInfo *type) RANGE_EXTEND_PREV(inferred_array); return inferred_array; } - if (try_consume(context, TOKEN_STAR)) - { - CONSUME_OR(TOKEN_RBRACKET, poisoned_type_info); - TypeInfo *vararray = type_info_new(TYPE_INFO_VARARRAY, type->span); - vararray->array.base = type; - vararray->array.len = NULL; - RANGE_EXTEND_PREV(vararray); - return vararray; - } if (try_consume(context, TOKEN_RBRACKET)) { TypeInfo *subarray = type_info_new(TYPE_INFO_SUBARRAY, type->span); diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 5d6d337c3..3c9794f74 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -1191,6 +1191,7 @@ Ast *parse_stmt(Context *context) case TOKEN_BANGBANG: case TOKEN_UNDERSCORE: case TOKEN_PRIVATE: + case TOKEN_PLACEHOLDER: SEMA_TOKEN_ERROR(context->tok, "Unexpected '%s' found when expecting a statement.", token_type_to_string(context->tok.type)); advance(context); return poisoned_ast; diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 102c4e3f3..fd26d3602 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -360,8 +360,6 @@ CastKind cast_to_bool_kind(Type *type) return CAST_BOOLBOOL; case TYPE_ERR_UNION: return CAST_EUBOOL; - case TYPE_VARARRAY: - return CAST_VARBOOL; case TYPE_SUBARRAY: return CAST_SABOOL; case ALL_INTS: @@ -432,7 +430,7 @@ bool cast_may_explicit(Type *from_type, Type *to_type) return type_is_any_integer(to) || type_is_float(to) || to == type_bool || to_kind == TYPE_ENUM; case TYPE_POINTER: // Allow conversion ptr -> int (min pointer size)/bool/pointer/vararray - if ((type_is_integer(to) && type_size(to) >= type_size(type_iptr)) || to == type_bool || to_kind == TYPE_POINTER || to_kind == TYPE_VARARRAY) return true; + if ((type_is_integer(to) && type_size(to) >= type_size(type_iptr)) || to == type_bool || to_kind == TYPE_POINTER) return true; // Special subarray conversion: someType[N]* -> someType[] if (to_kind == TYPE_SUBARRAY && from->pointer->type_kind == TYPE_ARRAY && from->pointer->array.base == to->array.base) return true; return false; @@ -460,13 +458,6 @@ bool cast_may_explicit(Type *from_type, Type *to_type) if (to_kind == TYPE_POINTER) return true; if (to_kind == TYPE_SUBARRAY && (to->array.base == type_char || to->array.base == type_ichar)) return true; return false; - case TYPE_VARARRAY: - if (to_kind == TYPE_POINTER) return true; - if (to_kind == TYPE_SUBARRAY || to_kind == TYPE_VARARRAY) - { - return type_is_structurally_equivalent(from->array.base, from->pointer->array.base); - } - return false; case TYPE_SUBARRAY: return to_kind == TYPE_POINTER; case TYPE_VECTOR: @@ -525,7 +516,7 @@ bool cast_may_implicit(Type *from_type, Type *to_type) if (type_is_pointer(to)) { // 4a. Assigning a subarray or vararray to a pointer of the same base type is fine - if (from->type_kind == TYPE_SUBARRAY || from->type_kind == TYPE_VARARRAY) + if (from->type_kind == TYPE_SUBARRAY) { // void* conversion always work. if (to == type_voidptr) return true; @@ -565,11 +556,6 @@ bool cast_may_implicit(Type *from_type, Type *to_type) return from->pointer->type_kind == TYPE_ARRAY && from->pointer->array.base == to->array.base; } - // 5b. Assign var array int[] = int[*] - if (from->type_kind == TYPE_VARARRAY) - { - return from->array.base == to->array.base; - } return false; } @@ -774,7 +760,6 @@ bool cast(Expr *expr, Type *to_type) if (type_is_integer(canonical)) return pointer_to_integer(expr, to_type); if (canonical->type_kind == TYPE_BOOL) return pointer_to_bool(expr, to_type); if (canonical->type_kind == TYPE_POINTER) return pointer_to_pointer(expr, to_type); - if (canonical->type_kind == TYPE_VARARRAY) return insert_cast(expr, CAST_PTRVAR, to_type); if (canonical->type_kind == TYPE_SUBARRAY) return insert_cast(expr, CAST_APTSA, to_type); break; case TYPE_VIRTUAL: @@ -803,11 +788,6 @@ bool cast(Expr *expr, Type *to_type) if (canonical->type_kind == TYPE_POINTER) return insert_cast(expr, CAST_STRPTR, to_type); if (canonical->type_kind == TYPE_SUBARRAY) return string_literal_to_subarray(expr, to_type); break; - case TYPE_VARARRAY: - if (canonical->type_kind == TYPE_SUBARRAY) return insert_cast(expr, CAST_VARSA, to_type); - if (canonical->type_kind == TYPE_VARARRAY) return insert_cast(expr, CAST_VARVAR, to_type); - if (canonical->type_kind == TYPE_POINTER) return insert_cast(expr, CAST_VARPTR, to_type); - break; case TYPE_SUBARRAY: if (canonical->type_kind == TYPE_POINTER) return insert_cast(expr, CAST_SAPTR, canonical); break; diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 30930ce95..f7d3fe59c 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -496,7 +496,6 @@ static inline bool sema_analyse_distinct(Context *context, Decl *decl) case TYPE_STRUCT: case TYPE_UNION: case TYPE_ARRAY: - case TYPE_VARARRAY: case TYPE_SUBARRAY: case TYPE_VECTOR: break; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 85b721193..4d3230901 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -733,7 +733,6 @@ static inline bool expr_may_unpack_as_vararg(Expr *expr, Type *variadic_base_typ { case TYPE_ARRAY: case TYPE_SUBARRAY: - case TYPE_VARARRAY: return canonical->array.base == base_type; case TYPE_POINTER: if (canonical->pointer->type_kind == TYPE_ARRAY) return canonical->pointer->array.base == base_type; @@ -1266,6 +1265,8 @@ static inline bool sema_expr_analyse_macro_call(Context *context, Type *to, Expr context->macro_scope = (MacroScope){ .macro = decl, + .inline_line = TOKLOC(call_expr->span.loc)->line, + .original_inline_line = old_macro_scope.depth ? old_macro_scope.original_inline_line : TOKLOC(call_expr->span.loc)->line, .locals_start = context->active_scope.current_local, .depth = old_macro_scope.depth + 1, .yield_symbol_start = first_local, @@ -1460,7 +1461,6 @@ static bool expr_check_index_in_range(Context *context, Type *type, Expr *index_ break; } case TYPE_STRLIT: - case TYPE_VARARRAY: case TYPE_SUBARRAY: // If not from end, just check the negative values. if (!from_end) break; @@ -2068,7 +2068,6 @@ CHECK_DEEPER: switch (type->type_kind) { case TYPE_SUBARRAY: - case TYPE_VARARRAY: if (kw == kw_sizeof) { expr_rewrite_to_int_const(expr, type_usize, type_size(type)); @@ -2916,8 +2915,6 @@ static inline bool sema_expr_analyse_initializer_list(Context *context, Type *to case TYPE_ERRTYPE: case TYPE_INFERRED_ARRAY: return sema_expr_analyse_initializer(context, to, assigned, expr); - case TYPE_VARARRAY: - TODO default: break; } @@ -3983,7 +3980,6 @@ static bool sema_expr_analyse_comp(Context *context, Expr *expr, Expr *left, Exp case TYPE_ERR_UNION: case TYPE_STRLIT: case TYPE_ARRAY: - case TYPE_VARARRAY: case TYPE_SUBARRAY: case TYPE_TYPEID: case TYPE_VIRTUAL_ANY: @@ -4320,7 +4316,6 @@ static bool sema_expr_analyse_not(Expr *expr, Expr *inner) case TYPE_POINTER: case TYPE_VIRTUAL: case TYPE_VIRTUAL_ANY: - case TYPE_VARARRAY: case TYPE_SUBARRAY: case TYPE_BOOL: case TYPE_VECTOR: @@ -4757,6 +4752,55 @@ static inline bool sema_expr_analyse_failable(Context *context, Type *to, Expr * return true; } +static inline bool sema_expr_analyse_placeholder(Context *context, Type *to, Expr *expr) +{ + const char *string = TOKSTR(expr->placeholder_expr.identifier); + if (string == kw_FILE) + { + expr_rewrite_to_string(expr, context->file->name); + return true; + } + if (string == kw_FUNC) + { + if (!context->active_function_for_analysis) + { + expr_rewrite_to_string(expr, ""); + return true; + } + expr_rewrite_to_string(expr, context->active_function_for_analysis->name); + return true; + } + if (string == kw_LINEREAL) + { + expr_rewrite_to_int_const(expr, type_compint, TOKLOC(expr->placeholder_expr.identifier)->line); + return true; + } + if (string == kw_LINE) + { + if (context->macro_scope.depth) + { + expr_rewrite_to_int_const(expr, type_compint, context->macro_scope.original_inline_line); + } + else + { + expr_rewrite_to_int_const(expr, type_compint, TOKLOC(expr->placeholder_expr.identifier)->line); + } + return true; + } + Expr *value = stable_get(&global_context.compiler_defines, string); + if (!value) + { + SEMA_ERROR(expr, "The placeholder constant '%s' was not defined, did you mistype or forget to add it?", string); + return false; + } + expr_replace(expr, value); + if (expr->expr_kind == EXPR_CONST && type_kind_is_any_integer(expr->const_expr.kind) && value->const_expr.i.digit_count > 1) + { + bigint_init_bigint(&expr->const_expr.i, &value->const_expr.i); + } + return true; +} + static inline bool sema_analyse_expr_dispatch(Context *context, Type *to, Expr *expr) { @@ -4775,6 +4819,8 @@ static inline bool sema_analyse_expr_dispatch(Context *context, Type *to, Expr * return sema_expr_analyse_ct_identifier(context, expr); case EXPR_FAILABLE: return sema_expr_analyse_failable(context, to, expr); + case EXPR_PLACEHOLDER: + return sema_expr_analyse_placeholder(context, to, expr); case EXPR_POISONED: return false; case EXPR_LEN: diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 506d0c599..be3c706a6 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -6,7 +6,7 @@ static inline bool sema_resolve_ptr_type(Context *context, TypeInfo *type_info) { - if (!sema_resolve_type_shallow(context, type_info->pointer, false)) + if (!sema_resolve_type_shallow(context, type_info->pointer, false, true)) { return type_info_poison(type_info); } @@ -15,18 +15,27 @@ static inline bool sema_resolve_ptr_type(Context *context, TypeInfo *type_info) return true; } -static inline bool sema_resolve_array_type(Context *context, TypeInfo *type) +// TODO cleanup. +static inline bool sema_resolve_array_type(Context *context, TypeInfo *type, bool shallow) { - if (!sema_resolve_type_info(context, type->array.base)) + if (type->kind == TYPE_INFO_SUBARRAY || shallow) { - return type_info_poison(type); + if (!sema_resolve_type_shallow(context, type->array.base, false, true)) + { + return type_info_poison(type); + } } + else + { + if (!sema_resolve_type_info(context, type->array.base)) + { + return type_info_poison(type); + } + } + uint64_t len; switch (type->kind) { - case TYPE_INFO_VARARRAY: - type->type = type_get_vararray(type->array.base->type); - break; case TYPE_INFO_SUBARRAY: type->type = type_get_subarray(type->array.base->type); break; @@ -126,7 +135,7 @@ static bool sema_resolve_type_identifier(Context *context, TypeInfo *type_info) } -bool sema_resolve_type_shallow(Context *context, TypeInfo *type_info, bool allow_inferred_type) +bool sema_resolve_type_shallow(Context *context, TypeInfo *type_info, bool allow_inferred_type, bool in_shallow) { if (type_info->resolve_status == RESOLVE_DONE) return type_info_ok(type_info); @@ -163,9 +172,8 @@ bool sema_resolve_type_shallow(Context *context, TypeInfo *type_info, bool allow } FALLTHROUGH; case TYPE_INFO_SUBARRAY: - case TYPE_INFO_VARARRAY: case TYPE_INFO_ARRAY: - if (!sema_resolve_array_type(context, type_info)) return false; + if (!sema_resolve_array_type(context, type_info, in_shallow)) return false; break; case TYPE_INFO_POINTER: if (!sema_resolve_ptr_type(context, type_info)) return false; diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index f694c9aa9..5bfd48f0d 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -12,7 +12,7 @@ void sema_shadow_error(Decl *decl, Decl *old) bool sema_resolve_type_info_maybe_inferred(Context *context, TypeInfo *type_info, bool allow_inferred_type) { - if (!sema_resolve_type_shallow(context, type_info, allow_inferred_type)) return false; + if (!sema_resolve_type_shallow(context, type_info, allow_inferred_type, false)) return false; Type *type = type_info->type; // usize and similar typedefs will not have a decl. if (type->type_kind == TYPE_TYPEDEF && type->decl == NULL) return true; diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index a0f250289..49c168ac4 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -62,7 +62,10 @@ const char *kw___ceil; const char *kw___round; const char *kw___sqrt; const char *kw___trunc; - +const char *kw_FILE; +const char *kw_FUNC; +const char *kw_LINE; +const char *kw_LINEREAL; void symtab_init(uint32_t capacity) { @@ -121,6 +124,10 @@ void symtab_init(uint32_t capacity) kw___round = KW_DEF("__round"); kw___sqrt = KW_DEF("__sqrt"); kw___trunc = KW_DEF("__trunc"); + kw_LINE = KW_DEF("LINE"); + kw_LINEREAL = KW_DEF("LINEREAL"); + kw_FILE = KW_DEF("FILE"); + kw_FUNC = KW_DEF("FUNC"); attribute_list[ATTRIBUTE_INLINE] = kw_inline; attribute_list[ATTRIBUTE_NOINLINE] = KW_DEF("noinline"); diff --git a/src/compiler/target.c b/src/compiler/target.c index 8ef16c1ee..ee1c65018 100644 --- a/src/compiler/target.c +++ b/src/compiler/target.c @@ -1206,6 +1206,7 @@ void target_setup(BuildTarget *target) platform_target.width_c_long = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_LONG); platform_target.width_c_long_long = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_LONG_LONG); + /** * x86-64: CMOV, CMPXCHG8B, FPU, FXSR, MMX, FXSR, SCE, SSE, SSE2 * x86-64-v2: (close to Nehalem) CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3 diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index 2b3a55245..ae1bab177 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -106,6 +106,8 @@ const char *token_type_to_string(TokenType type) return "!="; case TOKEN_OR: return "||"; + case TOKEN_PLACEHOLDER: + return "${"; case TOKEN_PLUS_ASSIGN: return "+="; case TOKEN_PLUSPLUS: diff --git a/src/compiler/types.c b/src/compiler/types.c index 70cb5dc0c..1d3bb1f57 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -5,55 +5,59 @@ #include "compiler_internal.h" static STable function_types; -static Type t_u0, t_u1, t_i8, t_i16, t_i32, t_i64, t_i128, t_ixx; -static Type t_u8, t_u16, t_u32, t_u64, t_u128; -static Type t_f16, t_f32, t_f64, t_f128, t_fxx; -static Type t_usz, t_isz, t_uptr, t_iptr, t_uptrdiff, t_iptrdiff; -static Type t_cus, t_cui, t_cul, t_cull; -static Type t_cs, t_ci, t_cl, t_cll; -static Type t_voidstar, t_typeid, t_error, t_typeinfo; -static Type t_str, t_varheader, t_virtual, t_virtual_generic; +static struct +{ + Type u0, u1, i8, i16, i32, i64, i128, ixx; + Type u8, u16, u32, u64, u128; + Type f16, f32, f64, f128, fxx; + Type usz, isz, uptr, iptr, uptrdiff, iptrdiff; + Type t_cus, t_cui, t_cul, t_cull; + Type t_cs, t_ci, t_cl, t_cll; + Type voidstar, typeid, error, typeinfo; + Type str, varheader, virtual, virtual_generic; -Type *type_bool = &t_u1; -Type *type_void = &t_u0; -Type *type_voidptr = &t_voidstar; -Type *type_virtual = &t_virtual; -Type *type_virtual_generic = &t_virtual_generic; -Type *type_half = &t_f16; -Type *type_float = &t_f32; -Type *type_double = &t_f64; -Type *type_quad = &t_f128; -Type *type_typeid = &t_typeid; -Type *type_typeinfo = &t_typeinfo; -Type *type_ichar = &t_i8; -Type *type_short = &t_i16; -Type *type_int = &t_i32; -Type *type_long = &t_i64; -Type *type_i128 = &t_i128; -Type *type_iptr = &t_iptr; -Type *type_iptrdiff = &t_iptrdiff; -Type *type_isize = &t_isz; -Type *type_char = &t_u8; -Type *type_ushort = &t_u16; -Type *type_uint = &t_u32; -Type *type_ulong = &t_u64; -Type *type_u128 = &t_u128; -Type *type_uptr = &t_uptr; -Type *type_uptrdiff = &t_uptrdiff; -Type *type_usize = &t_usz; -Type *type_compint = &t_ixx; -Type *type_compfloat = &t_fxx; -Type *type_compstr = &t_str; -Type *type_c_short = &t_cs; -Type *type_c_int = &t_ci; -Type *type_c_long = &t_cl; -Type *type_c_longlong = &t_cll; -Type *type_c_ushort = &t_cus; -Type *type_c_uint = &t_cui; -Type *type_c_ulong = &t_cul; -Type *type_c_ulonglong = &t_cull; -Type *type_error = &t_error; -Type *type_varheader = &t_varheader; +} t; + +Type *type_bool = &t.u1; +Type *type_void = &t.u0; +Type *type_voidptr = &t.voidstar; +Type *type_virtual = &t.virtual; +Type *type_virtual_generic = &t.virtual_generic; +Type *type_half = &t.f16; +Type *type_float = &t.f32; +Type *type_double = &t.f64; +Type *type_quad = &t.f128; +Type *type_typeid = &t.typeid; +Type *type_typeinfo = &t.typeinfo; +Type *type_ichar = &t.i8; +Type *type_short = &t.i16; +Type *type_int = &t.i32; +Type *type_long = &t.i64; +Type *type_i128 = &t.i128; +Type *type_iptr = &t.iptr; +Type *type_iptrdiff = &t.iptrdiff; +Type *type_isize = &t.isz; +Type *type_char = &t.u8; +Type *type_ushort = &t.u16; +Type *type_uint = &t.u32; +Type *type_ulong = &t.u64; +Type *type_u128 = &t.u128; +Type *type_uptr = &t.uptr; +Type *type_uptrdiff = &t.uptrdiff; +Type *type_usize = &t.usz; +Type *type_compint = &t.ixx; +Type *type_compfloat = &t.fxx; +Type *type_compstr = &t.str; +Type *type_c_short = &t.t_cs; +Type *type_c_int = &t.t_ci; +Type *type_c_long = &t.t_cl; +Type *type_c_longlong = &t.t_cll; +Type *type_c_ushort = &t.t_cus; +Type *type_c_uint = &t.t_cui; +Type *type_c_ulong = &t.t_cul; +Type *type_c_ulonglong = &t.t_cull; +Type *type_error = &t.error; +Type *type_varheader = &t.varheader; static unsigned size_subarray; static unsigned alignment_subarray; @@ -63,8 +67,7 @@ unsigned alignment_error_code; #define PTR_OFFSET 0 #define INFERRED_ARRAY_OFFSET 1 #define SUB_ARRAY_OFFSET 2 -#define VAR_ARRAY_OFFSET 3 -#define ARRAY_OFFSET 4 +#define ARRAY_OFFSET 3 Type *type_int_signed_by_bitsize(unsigned bytesize) { @@ -145,9 +148,6 @@ const char *type_to_error_string(Type *type) case TYPE_ARRAY: asprintf(&buffer, "%s[%llu]", type_to_error_string(type->array.base), (unsigned long long)type->array.len); return buffer; - case TYPE_VARARRAY: - asprintf(&buffer, "%s[*]", type_to_error_string(type->array.base)); - return buffer; case TYPE_INFERRED_ARRAY: asprintf(&buffer, "%s[?]", type_to_error_string(type->array.base)); return buffer; @@ -223,8 +223,7 @@ ByteSize type_size(Type *type) case TYPE_STRLIT: case TYPE_FUNC: case TYPE_POINTER: - case TYPE_VARARRAY: - return t_usz.canonical->builtin.bytesize; + return t.usz.canonical->builtin.bytesize; case TYPE_ARRAY: return type_size(type->array.base) * type->array.len; case TYPE_SUBARRAY: @@ -339,7 +338,6 @@ bool type_is_abi_aggregate(Type *type) case TYPE_VOID: case ALL_INTS: case TYPE_BOOL: - case TYPE_VARARRAY: case TYPE_TYPEID: case TYPE_POINTER: case TYPE_ENUM: @@ -585,7 +583,6 @@ bool type_is_homogenous_aggregate(Type *type, Type **base, unsigned *elements) case TYPE_VECTOR: break; case TYPE_POINTER: - case TYPE_VARARRAY: // All pointers are the same. type = type_voidptr; break; @@ -664,7 +661,7 @@ AlignSize type_abi_alignment(Type *type) case TYPE_ENUM: return type->decl->enums.type_info->type->canonical->builtin.abi_alignment; case TYPE_ERRTYPE: - return t_usz.canonical->builtin.abi_alignment; + return t.usz.canonical->builtin.abi_alignment; case TYPE_STRUCT: case TYPE_UNION: return type->decl->alignment; @@ -680,9 +677,8 @@ AlignSize type_abi_alignment(Type *type) return type_virtual_generic->builtin.abi_alignment; case TYPE_FUNC: case TYPE_POINTER: - case TYPE_VARARRAY: case TYPE_STRLIT: - return t_usz.canonical->builtin.abi_alignment; + return t.usz.canonical->builtin.abi_alignment; case TYPE_ARRAY: return type_abi_alignment(type->array.base); case TYPE_SUBARRAY: @@ -778,31 +774,6 @@ static Type *type_generate_inferred_array(Type *arr_type, bool canonical) return arr; } -static Type *type_generate_vararray(Type *arr_type, bool canonical) -{ - if (canonical) arr_type = arr_type->canonical; - if (!arr_type->type_cache) - { - create_type_cache(arr_type); - } - - Type *arr = arr_type->type_cache[VAR_ARRAY_OFFSET]; - if (arr == NULL) - { - arr = type_new(TYPE_VARARRAY, strformat("%s[*]", arr_type->name)); - arr->array.base = arr_type; - arr_type->type_cache[VAR_ARRAY_OFFSET] = arr; - if (arr_type == arr_type->canonical) - { - arr->canonical = arr; - } - else - { - arr->canonical = type_generate_vararray(arr_type->canonical, true); - } - } - return arr; -} Type *type_get_ptr(Type *ptr_type) @@ -820,11 +791,6 @@ Type *type_get_inferred_array(Type *arr_type) return type_generate_inferred_array(arr_type, false); } -Type *type_get_vararray(Type *arr_type) -{ - return type_generate_vararray(arr_type, false); -} - static inline bool array_structurally_equivalent_to_struct(Type *array, Type *type) { assert(array->type_kind == TYPE_ARRAY); @@ -940,7 +906,6 @@ Type *type_get_indexed_type(Type *type) { case TYPE_POINTER: return type->pointer; - case TYPE_VARARRAY: case TYPE_ARRAY: case TYPE_SUBARRAY: case TYPE_INFERRED_ARRAY: @@ -1101,8 +1066,6 @@ static void type_append_name_to_scratch(Type *type) break; case TYPE_ARRAY: TODO - case TYPE_VARARRAY: - TODO case TYPE_VIRTUAL: scratch_buffer_append("virtual "); scratch_buffer_append(type->decl->name); @@ -1159,61 +1122,61 @@ void type_setup(PlatformTarget *target) #define DEF_TYPE(name_, shortname_, type_, bits_, aligned_) \ type_create(#name_, &(shortname_), type_, bits_, target->align_ ## aligned_, target->align_pref_ ## aligned_) - DEF_TYPE(bool, t_u1, TYPE_BOOL, 1, byte); - DEF_TYPE(float, t_f32, TYPE_F32, 32, float); - DEF_TYPE(double, t_f64, TYPE_F64, 64, double); + DEF_TYPE(bool, t.u1, TYPE_BOOL, 1, byte); + DEF_TYPE(float, t.f32, TYPE_F32, 32, float); + DEF_TYPE(double, t.f64, TYPE_F64, 64, double); - DEF_TYPE(ichar, t_i8, TYPE_I8, 8, byte); - DEF_TYPE(short, t_i16, TYPE_I16, 16, short); - DEF_TYPE(int, t_i32, TYPE_I32, 32, int); - DEF_TYPE(long, t_i64, TYPE_I64, 64, long); - DEF_TYPE(i128, t_i128, TYPE_I128, 128, i128); + DEF_TYPE(ichar, t.i8, TYPE_I8, 8, byte); + DEF_TYPE(short, t.i16, TYPE_I16, 16, short); + DEF_TYPE(int, t.i32, TYPE_I32, 32, int); + DEF_TYPE(long, t.i64, TYPE_I64, 64, long); + DEF_TYPE(i128, t.i128, TYPE_I128, 128, i128); - DEF_TYPE(char, t_u8, TYPE_U8, 8, byte); - DEF_TYPE(ushort, t_u16, TYPE_U16, 16, short); - DEF_TYPE(uint, t_u32, TYPE_U32, 32, int); - DEF_TYPE(ulong, t_u64, TYPE_U64, 64, long); - DEF_TYPE(u128, t_u128, TYPE_U128, 128, i128); + DEF_TYPE(char, t.u8, TYPE_U8, 8, byte); + DEF_TYPE(ushort, t.u16, TYPE_U16, 16, short); + DEF_TYPE(uint, t.u32, TYPE_U32, 32, int); + DEF_TYPE(ulong, t.u64, TYPE_U64, 64, long); + DEF_TYPE(u128, t.u128, TYPE_U128, 128, i128); - DEF_TYPE(void, t_u0, TYPE_VOID, 8, byte); - DEF_TYPE(string, t_str, TYPE_STRLIT, target->width_pointer, pointer); + DEF_TYPE(void, t.u0, TYPE_VOID, 8, byte); + DEF_TYPE(string, t.str, TYPE_STRLIT, target->width_pointer, pointer); #undef DEF_TYPE - type_create("typeinfo", &t_typeinfo, TYPE_TYPEINFO, 0, 0, 0); - type_create("typeid", &t_typeid, TYPE_TYPEID, target->width_pointer, target->align_pref_pointer, target->align_pointer); - type_create("void*", &t_voidstar, TYPE_POINTER, target->width_pointer, target->align_pref_pointer, target->align_pointer); + type_create("typeinfo", &t.typeinfo, TYPE_TYPEINFO, 0, 0, 0); + type_create("typeid", &t.typeid, TYPE_TYPEID, target->width_pointer, target->align_pref_pointer, target->align_pointer); + type_create("void*", &t.voidstar, TYPE_POINTER, target->width_pointer, target->align_pref_pointer, target->align_pointer); create_type_cache(type_void); - type_void->type_cache[0] = &t_voidstar; - t_voidstar.pointer = type_void; - type_create("virtual*", &t_virtual, TYPE_VIRTUAL_ANY, target->width_pointer * 2, target->align_pref_pointer, target->align_pointer); - type_create("virtual_generic", &t_virtual_generic, TYPE_VIRTUAL, target->width_pointer * 2, target->align_pref_pointer, target->align_pointer); + type_void->type_cache[0] = &t.voidstar; + t.voidstar.pointer = type_void; + type_create("virtual*", &t.virtual, TYPE_VIRTUAL_ANY, target->width_pointer * 2, target->align_pref_pointer, target->align_pointer); + type_create("virtual_generic", &t.virtual_generic, TYPE_VIRTUAL, target->width_pointer * 2, target->align_pref_pointer, target->align_pointer); - type_create("compint", &t_ixx, TYPE_IXX, 0, 0, 0); - type_create("compfloat", &t_fxx, TYPE_FXX, 0, 0, 0); + type_create("compint", &t.ixx, TYPE_IXX, 0, 0, 0); + type_create("compfloat", &t.fxx, TYPE_FXX, 0, 0, 0); - type_create_alias("usize", &t_usz, type_int_unsigned_by_bitsize(target->width_pointer)); - type_create_alias("isize", &t_isz, type_int_signed_by_bitsize(target->width_pointer)); + type_create_alias("usize", &t.usz, type_int_unsigned_by_bitsize(target->width_pointer)); + type_create_alias("isize", &t.isz, type_int_signed_by_bitsize(target->width_pointer)); - type_create_alias("uptr", &t_uptr, type_int_unsigned_by_bitsize(target->width_pointer)); - type_create_alias("iptr", &t_iptr, type_int_signed_by_bitsize(target->width_pointer)); + type_create_alias("uptr", &t.uptr, type_int_unsigned_by_bitsize(target->width_pointer)); + type_create_alias("iptr", &t.iptr, type_int_signed_by_bitsize(target->width_pointer)); - type_create_alias("uptrdiff", &t_uptrdiff, type_int_unsigned_by_bitsize(target->width_pointer)); - type_create_alias("iptrdiff", &t_iptrdiff, type_int_signed_by_bitsize(target->width_pointer)); + type_create_alias("uptrdiff", &t.uptrdiff, type_int_unsigned_by_bitsize(target->width_pointer)); + type_create_alias("iptrdiff", &t.iptrdiff, type_int_signed_by_bitsize(target->width_pointer)); - type_create_alias("c_ushort", &t_cus, type_int_unsigned_by_bitsize(target->width_c_short)); - type_create_alias("c_uint", &t_cui, type_int_unsigned_by_bitsize(target->width_c_int)); - type_create_alias("c_ulong", &t_cul, type_int_unsigned_by_bitsize(target->width_c_long)); - type_create_alias("c_ulonglong", &t_cull, type_int_unsigned_by_bitsize(target->width_c_long_long)); + type_create_alias("c_ushort", &t.t_cus, type_int_unsigned_by_bitsize(target->width_c_short)); + type_create_alias("c_uint", &t.t_cui, type_int_unsigned_by_bitsize(target->width_c_int)); + type_create_alias("c_ulong", &t.t_cul, type_int_unsigned_by_bitsize(target->width_c_long)); + type_create_alias("c_ulonglong", &t.t_cull, type_int_unsigned_by_bitsize(target->width_c_long_long)); - type_create_alias("c_short", &t_cs, type_int_signed_by_bitsize(target->width_c_short)); - type_create_alias("c_int", &t_ci, type_int_signed_by_bitsize(target->width_c_int)); - type_create_alias("c_long", &t_cl, type_int_signed_by_bitsize(target->width_c_long)); - type_create_alias("c_longlong", &t_cll, type_int_signed_by_bitsize(target->width_c_long_long)); + type_create_alias("c_short", &t.t_cs, type_int_signed_by_bitsize(target->width_c_short)); + type_create_alias("c_int", &t.t_ci, type_int_signed_by_bitsize(target->width_c_int)); + type_create_alias("c_long", &t.t_cl, type_int_signed_by_bitsize(target->width_c_long)); + type_create_alias("c_longlong", &t.t_cll, type_int_signed_by_bitsize(target->width_c_long_long)); - alignment_subarray = MAX(type_abi_alignment(&t_voidstar), type_abi_alignment(t_usz.canonical)); + alignment_subarray = MAX(type_abi_alignment(&t.voidstar), type_abi_alignment(t.usz.canonical)); size_subarray = alignment_subarray * 2; - type_create("error", &t_error, TYPE_ERR_UNION, target->width_pointer * 2, target->align_pointer, target->align_pref_pointer); + type_create("error", &t.error, TYPE_ERR_UNION, target->width_pointer * 2, target->align_pointer, target->align_pref_pointer); } bool type_is_scalar(Type *type) @@ -1243,7 +1206,6 @@ bool type_is_scalar(Type *type) case TYPE_ENUM: case TYPE_ERRTYPE: case TYPE_ERR_UNION: - case TYPE_VARARRAY: case TYPE_VIRTUAL: case TYPE_VIRTUAL_ANY: return true; @@ -1368,7 +1330,7 @@ Type *type_find_max_num_type(Type *num_type, Type *other_num) static inline Type *type_find_max_ptr_type(Type *type, Type *other) { // Subarray and vararray can implicitly convert to a pointer. - if (other->type_kind == TYPE_SUBARRAY || other->type_kind == TYPE_VARARRAY) + if (other->type_kind == TYPE_SUBARRAY) { Type *max_type = type_find_max_type(type->pointer, other->pointer); if (!max_type) return NULL; @@ -1402,39 +1364,6 @@ static inline Type *type_find_max_ptr_type(Type *type, Type *other) return type_get_ptr(max_type); } -/** - * Find the maximum vararray type. Due to ordering the other type fullfils - * other->type_kind >= TYPE_VARARRAY - * - * @param type - * @param other - * @return maximum type or NULL if none is found. - */ -static inline Type *type_find_max_vararray_type(Type *type, Type *other) -{ - assert(other->canonical != type->canonical && "Expected different types"); - assert(other->type_kind >= type->type_kind && "Expected sorted types"); - switch (other->type_kind) - { - case TYPE_VARARRAY: - // Because of the stride being different, it's not safe to implictly - // convert one vararray to another. However, it is fine if they are both pointers - // since the stride is the same. - if (type->array.base->type_kind == TYPE_POINTER && other->array.base->type_kind == TYPE_POINTER) - { - // Jolly nice. Let's create the max from these: - Type *max_type = type_find_max_ptr_type(type->array.base, other->array.base); - if (max_type == NULL) return NULL; - return type_get_array(max_type, 0); - } - // If it's not a pointer then there's no real way of converting them. - return NULL; - case TYPE_SUBARRAY: - TODO; // Will return the subarray - default: - UNREACHABLE - } -} Type *type_find_max_type(Type *type, Type *other) { @@ -1504,8 +1433,6 @@ Type *type_find_max_type(Type *type, Type *other) return NULL; case TYPE_ARRAY: return NULL; - case TYPE_VARARRAY: - return type_find_max_vararray_type(type, other); case TYPE_SUBARRAY: TODO case TYPE_VECTOR: diff --git a/src/version.h b/src/version.h index 4317dfc4a..c65ec02d8 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "A227" \ No newline at end of file +#define COMPILER_VERSION "A228" \ No newline at end of file diff --git a/test/test_suite/comments/simple_comments.c3 b/test/test_suite/comments/simple_comments.c3 index 61cab8561..dd4fe904b 100644 --- a/test/test_suite/comments/simple_comments.c3 +++ b/test/test_suite/comments/simple_comments.c3 @@ -12,3 +12,4 @@ func void test() return; } +/* /* nested /* comments! */ !! */ goes here */ diff --git a/test/test_suite/struct/recursive_structs.c3 b/test/test_suite/struct/recursive_structs.c3 new file mode 100644 index 000000000..19dbbf06a --- /dev/null +++ b/test/test_suite/struct/recursive_structs.c3 @@ -0,0 +1,25 @@ +struct Test1 +{ + Test1 *x; +} + +struct Test2 +{ + Test2[] y; +} + +struct Test3 // #error: Recursive definition +{ + Test3[4] z; +} + +struct Test4 +{ + Test4[3]* w; +} + + +struct Test5 +{ + Test5[3][] w; +}