Errno updates with errno for linux/win/macos. Updated $$ syntax to also match compiler constants.
This commit is contained in:
Christoffer Lerno
2022-01-18 01:31:14 +01:00
committed by GitHub
parent 3f60443d66
commit e4e8abbc6c
22 changed files with 186 additions and 99 deletions

View File

@@ -3,10 +3,10 @@
// a copy of which can be found in the LICENSE_STDLIB file.
module std::cinterop;
const C_INT_SIZE = ${C_INT_SIZE};
const C_LONG_SIZE = ${C_LONG_SIZE};
const C_SHORT_SIZE = ${C_SHORT_SIZE};
const C_LONG_LONG_SIZE = ${C_LONG_LONG_SIZE};
const C_INT_SIZE = $$C_INT_SIZE;
const C_LONG_SIZE = $$C_LONG_SIZE;
const C_SHORT_SIZE = $$C_SHORT_SIZE;
const C_LONG_LONG_SIZE = $$C_LONG_LONG_SIZE;
$assert (C_SHORT_SIZE < 32);
$assert (C_INT_SIZE < 128);
@@ -16,55 +16,55 @@ $assert (C_SHORT_SIZE <= C_INT_SIZE);
$assert (C_INT_SIZE <= C_LONG_SIZE);
$assert (C_LONG_SIZE <= C_LONG_LONG_SIZE);
$if (C_INT_SIZE == 64):
$if C_INT_SIZE == 64:
define CInt = long;
define CUInt = ulong;
$elif (C_INT_SIZE == 32):
$elif C_INT_SIZE == 32:
define CInt = int;
define CUInt = uint;
$elif (C_INT_SIZE == 16):
$elif C_INT_SIZE == 16:
define CInt = short;
define CUInt = ushort;
$else:
$assert(false, "Invalid C int size");
$endif;
$if (C_LONG_SIZE == 64):
$if C_LONG_SIZE == 64:
define CLong = long;
define CULong = ulong;
$elif (C_LONG_SIZE == 32):
$elif C_LONG_SIZE == 32:
define CLong = int;
define CULong = uint;
$elif (C_LONG_SIZE == 16):
$elif C_LONG_SIZE == 16:
define CLong = short;
define CULong = ushort;
$else:
$assert(false, "Invalid C long size");
$endif;
$if (C_SHORT_SIZE == 32):
$if C_SHORT_SIZE == 32:
define CShort = int;
define CUShort = uint;
$elif (C_SHORT_SIZE == 16):
$elif C_SHORT_SIZE == 16:
define CShort = short;
define CUShort = ushort;
$elif (C_SHORT_SIZE == 8):
$elif C_SHORT_SIZE == 8:
define CShort = ichar;
define CUShort = char;
$else:
$assert(false, "Invalid C short size");
$endif;
$if (C_LONG_LONG_SIZE == 128):
$if C_LONG_LONG_SIZE == 128:
define CLongLong = int128;
define CULongLong = uint128;
$elif (C_LONG_LONG_SIZE == 64):
$elif C_LONG_LONG_SIZE == 64:
define CLongLong = long;
define CULongLong = ulong;
$elif (C_LONG_LONG_SIZE == 32):
$elif C_LONG_LONG_SIZE == 32:
define CLongLong = int;
define CULongLong = uint;
$elif (C_LONG_LONG_SIZE == 16):
$elif C_LONG_LONG_SIZE == 16:
define CLongLong = short;
define CULongLong = ushort;
$else:
@@ -74,7 +74,7 @@ $endif;
define CSChar = ichar;
define CUChar = char;
$if (${C_CHAR_IS_SIGNED}):
$if $$C_CHAR_IS_SIGNED:
define CChar = ichar;
$else:
define CChar = char;

View File

