"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/onyx",
- "args": ["progs/structs.onyx"],
+ "args": ["progs/ufc.onyx"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
[X] Bitwise operators
- [ ] Dead code elimination
+ [X] Dead code elimination
+ - Start with uncalled functions being removed
+ - Foreign functions will rename in the code because it is turning out
+ to be a nightmare to remove them. Lot's of refactoring... ugh
[ ] Enum types
// Function flags
Ast_Flag_Inline = BH_BIT(8),
Ast_Flag_Intrinsic = BH_BIT(9),
+ Ast_Flag_Function_Used = BH_BIT(10),
// Expression flags
Ast_Flag_Expr_Ignored = BH_BIT(8),
Binary_Op_Bool_And = 17,
Binary_Op_Bool_Or = 18,
- Binary_Op_Bool_Xor = 19,
-
- Binary_Op_Assign_Start = 20,
- Binary_Op_Assign = 21,
- Binary_Op_Assign_Add = 22,
- Binary_Op_Assign_Minus = 23,
- Binary_Op_Assign_Multiply = 24,
- Binary_Op_Assign_Divide = 25,
- Binary_Op_Assign_Modulus = 26,
- Binary_Op_Assign_And = 27,
- Binary_Op_Assign_Or = 28,
- Binary_Op_Assign_Xor = 29,
- Binary_Op_Assign_Shl = 30,
- Binary_Op_Assign_Shr = 31,
- Binary_Op_Assign_Sar = 32,
- Binary_Op_Assign_End = 33,
+
+ Binary_Op_Assign_Start = 19,
+ Binary_Op_Assign = 20,
+ Binary_Op_Assign_Add = 21,
+ Binary_Op_Assign_Minus = 22,
+ Binary_Op_Assign_Multiply = 23,
+ Binary_Op_Assign_Divide = 24,
+ Binary_Op_Assign_Modulus = 25,
+ Binary_Op_Assign_And = 26,
+ Binary_Op_Assign_Or = 27,
+ Binary_Op_Assign_Xor = 28,
+ Binary_Op_Assign_Shl = 29,
+ Binary_Op_Assign_Shr = 30,
+ Binary_Op_Assign_Sar = 31,
+ Binary_Op_Assign_End = 32,
} BinaryOp;
typedef enum OnyxIntrinsic {
Token_Type_Xor_Equal = 288,
Token_Type_And_And = 289,
Token_Type_Or_Or = 290,
- Token_Type_Xor_Xor = 291,
- Token_Type_Shift_Left = 292,
- Token_Type_Shift_Right = 293,
- Token_Type_Shift_Arith_Right = 294,
- Token_Type_Shl_Equal = 295,
- Token_Type_Shr_Equal = 296,
- Token_Type_Sar_Equal = 297,
-
- Token_Type_Symbol = 298,
- Token_Type_Literal_String = 299,
- Token_Type_Literal_Numeric = 300,
- Token_Type_Literal_True = 301,
- Token_Type_Literal_False = 302,
-
- Token_Type_Count = 303,
+ Token_Type_Shift_Left = 291,
+ Token_Type_Shift_Right = 292,
+ Token_Type_Shift_Arith_Right = 293,
+ Token_Type_Shl_Equal = 294,
+ Token_Type_Shr_Equal = 295,
+ Token_Type_Sar_Equal = 296,
+
+ Token_Type_Symbol = 297,
+ Token_Type_Literal_String = 298,
+ Token_Type_Literal_Numeric = 299,
+ Token_Type_Literal_True = 300,
+ Token_Type_Literal_False = 301,
+
+ Token_Type_Count = 302,
} TokenType;
typedef struct OnyxFilePos {
// to make any more node in the tree
bh_allocator allocator, node_allocator;
+ // NOTE: Used wherever
+ ProgramInfo* program;
+
// NOTE: Used in symbol resolution phase
Scope* global_scope;
Scope* curr_scope;
extern SemState semstate;
// NOTE: Resolving all symbols in the tree
-void onyx_resolve_symbols(ProgramInfo* program);
+void onyx_resolve_symbols();
// NOTE: Inferring and checking types in the tree
-void onyx_type_check(ProgramInfo* program);
+void onyx_type_check();
// NOTE: Full semantic pass
void onyx_sempass_init(bh_allocator alloc, bh_allocator node_alloc);
return 1;
}
+ callee->flags |= Ast_Flag_Function_Used;
+
return 0;
}
}
if (binop->operation >= Binary_Op_Bool_And
- && binop->operation <= Binary_Op_Bool_Xor) {
+ && binop->operation <= Binary_Op_Bool_Or) {
if (!type_is_bool(binop->left->type) || !type_is_bool(binop->right->type)) {
onyx_message_add(Msg_Type_Literal,
}
}
-void onyx_type_check(ProgramInfo* program) {
- bh_arr_each(Entity, entity, program->entities) {
+void onyx_type_check() {
+ bh_arr_each(Entity, entity, semstate.program->entities) {
switch (entity->type) {
case Entity_Type_Function_Header:
- if (entity->function->flags & Ast_Kind_Foreign) program->foreign_func_count++;
+ if (entity->function->flags & Ast_Kind_Foreign)
+ semstate.program->foreign_func_count++;
+
if (check_function_header(entity->function)) return;
break;
break;
case Entity_Type_Global:
- if (entity->global->flags & Ast_Kind_Foreign) program->foreign_global_count++;
+ if (entity->global->flags & Ast_Kind_Foreign)
+ semstate.program->foreign_global_count++;
if (check_global(entity->global)) return;
break;
"*=",
"/=",
"%=",
+ "&=",
+ "|=",
+ "^=",
+ "&&",
+ "||",
+ "^^",
+ "<<",
+ ">>",
+ ">>>",
+ "<<=",
+ ">>=",
+ ">>>="
"TOKEN_TYPE_SYMBOL",
"TOKEN_TYPE_LITERAL_STRING",
LITERAL_TOKEN("---", 0, Token_Type_Empty_Block);
LITERAL_TOKEN("&&", 0, Token_Type_And_And);
LITERAL_TOKEN("||", 0, Token_Type_Or_Or);
- LITERAL_TOKEN("^^", 0, Token_Type_Xor_Xor);
LITERAL_TOKEN(">>>=", 0, Token_Type_Sar_Equal);
LITERAL_TOKEN(">>=", 0, Token_Type_Shr_Equal);
LITERAL_TOKEN("<<=", 0, Token_Type_Shl_Equal);
case Binary_Op_Bool_And: return 2;
case Binary_Op_Bool_Or: return 2;
- case Binary_Op_Bool_Xor: return 2;
case Binary_Op_Equal: return 3;
case Binary_Op_Not_Equal: return 3;
case Token_Type_And_And: bin_op_kind = Binary_Op_Bool_And; break;
case Token_Type_Or_Or: bin_op_kind = Binary_Op_Bool_Or; break;
- case Token_Type_Xor_Xor: bin_op_kind = Binary_Op_Bool_Xor; break;
case '=': bin_op_kind = Binary_Op_Assign; break;
case Token_Type_Plus_Equal: bin_op_kind = Binary_Op_Assign_Add; break;
}
void onyx_sempass(ProgramInfo* program) {
+ semstate.program = program;
+
onyx_resolve_symbols(program);
if (onyx_message_has_errors()) return;
}
}
-void onyx_resolve_symbols(ProgramInfo* program) {
+void onyx_resolve_symbols() {
semstate.global_scope = scope_create(semstate.node_allocator, NULL);
scope_enter(semstate.global_scope);
bsym++;
}
- bh_arr_each(AstBinding *, binding, program->bindings)
+ bh_arr_each(AstBinding *, binding, semstate.program->bindings)
if (!symbol_introduce((*binding)->token, (*binding)->node)) return;
- bh_arr_each(Entity, entity, program->entities) {
+ bh_arr_each(Entity, entity, semstate.program->entities) {
switch (entity->type) {
case Entity_Type_Function: symres_function(entity->function); break;
case Entity_Type_Overloaded_Function: symres_overloaded_function(entity->overloaded_function); break;
/* BAND */ { WI_I32_AND, WI_I64_AND, WI_NOP, WI_NOP },
/* BOR */ { WI_I32_OR, WI_I64_OR, WI_NOP, WI_NOP },
- /* BXOR */ { WI_I32_XOR, WI_I64_XOR, WI_NOP, WI_NOP },
};
COMPILE_FUNC(binop, AstBinaryOp* binop) {
return type_idx;
}
+static inline b32 should_compile_function(AstFunction* fd) {
+ // NOTE: Don't output intrinsic functions
+ if (fd->flags & Ast_Flag_Intrinsic) return 0;
+
+ if (fd->flags & Ast_Flag_Foreign) return 1;
+
+ // NOTE: Don't output functions that are not used, only if
+ // they are also not exported.
+ if ((fd->flags & Ast_Flag_Function_Used) == 0) {
+ if (fd->flags & Ast_Flag_Exported) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static void compile_function(OnyxWasmModule* mod, AstFunction* fd) {
- // NOTE: Don't compile intrinsics
- if (fd->flags & Ast_Flag_Intrinsic) return;
+ if (!should_compile_function(fd)) return;
i32 type_idx = generate_type_idx(mod, fd);
bh_arr_each(Entity, entity, program->entities) {
switch (entity->type) {
case Entity_Type_Function_Header: {
- if (entity->function->flags & Ast_Flag_Intrinsic) break;
+ if (!should_compile_function(entity->function)) break;
u64 func_idx;
if ((entity->function->flags & Ast_Flag_Foreign) != 0)