Skip to content

Commit

Permalink
$embed
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Jul 7, 2023
1 parent 8780df8 commit 371cb81
Show file tree
Hide file tree
Showing 27 changed files with 309 additions and 175 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Changes / improvements
- New generic syntax.
- Added `$embed` to embed binary data.
- Ad hoc generics are now allowed.
- Allow inferred type on method first argument.
- Fix to void expression blocks
Expand Down
32 changes: 22 additions & 10 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,11 @@ typedef struct
uint64_t ptr;
bool b;
struct
{
const char *chars;
ArraySize len;
} string;
Decl *enum_err_val;
struct
{
const char *ptr;
TypeSize len;
ArraySize len;
} bytes;
Decl *enum_err_val;
Type *typeid;
ConstInitializer *initializer;
Expr **untyped_list;
Expand All @@ -222,6 +217,7 @@ typedef struct
{
FileId file_id;
const char *contents;
size_t content_len;
char *name;
char *dir_path;
const char *full_path;
Expand Down Expand Up @@ -593,7 +589,7 @@ typedef struct

typedef enum
{
DEFINE_TYPE_GENERIC,
DEFINE_TYPE_GENERIC_OLD,
DEFINE_IDENT_ALIAS,
DEFINE_IDENT_GENERIC,
} DefineType;
Expand Down Expand Up @@ -846,6 +842,11 @@ typedef struct
ExprId inner;
} ExprBuiltinAccess;