@@ -11,7 +11,48 @@ enum CompilerOptLevel
O3
}
const CompilerOptLevel COMPILER_OPT_LEVEL = (CompilerOptLevel)(${COMPILER_OPT_LEVEL});
const bool BIG_ENDIAN = ${PLATFORM_BIG_ENDIAN};
const bool I128_SUPPORT = ${PLATFORM_I128_SUPPORTED};
const bool COMPILER_SAFE_MODE = ${COMPILER_SAFE_MODE};
enum OsType
{
UNKNOWN,
NONE,
ANANAS,
CLOUD_ABI,
DRAGON_FLY,
FREEBSD,
FUCHSIA,
IOS,
KFREEBSD,
LINUX,
PS3,
MACOSX,
NETBSD,
OPENBSD,
SOLARIS,
WIN32,
HAIKU,
MINIX,
RTEMS,
NACL, // Native Client
CNK, // BG/P Compute-Node Kernel
AIX,
CUDA,
NVOPENCL,
AMDHSA,
PS4,
ELFIAMCU,
TVOS,
WATCHOS,
MESA3D,
CONTIKI,
AMDPAL,
HERMITCORE,
HURD,
WASI,
EMSCRIPTEN,
}
const OsType OS_TYPE = (OsType)($$OS_TYPE);
const CompilerOptLevel COMPILER_OPT_LEVEL = (CompilerOptLevel)($$COMPILER_OPT_LEVEL);
const bool BIG_ENDIAN = $$PLATFORM_BIG_ENDIAN;
const bool I128_SUPPORT = $$PLATFORM_I128_SUPPORTED;
const bool COMPILER_SAFE_MODE = $$COMPILER_SAFE_MODE;

View File

@@ -3,7 +3,10 @@
// a copy of which can be found in the LICENSE_STDLIB file.
module libc;
import std::cinterop;
import std::env;
import std::os::linux;
import std::os::macos;
import std::os::windows;
// stdlib
// Constants need to be per os/arch
@@ -160,7 +163,19 @@ enum Errno : ErrnoType
ENOTRECOVERABLE = 131, /* State not recoverable */
}
extern fn Errno errno();
fn Errno errno()
{
$if (env::OS_TYPE == OsType.WIN32):
return windows::errno();
$elif (env::OS_TYPE == OsType.MACOSX):
return macos::errno();
$elif (env::OS_TYPE == OsType.LINUX):
return linux::errno();
$else:
return Errno.ENOTRECOVERABLE;
$endif;
}
define TerminateFunction = fn void();
define CompareFunction = fn int(void*, void*);
@@ -233,15 +248,15 @@ const int EOF = -1;
const int FOPEN_MAX = 20;
const int FILENAME_MAX = 1024;
$if (${C_INT_SIZE} == 64):
$if $$C_INT_SIZE == 64:
define ErrnoType = long;
$elif (${C_INT_SIZE} == 32):
$elif $$C_INT_SIZE == 32:
define ErrnoType = int;
$else:
define ErrnoType = short;
$endif;
$if (${C_LONG_SIZE} == 64):
$if $$C_LONG_SIZE == 64:
define SeekIndex = long;
$else:
define SeekIndex = int;
@@ -287,7 +302,7 @@ extern fn void perror(char* str);
// time.h
$if (${C_LONG_SIZE} == 64):
$if $$C_LONG_SIZE == 64:
define TimeOffset = long;
$else:
define TimeOffset = int;

View File

@@ -0,0 +1,18 @@
module std::os::linux;
import std::env;
$if (env::OS_TYPE == OsType.LINUX):
extern fn int* __errno_location();
fn int errno() @inline
{
return *__errno_location();
}
fn void errno_set(int errno)
{
*(__errno_location()) = errno;
}
$endif;

View File

@@ -0,0 +1,15 @@
module std::os::macos;
import std::env;
$if (env::OS_TYPE == OsType.MACOSX):
extern fn int* __error();
fn int errno() @inline
{
return *__error();
}
fn void errno_set(int errno)
{
*(__error()) = errno;
}
$endif;

View File

@@ -0,0 +1,10 @@
module std::os::windows;
import std::env;
$if (env::OS_TYPE == OsType.WIN32):
extern fn int getLastError() @stdcall @extname("GetLastError");
fn int errno() @inline
{
return getLastError();
}
$endif;

View File

@@ -231,6 +231,7 @@ bool expr_is_pure(Expr *expr)
{
case EXPR_BUILTIN:
return false;
case EXPR_COMPILER_CONST:
case EXPR_CONST:
case EXPR_CONST_IDENTIFIER:
case EXPR_IDENTIFIER:
@@ -280,7 +281,6 @@ bool expr_is_pure(Expr *expr)
case EXPR_FLATPATH:
case EXPR_INITIALIZER_LIST:
case EXPR_DESIGNATED_INITIALIZER_LIST:
case EXPR_PLACEHOLDER:
case EXPR_POST_UNARY:
case EXPR_SCOPED_EXPR:
case EXPR_SLICE_ASSIGN:

View File

@@ -422,6 +422,7 @@ void compile()
setup_bool_define("PLATFORM_BIG_ENDIAN", platform_target.big_endian);
setup_bool_define("PLATFORM_I128_SUPPORTED", platform_target.int128);
setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)active_target.optimization_level, type_int);
setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int);
setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.size_optimization_level, type_int);
setup_bool_define("COMPILER_SAFE_MODE", active_target.feature.safe_mode);

View File

@@ -2344,29 +2344,27 @@ static inline Type *type_flatten_distinct(Type *type)
static inline Type *type_flatten(Type *type)
{
type = type->canonical;
while (1)
{
if (type->type_kind == TYPE_DISTINCT)
type = type->canonical;
switch (type->type_kind)
{
type = type->decl->distinct_decl.base_type;
continue;
case TYPE_DISTINCT:
type = type->decl->distinct_decl.base_type;
break;
case TYPE_ENUM:
type = type->decl->enums.type_info->type;
break;
case TYPE_FAILABLE:
type = type->failable;
break;
case TYPE_FAILABLE_ANY:
return type_void;
case TYPE_TYPEDEF:
UNREACHABLE
default:
return type;
}
if (type->type_kind == TYPE_ENUM)
{
type = type->decl->enums.type_info->type;
continue;
}
if (type->type_kind == TYPE_FAILABLE)
{
type = type->failable;
continue;
}
if (type->type_kind == TYPE_FAILABLE_ANY)
{
return type_void;
}
return type;
}
}

View File

@@ -101,11 +101,11 @@ Expr *copy_expr(Expr *source_expr)
MACRO_COPY_EXPR_LIST(expr->catch_unwrap_expr.exprs);
MACRO_COPY_TYPE(expr->catch_unwrap_expr.type);
return expr;
case EXPR_PLACEHOLDER:
case EXPR_CONST_IDENTIFIER:
case EXPR_CT_IDENT:
case EXPR_IDENTIFIER:
case EXPR_HASH_IDENT:
case EXPR_COMPILER_CONST:
return expr;
case EXPR_MACRO_EXPANSION:
MACRO_COPY_EXPR(expr->macro_expansion_expr.inner);

View File

@@ -174,6 +174,7 @@ typedef enum
EXPR_BITASSIGN,
EXPR_BINARY,
EXPR_BUILTIN,
EXPR_COMPILER_CONST,
EXPR_MACRO_BODY_EXPANSION,
EXPR_CALL,
EXPR_CAST,
@@ -203,7 +204,6 @@ typedef enum
EXPR_DESIGNATED_INITIALIZER_LIST,
EXPR_LEN,
EXPR_PTR,
EXPR_PLACEHOLDER,
EXPR_POST_UNARY,
EXPR_SCOPED_EXPR,
EXPR_SLICE,
@@ -350,7 +350,6 @@ typedef enum
TOKEN_MULT_ASSIGN, // *=
TOKEN_NOT_EQUAL, // !=
TOKEN_OR, // ||
TOKEN_PLACEHOLDER, // ${
TOKEN_PLUS_ASSIGN, // +=
TOKEN_PLUSPLUS, // ++
TOKEN_RBRAPIPE, // |}

View File