typedef struct
{
Expr *filename;
Expr *default_value;
} ExprEmbedExpr;
typedef struct
{
ExprId parent;
Expand Down Expand Up @@ -1146,6 +1147,7 @@ struct Expr_
ExprTryUnwrap try_unwrap_expr; // 24
ExprCall call_expr; // 32
Expr *inner_expr; // 8
ExprEmbedExpr embed_expr;
ExprBuiltinAccess builtin_access_expr;
ExprGenericIdent generic_ident_expr;
ExprCatchUnwrap catch_unwrap_expr; // 24
Expand Down Expand Up @@ -2213,7 +2215,7 @@ Path *path_create_from_string(const char *string, uint32_t len, SourceSpan span)
#define SEMA_ERROR(_node, ...) sema_error_at((_node)->span, __VA_ARGS__)
#define RETURN_SEMA_ERROR(_node, ...) do { sema_error_at((_node)->span, __VA_ARGS__); return false; } while (0)
#define SEMA_NOTE(_node, ...) sema_error_prev_at((_node)->span, __VA_ARGS__)
#define EXPAND_EXPR_STRING(str_) (str_)->const_expr.string.len, (str_)->const_expr.string.chars
#define EXPAND_EXPR_STRING(str_) (str_)->const_expr.bytes.len, (str_)->const_expr.bytes.ptr
#define TABLE_MAX_LOAD 0.5

void sema_analysis_run(void);
Expand Down Expand Up @@ -2939,7 +2941,7 @@ INLINE bool decl_is_user_defined_type(Decl *decl)

INLINE Decl *decl_flatten(Decl *decl)
{
if (decl->decl_kind == DECL_DEFINE && decl->define_decl.define_kind != DEFINE_TYPE_GENERIC)
if (decl->decl_kind == DECL_DEFINE && decl->define_decl.define_kind != DEFINE_TYPE_GENERIC_OLD)
{
return decl->define_decl.alias;
}
Expand Down Expand Up @@ -3318,11 +3320,21 @@ INLINE bool expr_is_const_pointer(Expr *expr)
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_POINTER;
}

INLINE bool expr_is_const_bool(Expr *expr)
{
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_BOOL;
}

INLINE bool expr_is_const_initializer(Expr *expr)
{
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_INITIALIZER;
}

INLINE bool expr_is_const_bytes(Expr *expr)
{
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_BYTES;
}

INLINE bool expr_is_const_untyped_list(Expr *expr)
{
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_UNTYPED_LIST;
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/copying.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
{
case EXPR_ANYSWITCH:
UNREACHABLE
case EXPR_EMBED:
MACRO_COPY_EXPR(expr->embed_expr.default_value);
MACRO_COPY_EXPR(expr->embed_expr.filename);
return expr;
case EXPR_GENERIC_IDENT:
MACRO_COPY_EXPRID(expr->generic_ident_expr.parent);
MACRO_COPY_EXPR_LIST(expr->generic_ident_expr.parmeters);
Expand Down Expand Up @@ -971,7 +975,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl)
case DECL_DEFINE:
switch (decl->define_decl.define_kind)
{
case DEFINE_TYPE_GENERIC:
case DEFINE_TYPE_GENERIC_OLD:
case DEFINE_IDENT_GENERIC:
MACRO_COPY_EXPR_LIST(decl->define_decl.generic_params);
break;
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ typedef enum
EXPR_DECL,
EXPR_DESIGNATED_INITIALIZER_LIST,
EXPR_DESIGNATOR,
EXPR_EMBED,
EXPR_EXPRESSION_LIST,
EXPR_EXPR_BLOCK,
EXPR_OPTIONAL,
Expand Down Expand Up @@ -556,6 +557,7 @@ typedef enum
TOKEN_CT_DEFINED, // $defined
TOKEN_CT_ECHO, // $echo
TOKEN_CT_ELSE, // $else
TOKEN_CT_EMBED, // $embed
TOKEN_CT_ENDFOR, // $endfor
TOKEN_CT_ENDFOREACH, // $endforeach
TOKEN_CT_ENDIF, // $endif
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ bool expr_may_addr(Expr *expr)
case EXPR_SWIZZLE:
case EXPR_LAMBDA:
case EXPR_GENERIC_IDENT:
case EXPR_EMBED:
return false;
}
UNREACHABLE
Expand Down Expand Up @@ -203,6 +204,7 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
case EXPR_STRINGIFY:
case EXPR_CT_CHECKS:
case EXPR_LAMBDA:
case EXPR_EMBED:
return true;
case EXPR_COND:
return expr_list_is_constant_eval(expr->cond_expr, eval_kind);
Expand Down Expand Up @@ -662,6 +664,7 @@ bool expr_is_pure(Expr *expr)
case EXPR_OPERATOR_CHARS:
case EXPR_CT_CHECKS:
case EXPR_LAMBDA:
case EXPR_EMBED:
return true;
case EXPR_VASPLAT:
return true;
Expand Down Expand Up @@ -932,9 +935,9 @@ void expr_rewrite_to_string(Expr *expr_to_rewrite, const char *string)
{
expr_to_rewrite->expr_kind = EXPR_CONST;
expr_to_rewrite->const_expr.const_kind = CONST_STRING;
expr_to_rewrite->const_expr.string.chars = (char *)string;
expr_to_rewrite->const_expr.bytes.ptr = (char *)string;
ArraySize len = (ArraySize)strlen(string);
expr_to_rewrite->const_expr.string.len = len;
expr_to_rewrite->const_expr.bytes.len = len;
expr_to_rewrite->resolve_status = RESOLVE_DONE;
expr_to_rewrite->type = type_string;
}
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/headers.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
Expr *init = decl->var.init_expr;
if (type_is_arraylike(type) || type_is_user_defined(type) || !init) return;
OUTPUT("#define %s ", decl_get_extname(decl));
assert(init->expr_kind == EXPR_CONST);
assert(expr_is_const(init));
switch (init->const_expr.const_kind)
{
case CONST_INTEGER:
Expand All @@ -503,9 +503,9 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
return;
case CONST_STRING:
putc('\"', file);
for (unsigned i = 0; i < init->const_expr.string.len; i++)
for (unsigned i = 0; i < init->const_expr.bytes.len; i++)
{
char ch = init->const_expr.string.chars[i];
char ch = init->const_expr.bytes.ptr[i];
if (ch >= ' ' && ch <= 127 && ch != '"')
{
fputc(ch, file);
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/llvm_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,15 +395,15 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
}
if (init_expr)
{
if (init_expr->expr_kind == EXPR_CONST && init_expr->const_expr.const_kind == CONST_INITIALIZER)
if (expr_is_const_initializer(init_expr))
{
ConstInitializer *list = init_expr->const_expr.initializer;
init_value = llvm_emit_const_initializer(c, list);
}
else
{
BEValue value;
if (init_expr->expr_kind == EXPR_CONST && init_expr->const_expr.const_kind == CONST_BYTES)
if (expr_is_const_bytes(init_expr))
{
init_value = llvm_get_bytes(c, init_expr->const_expr.bytes.ptr, init_expr->const_expr.bytes.len);
}
Expand Down Expand Up @@ -1071,7 +1071,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
}
return backend_ref;
case DECL_DEFINE:
if (decl->define_decl.define_kind != DEFINE_TYPE_GENERIC) return llvm_get_ref(c, decl->define_decl.alias);
if (decl->define_decl.define_kind != DEFINE_TYPE_GENERIC_OLD) return llvm_get_ref(c, decl->define_decl.alias);
UNREACHABLE
case DECL_FAULTVALUE:
if (!decl->backend_ref)
Expand Down
Loading

0 comments on commit 371cb81

Please sign in to comment.