@@ -1717,7 +1717,6 @@ 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, "${");
if (match(lexer, '$'))
{
if (is_letter(peek(lexer)))

View File

@@ -8,6 +8,10 @@ ABIArgInfo *win64_classify(Regs *regs, Type *type, bool is_return, bool is_vecto
{
if (type->type_kind == TYPE_VOID) return abi_arg_ignore();
if (type_lowering(type)->type_kind == TYPE_TYPEDEF)
{
printf("foekf");
}
// Lower enums etc.
type = type_lowering(type);

View File

@@ -5431,7 +5431,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
case EXPR_MACRO_EXPANSION:
case EXPR_CT_IDENT:
case EXPR_HASH_IDENT:
case EXPR_PLACEHOLDER:
case EXPR_COMPILER_CONST:
case EXPR_CT_CALL:
case EXPR_FLATPATH:
case EXPR_VARIANTSWITCH:

View File

@@ -943,27 +943,21 @@ static Expr *parse_builtin(ParseContext *context, Expr *left)
assert(!left && "Had left hand side");
Expr *expr = EXPR_NEW_TOKEN(EXPR_BUILTIN, context->tok);
advance_and_verify(context, TOKEN_BUILTIN);
expr->builtin_expr.identifier = context->tok;
CONSUME_OR(TOKEN_IDENT, poisoned_expr);
RANGE_EXTEND_PREV(expr);
return expr;
}
static Expr *parse_placeholder(ParseContext *context, Expr *left)
{
assert(!left && "Had left hand side");
advance_and_verify(context, TOKEN_PLACEHOLDER);
ASSIGN_EXPR_ELSE(Expr *expr, 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)
if (!token_is_some_ident(context->tok.type))
{
SEMA_ERROR(expr, "Expected an uppercase identifier that corresponds to a compile time argument.");
SEMA_TOKEN_ERROR(context->tok, "Expected a name here.");
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;
expr->builtin_expr.identifier = context->tok;
if (try_consume(context, TOKEN_CONST_IDENT))
{
expr->expr_kind = EXPR_COMPILER_CONST;
}
else
{
CONSUME_OR(TOKEN_IDENT, poisoned_expr);
}
RANGE_EXTEND_PREV(expr);
return expr;
}
@@ -1616,7 +1610,6 @@ 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_BUILTIN] = { parse_builtin, NULL, PREC_NONE },
[TOKEN_CHAR_LITERAL] = { parse_char_lit, NULL, PREC_NONE },
[TOKEN_AT] = { parse_macro_expansion, NULL, PREC_NONE },

View File

@@ -139,7 +139,7 @@ static inline Decl *parse_ct_if_top_level(ParseContext *context)
{
advance_and_verify(context, TOKEN_CT_IF);
Decl *ct = decl_new_ct(DECL_CT_IF, context->prev_tok);
ASSIGN_EXPR_ELSE(ct->ct_if_decl.expr, parse_const_paren_expr(context), poisoned_decl);
ASSIGN_EXPR_ELSE(ct->ct_if_decl.expr, parse_constant_expr(context), poisoned_decl);
if (!parse_top_level_block(context, &ct->ct_if_decl.then, TOKEN_CT_ENDIF, TOKEN_CT_ELIF, TOKEN_CT_ELSE)) return poisoned_decl;
@@ -148,7 +148,7 @@ static inline Decl *parse_ct_if_top_level(ParseContext *context)
{
advance_and_verify(context, TOKEN_CT_ELIF);
Decl *ct_elif = decl_new_ct(DECL_CT_ELIF, context->prev_tok);
ASSIGN_EXPR_ELSE(ct_elif->ct_elif_decl.expr, parse_const_paren_expr(context), poisoned_decl);
ASSIGN_EXPR_ELSE(ct_elif->ct_elif_decl.expr, parse_constant_expr(context), poisoned_decl);
if (!parse_top_level_block(context, &ct_elif->ct_elif_decl.then, TOKEN_CT_ENDIF, TOKEN_CT_ELIF, TOKEN_CT_ELSE)) return poisoned_decl;
ct_if_decl->elif = ct_elif;

View File

@@ -965,7 +965,6 @@ Ast *parse_stmt(ParseContext *context)
case TOKEN_BANGBANG:
case TOKEN_UNDERSCORE:
case TOKEN_PRIVATE:
case TOKEN_PLACEHOLDER:
case TOKEN_BITSTRUCT:
case TOKEN_LVEC:
case TOKEN_RVEC:

View File

@@ -802,7 +802,6 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type)
case EXPR_FLATPATH:
case EXPR_INITIALIZER_LIST:
case EXPR_DESIGNATED_INITIALIZER_LIST:
case EXPR_PLACEHOLDER:
case EXPR_TYPEID:
case EXPR_TYPEINFO:
case EXPR_UNDEF:
@@ -818,6 +817,7 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type)
case EXPR_PTR:
case EXPR_VARIANTSWITCH:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_COMPILER_CONST:
UNREACHABLE
case EXPR_POST_UNARY:
return recursive_may_narrow_float(expr->unary_expr.expr, type);
@@ -959,7 +959,6 @@ Expr *recursive_may_narrow_int(Expr *expr, Type *type)
case EXPR_FLATPATH:
case EXPR_INITIALIZER_LIST:
case EXPR_DESIGNATED_INITIALIZER_LIST:
case EXPR_PLACEHOLDER:
case EXPR_TYPEID:
case EXPR_TYPEINFO:
case EXPR_UNDEF:
@@ -973,6 +972,7 @@ Expr *recursive_may_narrow_int(Expr *expr, Type *type)
case EXPR_PTR:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_VARIANTSWITCH:
case EXPR_COMPILER_CONST:
UNREACHABLE
case EXPR_POST_UNARY:
return recursive_may_narrow_int(expr->unary_expr.expr, type);

View File

@@ -449,7 +449,7 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
case EXPR_FLATPATH:
case EXPR_COMPOUND_LITERAL:
case EXPR_MACRO_EXPANSION:
case EXPR_PLACEHOLDER:
case EXPR_COMPILER_CONST:
case EXPR_POISONED:
case EXPR_ARGV_TO_SUBARRAY:
UNREACHABLE
@@ -6016,9 +6016,9 @@ static inline bool sema_expr_analyse_failable(SemaContext *context, Expr *expr)
return true;
}
static inline bool sema_expr_analyse_placeholder(SemaContext *context, Expr *expr)
static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *expr)
{
const char *string = TOKSTR(expr->placeholder_expr.identifier);
const char *string = TOKSTR(expr->builtin_expr.identifier);
if (string == kw_FILE)
{
expr_rewrite_to_string(expr, context->unit->file->name);
@@ -6054,7 +6054,7 @@ static inline bool sema_expr_analyse_placeholder(SemaContext *context, Expr *exp
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);
SEMA_ERROR(expr, "The compiler constant '%s' was not defined, did you mistype or forget to add it?", string);
return false;
}
expr_replace(expr, value);
@@ -6868,8 +6868,8 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr)
return sema_expr_analyse_ct_identifier(context, expr);
case EXPR_FAILABLE:
return sema_expr_analyse_failable(context, expr);
case EXPR_PLACEHOLDER:
return sema_expr_analyse_placeholder(context, expr);
case EXPR_COMPILER_CONST:
return sema_expr_analyse_compiler_const(context, expr);
case EXPR_POISONED:
return false;
case EXPR_LEN:

View File

@@ -110,8 +110,6 @@ 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:

View File

@@ -292,10 +292,10 @@ void file_add_wildcard_files(const char ***files, const char *path, bool recursi
while ((ent = readdir(dir)))
{
size_t namelen = strlen(ent->d_name);
if (namelen < 3) continue;
if (namelen == 0 || ent->d_name[0] == '.') continue;
// Doesn't end with .c3
if (strncmp(&ent->d_name[namelen - len1], suffix1, len1) != 0 && strncmp(&ent->d_name[namelen - len2], suffix2, len2) != 0)
if (namelen < 3 || (strncmp(&ent->d_name[namelen - len1], suffix1, len1) != 0 && strncmp(&ent->d_name[namelen - len2], suffix2, len2) != 0))
{
char *new_path = NULL;
char *format = path_ends_with_slash ? "%s%s" : "%s/%s";

View File

@@ -1,31 +1,28 @@
$if 3: // #error: Expected '('
$endif;
int x;
$if (x > 0):
$if x > 0:
$endif;
$if (0):
$if 0:
$assert(false);
$endif;
$if (1):
$if 1:
$else:
$endif;
$if (1):
$if 1:
$else:
$else: // #error: Expected a top level declaration here.
$endif;
$if (1):
$elif (2):
$if 1:
$elif 2:
$else:
$endif;
$if (1):
$elif (2):
$elif (3):
$if 1:
$elif 2:
$elif 3:
$else:
$endif;